Support Class Library
A set of tools providing classes and utility
Any.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 #include <memory>
5 #include <scl/macros.h>
10 //#include <scl/concepts/NonCopyable.h>
11 //#include <scl/concepts/Movable.h>
12 
13 namespace scl{
14  namespace utils{
15  namespace details{
16  struct __any_base{
17  using type = void;
18 
19  virtual void polymorphism() const = 0;
20  //template <class U>
21  //U as() const{}
22  };
23 
24  template <class T>
25  class __any__impl final : public __any_base{
26  protected:
27  T value;
28 
29  public:
30  using type = T;
31 
32  void polymorphism() const final{}
33 
34  template <class = META::enable_if_t<
35  META::is_move_constructible<T>()
36  >>
37  __any__impl(T&& value) : value{std::move(value)} {
38  }
39 
40  template <class = META::enable_if_t<
41  META::is_copy_constructible<T>()
42  >>
43  __any__impl(const T& value) : value{value} {
44  }
45 
46  template <class U>
47  U as() const{
48  try{
49  return static_cast<U>(this->value);
50  }catch(...){
52  }
53  }
54  };
55  }
56 
60  class Any{
61  protected:
66  std::unique_ptr<details::__any_base> impl;
67 
72  const std::type_info* ti;
73 
74  public:
80  template <class T>
81  Any(T&& value) : impl{new details::__any__impl<META::decay_t<T>>(std::forward<T>(value))}, ti{&typeid(T)} {
82  }
83 
84  Any(Any&&) = default;
85  Any& operator=(Any&&) = default;
86 
87  Any() = delete;
88  Any(const Any&) = delete;
89  Any& operator=(const Any&) = delete;
90 
97  template <class T>
98  Any& operator=(T&& value){
99  this->impl.reset(new details::__any__impl<T>(std::forward<T>(value)));
100  this->ti = &typeid(T);
101  return *this;
102  }
103 
110  template <class U>
111  bool canCastTo() const{
112  return this->ti->hash_code() == typeid(U).hash_code();
113  }
114 
121  template <class U>
122  U as() const{
123  if(this->canCastTo<U>())
124  return dynamic_cast<details::__any__impl<U>*>(impl.get())->template as<U>();
125 
126  throw exceptions::InvalidAnyCast{"Tried to cast Any to an unsupported type"};
127  }
128  };
129  }
130 }
131 
132 /*
133 assert_concept(
134  scl::concepts::Movable<scl::utils::Any>{} && scl::concepts::NonCopyable<scl::utils::Any>{},
135  "scl::utils::Any should be non copyable and movable."
136 );*/
Global namespace of the SCL.
Definition: alias.hpp:3
Exception class used when attempting to cast an Any to the wrong type.
__any__impl(const T &value)
Definition: Any.h:43
U as() const
Attempts to cast this Any.
Definition: Any.h:122
Any(T &&value)
Move a value into an Any.
Definition: Any.h:81
Class that can hold any value type (and change value type mid lifetime)
Definition: Any.h:60
void polymorphism() const final
Definition: Any.h:32
Any & operator=(T &&value)
Assign a new value to this Any.
Definition: Any.h:98
const std::type_info * ti
The type_info of the current value type.
Definition: Any.h:72
bool canCastTo() const
Safely determines whether or not you can cast from the current value type to the one given as argumen...
Definition: Any.h:111
virtual void polymorphism() const =0
std::unique_ptr< details::__any_base > impl
A PIMPL.
Definition: Any.h:66
typename std::enable_if< B, T >::type enable_if_t
An handy type alias for the result of std::enable_if.
Definition: enable_if.h:12