SPH
Any.h
Go to the documentation of this file.
1 #pragma once
2 
7 
10 #include <typeinfo>
11 
13 
15 class Any {
16 private:
17  class AbstractHolder : public Polymorphic {
18  public:
19  virtual const std::type_info& getTypeInfo() const = 0;
20  virtual AutoPtr<AbstractHolder> clone() const = 0;
21  };
22 
23  template <typename Type>
24  class Holder : public AbstractHolder {
25  static_assert(!std::is_reference<Type>::value, "Cannot store references in Any");
26 
27  private:
28  Type value;
29 
30  public:
31  Holder(const Type& value)
32  : value(value) {}
33 
34  Holder(Type&& value)
35  : value(std::move(value)) {}
36 
37  virtual const std::type_info& getTypeInfo() const {
38  return typeid(value);
39  }
40 
41  virtual AutoPtr<AbstractHolder> clone() const {
42  return makeAuto<Holder>(value);
43  }
44 
45  Type& get() {
46  return value;
47  }
48 
49  const Type& get() const {
50  return value;
51  }
52  };
53 
55 
56  template <typename Type>
57  using HolderType = Holder<std::decay_t<Type>>;
58 
59  template <typename Type>
60  HolderType<Type>* safeCast() {
61  if (data) {
62  return dynamic_cast<HolderType<Type>*>(&*data);
63  } else {
64  return nullptr;
65  }
66  }
67 
68  template <typename Type>
69  const HolderType<Type>* safeCast() const {
70  if (data) {
71  return dynamic_cast<const HolderType<Type>*>(&*data);
72  } else {
73  return nullptr;
74  }
75  }
76 
77  template <typename Type>
78  HolderType<Type>* cast() {
79  SPH_ASSERT(data);
80  return assert_cast<HolderType<Type>*>(&*data);
81  }
82 
83  template <typename Type>
84  const HolderType<Type>* cast() const {
85  SPH_ASSERT(data);
86  return assert_cast<const HolderType<Type>*>(&*data);
87  }
88 
89 
90 public:
92  Any() = default;
93 
95  Any(const Any& other) {
96  *this = other;
97  }
98 
100  Any(Any&& other) {
101  *this = std::move(other);
102  }
103 
105  template <typename Type, typename = std::enable_if_t<!std::is_same<Any, std::decay_t<Type>>::value>>
106  Any(Type&& value) {
107  *this = std::forward<Type>(value);
108  }
109 
111  Any& operator=(const Any& other) {
112  if (other.data) {
113  data = other.data->clone();
114  } else {
115  data = nullptr;
116  }
117  return *this;
118  }
119 
121  Any& operator=(Any&& other) {
122  data = std::move(other.data);
123  return *this;
124  }
125 
127  template <typename Type, typename = std::enable_if_t<!std::is_same<Any, std::decay_t<Type>>::value>>
128  Any& operator=(Type&& value) {
129  data = makeAuto<HolderType<Type>>(std::forward<Type>(value));
130  return *this;
131  }
132 
137  template <typename Type>
138  explicit operator const Type&() const {
139  return cast<Type>()->get();
140  }
141 
146  template <typename Type>
147  explicit operator Type&() {
148  return cast<Type>()->get();
149  }
150 
152  bool hasValue() const {
153  return bool(data);
154  }
155 
159  template <typename Type>
160  friend Optional<Type> anyCast(const Any& any);
161 
165  template <typename Type, typename = std::enable_if_t<!std::is_same<Any, std::decay_t<Type>>::value>>
166  bool operator==(Type&& value) const {
167  auto casted = safeCast<Type>();
168  return casted && casted->get() == value;
169  }
170 
171  template <typename Type, typename = std::enable_if_t<!std::is_same<Any, std::decay_t<Type>>::value>>
172  bool operator!=(Type&& value) const {
173  return !(*this == std::forward<Type>(value));
174  }
175 };
176 
177 template <typename Type>
179  const Any::Holder<Type>* casted = any.safeCast<Type>();
180  if (casted == nullptr) {
181  // either nothing stored or different type
182  return NOTHING;
183  }
184  return casted->get();
185 }
186 
Optional< Type > anyCast(const Any &any)
Definition: Any.h:178
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
Simplified implementation of std::unique_ptr, using only default deleter.
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
INLINE bool any(const Indices &i)
Definition: Indices.h:148
#define NAMESPACE_SPH_END
Definition: Object.h:12
Wrapper of type value of which may or may not be present.
const NothingType NOTHING
Definition: Optional.h:16
Type-safe object that can store value of any type, similar to std::any.
Definition: Any.h:15
bool operator!=(Type &&value) const
Definition: Any.h:172
Any & operator=(Type &&value)
Assigns given value to Any, type is deduced.
Definition: Any.h:128
bool hasValue() const
Checks if Any currently holds a values.
Definition: Any.h:152
bool operator==(Type &&value) const
Compares Any with another value.
Definition: Any.h:166
friend Optional< Type > anyCast(const Any &any)
Tries to extract value of given type from Any.
Definition: Any.h:178
Any(Any &&other)
Moves the value from another Any.
Definition: Any.h:100
Any & operator=(const Any &other)
Copies the value from another Any.
Definition: Any.h:111
Any(Type &&value)
Constructs Any from given value, type is deduced.
Definition: Any.h:106
Any & operator=(Any &&other)
Moves the value from another Any.
Definition: Any.h:121
Any(const Any &other)
Copies the value from another Any.
Definition: Any.h:95
Any()=default
Constructs an empty Any.
INLINE RawPtr< T > get() const
Definition: AutoPtr.h:69
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
Base class for all polymorphic objects.
Definition: Object.h:88