Block-Structured AMR Software Framework
AMReX_Any.H
Go to the documentation of this file.
1 #ifndef AMREX_ANY_H_
2 #define AMREX_ANY_H_
3 #include <AMReX_Config.H>
4 
5 #include <memory>
6 #include <typeinfo>
7 #include <type_traits>
8 
9 namespace amrex {
10 
16 class Any
17 {
18 public:
19 
20  Any () = default;
21  ~Any () = default;
22 
23  Any (Any const& rhs) = delete;
24  Any& operator= (Any const& rhs) = delete;
25 
26  Any (Any && rhs) = default;
27  Any& operator= (Any && rhs) = default;
28 
30  template <typename MF,
31  std::enable_if_t<!std::is_same_v<Any,std::decay_t<MF>>,int> = 0>
32  Any (MF && mf) // NOLINT(bugprone-forwarding-reference-overload)
33  : m_ptr(std::make_unique<innards<MF> >(std::forward<MF>(mf)))
34  {}
35 
37  template <typename MF,
38  std::enable_if_t<!std::is_same_v<Any,std::decay_t<MF>>,int> = 0>
39  Any& operator= (MF && mf) {
40  m_ptr = std::make_unique<innards<MF> >(std::forward<MF>(mf));
41  return *this;
42  }
43 
45  [[nodiscard]] const std::type_info& Type () const {
46  if (m_ptr) {
47  return m_ptr->Type();
48  } else {
49  return typeid(void);
50  }
51  }
52 
54  template <typename MF>
55  [[nodiscard]] MF& get () {
56  if (auto p0 = dynamic_cast<innards<MF>*>(m_ptr.get())) {
57  return p0->m_mf;
58  } else {
59  return dynamic_cast<innards<MF&>&>(*m_ptr).m_mf;
60  }
61  }
62 
64  template <typename MF>
65  [[nodiscard]] MF const& get () const {
66  if (auto p0 = dynamic_cast<innards<MF>*>(m_ptr.get())) {
67  return p0->m_mf;
68  } else if (auto p1 = dynamic_cast<innards<MF&>*>(m_ptr.get())) {
69  return p1->m_mf;
70  } else {
71  return dynamic_cast<innards<MF const&> const&>(*m_ptr).m_mf;
72  }
73  }
74 
75  template <typename MF>
76  [[nodiscard]] bool is () const { return Type() == typeid(MF); }
77 
78  [[nodiscard]] bool hasValue () const { return m_ptr != nullptr; }
79 
80 private:
81  struct innards_base // NOLINT(cppcoreguidelines-special-member-functions)
82  {
83  [[nodiscard]] virtual const std::type_info& Type () const = 0;
84  virtual ~innards_base () = default;
85  };
86 
87  template <typename MF>
88  struct innards final : innards_base // NOLINT(cppcoreguidelines-special-member-functions)
89  {
90  innards (MF && mf)
91  : m_mf(std::move(mf))
92  {}
93 
94  ~innards () final = default;
95 
96  [[nodiscard]] const std::type_info& Type () const final {
97  return typeid(MF);
98  }
99 
100  MF m_mf;
101  };
102 
103  std::unique_ptr<innards_base> m_ptr;
104 };
105 
106 }
107 
108 #endif
Definition: AMReX_Any.H:17
Any(MF &&mf)
Constructs by moving the given object.
Definition: AMReX_Any.H:32
bool is() const
Definition: AMReX_Any.H:76
MF const & get() const
Returns a const reference to the contained object.
Definition: AMReX_Any.H:65
~Any()=default
Any()=default
bool hasValue() const
Definition: AMReX_Any.H:78
MF & get()
Returns a reference to the contained object.
Definition: AMReX_Any.H:55
Any & operator=(Any const &rhs)=delete
const std::type_info & Type() const
Returns the contained type.
Definition: AMReX_Any.H:45
std::unique_ptr< innards_base > m_ptr
Definition: AMReX_Any.H:103
Any(Any const &rhs)=delete
Any(Any &&rhs)=default
Definition: AMReX_Amr.cpp:49
Definition: AMReX_Any.H:82
virtual ~innards_base()=default
virtual const std::type_info & Type() const =0
Definition: AMReX_Any.H:89
const std::type_info & Type() const final
Definition: AMReX_Any.H:96
MF m_mf
Definition: AMReX_Any.H:100
innards(MF &&mf)
Definition: AMReX_Any.H:90
~innards() final=default