singleton.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2019 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Eduard Valeyev
19  * Department of Chemistry, Virginia Tech
20  *
21  * util/singleton.h
22  * Mar 11, 2019
23  *
24  */
25 
26 #ifndef TILEDARRAY_UTIL_SINGLETON_H__INCLUDED
27 #define TILEDARRAY_UTIL_SINGLETON_H__INCLUDED
28 
29 #include <cassert>
30 #include <memory>
31 
32 #include <TiledArray/type_traits.h>
33 
34 namespace TiledArray {
35 
54 template <typename Derived>
55 class Singleton {
56  // can't use std::is_default_constructible since Derived's ctors should be
57  // private
58  template <typename T, typename Enabler = void>
59  struct is_default_constructible_helper : public std::false_type {};
60  template <typename T>
61  struct is_default_constructible_helper<T, std::void_t<decltype(T{})>>
62  : public std::true_type {};
63  constexpr static bool derived_is_default_constructible =
64  is_default_constructible_helper<Derived>::value;
65 
66  public:
68  template <typename D = Derived>
69  static std::enable_if_t<Singleton<D>::derived_is_default_constructible, D&>
71  const auto& result_ptr = instance_accessor();
72  if (result_ptr != nullptr) return *result_ptr;
73  set_instance();
74  return *instance_accessor();
75  }
76 
81  template <typename D = Derived>
82  static D& get_instance(
84  nullptr) {
85  const auto& result_ptr = instance_accessor();
86  if (result_ptr != nullptr) return *result_ptr;
87  throw std::logic_error(
88  "TiledArray::Singleton: is not default-constructible and "
89  "set_instance() "
90  "has not been called");
91  }
92 
95  template <typename D = Derived>
96  static std::enable_if_t<Singleton<D>::derived_is_default_constructible, D*>
98  const auto& result_ptr = instance_accessor();
99  if (result_ptr != nullptr) return result_ptr.get();
100  set_instance();
101  return instance_accessor();
102  }
103 
106  template <typename D = Derived>
107  static D* get_instance_ptr(
109  nullptr) {
110  const auto& result_ptr = instance_accessor();
111  if (result_ptr != nullptr) return result_ptr.get();
112  return nullptr;
113  }
114 
119  template <typename... Args>
120  static void set_instance(Args&&... args) {
121  assert(instance_accessor() == nullptr);
122  instance_accessor() = std::move(
123  std::unique_ptr<Derived>(new Derived(std::forward<Args>(args)...)));
124  }
125 
126  protected:
127  template <typename... Args>
128  Singleton(Args&&... args) {} // all constructors are private
129 
130  static auto& instance_accessor() {
131  static std::unique_ptr<Derived> instance(nullptr);
132  return instance;
133  }
134 };
135 
136 } // namespace TiledArray
137 
138 #endif // TILEDARRAY_UTIL_SINGLETON_H__INCLUDED
static D & get_instance(std::enable_if_t<!Singleton< Derived >::derived_is_default_constructible > *=nullptr)
Definition: singleton.h:82
static auto & instance_accessor()
Definition: singleton.h:130
Singleton base class To create a singleton class A do:
Definition: singleton.h:55
static std::enable_if_t< Singleton< D >::derived_is_default_constructible, D & > get_instance()
Definition: singleton.h:70
static void set_instance(Args &&... args)
Definition: singleton.h:120
Singleton(Args &&... args)
Definition: singleton.h:128
static D * get_instance_ptr(std::enable_if_t<!Singleton< Derived >::derived_is_default_constructible > *=nullptr)
Definition: singleton.h:107
static std::enable_if_t< Singleton< D >::derived_is_default_constructible, D * > get_instance_ptr()
Definition: singleton.h:97