mn_any.hpp
Go to the documentation of this file.
1 /*
2 *This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniThread ).
3 *Copyright (c) 2018 Amber-Sophia Schroeck
4 *
5 *The Mini Thread Library is free software; you can redistribute it and/or modify
6 *it under the terms of the GNU Lesser General Public License as published by
7 *the Free Software Foundation, version 3, or (at your option) any later version.
8 
9 *The Mini Thread Library is distributed in the hope that it will be useful, but
10 *WITHOUT ANY WARRANTY; without even the implied warranty of
11 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 *General Public License for more details.
13 *
14 *You should have received a copy of the GNU Lesser General Public
15 *License along with the Mini Thread Library; if not, see
16 *<https://www.gnu.org/licenses/>.
17 */
18 #ifndef __MINILIB_CONTAINER_ANY_H__
19 #define __MINILIB_CONTAINER_ANY_H__
20 
21 #include "../mn_config.hpp"
22 
23 # include <cassert>
24 # include <typeinfo>
25 
26 #include "mn_algorithm.hpp"
27 #include "../mn_allocator.hpp"
28 #include "../mn_def.hpp"
29 #include "../mn_functional.hpp"
30 #include "../mn_typetraits.hpp"
31 
32 #include "../utils/mn_utils.hpp"
33 
34 
35 
36 namespace mn {
37  namespace container {
45  class basic_any {
50  public:
51  virtual std::type_info const & type() const = 0;
52  virtual iholder * clone() const = 0;
53  };
54 
58  template< typename T >
60  public:
61  static const int TYPE_SIZE() { return sizeof(T); }
62 
63  basic_any_holder_impl( T const & value ) : m_typeHold( value ) {}
64  basic_any_holder_impl( T && value ) : m_typeHold( mn::move( value ) ) {}
65 
66 
71  virtual std::type_info const & type() const override {
72  return typeid( T );
73  }
74 
79  virtual basic_any_holder* clone() const override {
80  return new basic_any_holder_impl( m_typeHold );
81  }
82 
87  T get() { return m_typeHold; }
92  const T get() const { return m_typeHold; }
93 
97  operator T() { return get(); }
98  private:
103  };
104 
105  public:
108 
112  constexpr basic_any() noexcept
113  : m_asyContent( nullptr ) {}
114 
118  template< class T >
119  basic_any(const T & other ) : m_asyContent( nullptr ) {
120  construct(other);
121  }
122 
126  basic_any( const self_type& other )
127  : m_asyContent(nullptr ) {
128  if ((this != &other) && !other.empty()) construct(other);
129  }
130 
134  basic_any( self_type && other ) noexcept
135  : m_asyContent.content( mn::move( other.m_asyContent ) ) {
136  other.m_asyContent = nullptr;
137  }
138 
142  ~basic_any() { deconstruct(true); }
143 
147  void reset() noexcept {
148  deconstruct(false);
149  }
150 
154  self_type& swap( any & other ) noexcept {
155  if (this == &other) return *this;
156 
157  mn::swap( m_asyContent, other.m_asyContent );
158  return *this;
159  }
160 
165  bool has_value() const noexcept {
166  return m_asyContent != nullptr;
167  }
168 
173  bool is_empty() const noexcept {
174  return m_asyContent == nullptr;
175  }
176 
181  const std::type_info & type() const noexcept {
182  return has_value() ? m_asyContent->type() : typeid( void );
183  }
184 
189  template<class T>
190  const T * to_pointer() const {
191  auto* _content = static_cast<basic_any_holder_impl<T> *>( m_asyContent );
192  return &( _content->get() );
193  }
194 
199  template< class T >
200  T * to_pointer() {
201  auto* _content = static_cast<basic_any_holder_impl<T> *>( m_asyContent );
202  return &( _content->get() );
203  }
204 
208  self_type& operator=( const self_type& other ) noexcept {
209  self_type( other ).swap( *this );
210  return *this;
211  }
212 
216  self_type& operator=( self_type && other ) noexcept {
217  self_type( mn::move( other ) ).swap( *this );
218  return *this;
219  }
220 
224  template<typename T>
225  self_type& operator=(const T& other ) noexcept {
226  construct(other);
227  return *this;
228  }
229 
233  template< class T, class... Args >
234  void emplace( Args && ... args ) {
235  self_type( T( mn::forward<Args>(args)... ) ).swap( *this );
236  }
237  private:
241  void construct(const self_type& other) {
242  if(other.has_value())
243  m_asyContent = other.m_asyContent->clone() ;
244  else
245  m_asyContent = nullptr;
246  }
247 
251  template< class T >
252  void construct(const T & other) {
254  }
255 
261  void deconstruct(bool bdelete = false) {
262  mn::destruct<content_type>(m_asyContent);
263  if(bdelete) delete m_asyContent;
264  }
265  private:
270  };
271 
272  inline void swap( basic_any& x, basic_any& y ) noexcept {
273  x.swap( y );
274  }
275 
281  template< class T, class ...Args >
282  inline basic_any make_any( Args&& ...args ) {
283  return basic_any( mn::in_place_type<T>, mn::forward<Args>(args)...);
284  }
285 
291  template< class T >
292  inline const T* any_cast( const basic_any* other ) noexcept {
293  if(other == nullptr) return nullptr;
294  return operand->type() == typeid(T) ? operand->to_pointer<T>() : nullptr;
295  }
296 
302  template<class T >
303  inline T* any_cast(basic_any* other ) noexcept {
304  if(other == nullptr) return nullptr;
305  return operand->type() == typeid(T) ? operand->to_pointer<T>() : nullptr;
306  }
307  }
308 }
309 #endif // __MINILIB_CONTAINER_ANY_H__
The real impl of the basic_any holder.
Definition: mn_any.hpp:59
T get()
Get the stored value.
Definition: mn_any.hpp:87
basic_any_holder_impl(T const &value)
Definition: mn_any.hpp:63
const T get() const
Get the stored value.
Definition: mn_any.hpp:92
static const int TYPE_SIZE()
Definition: mn_any.hpp:61
virtual basic_any_holder * clone() const override
Get a clone from this.
Definition: mn_any.hpp:79
virtual std::type_info const & type() const override
Get the type info of the given type.
Definition: mn_any.hpp:71
basic_any_holder_impl(T &&value)
Definition: mn_any.hpp:64
Interface class for the holder.
Definition: mn_any.hpp:49
virtual std::type_info const & type() const =0
virtual iholder * clone() const =0
An Any class represents a general type and is capable of storing any type.
Definition: mn_any.hpp:45
~basic_any()
Deconstructor of this basic_any object.
Definition: mn_any.hpp:142
void reset() noexcept
Reset the basic_any.
Definition: mn_any.hpp:147
T * to_pointer()
Get the content as pointer.
Definition: mn_any.hpp:200
void construct(const self_type &other)
Helper function to construct the basic_any from other basic_any.
Definition: mn_any.hpp:241
self_type & swap(any &other) noexcept
Swaps the content of the two Anys.
Definition: mn_any.hpp:154
bool has_value() const noexcept
Has the basic_any any value?
Definition: mn_any.hpp:165
basic_any(const self_type &other)
Copy constructor, works with both empty and initialized Any values.
Definition: mn_any.hpp:126
self_type & operator=(self_type &&other) noexcept
Assignment operator for basic_any.
Definition: mn_any.hpp:216
void deconstruct(bool bdelete=false)
Helper function to deconstruct.
Definition: mn_any.hpp:261
self_type & operator=(const T &other) noexcept
Assignment operator for all types.
Definition: mn_any.hpp:225
basic_any< TAllocator > self_type
Definition: mn_any.hpp:106
holder_type m_asyContent
Holder of the value.
Definition: mn_any.hpp:269
const T * to_pointer() const
Get the content as pointer.
Definition: mn_any.hpp:190
const std::type_info & type() const noexcept
Returns the type information of the stored content.
Definition: mn_any.hpp:181
void emplace(Args &&... args)
emplace
Definition: mn_any.hpp:234
constexpr basic_any() noexcept
Construct an empty basic_any type.
Definition: mn_any.hpp:112
bool is_empty() const noexcept
if the basic_any empty?
Definition: mn_any.hpp:173
basic_any(const T &other)
Construct an any which stores the init parameter inside.
Definition: mn_any.hpp:119
self_type & operator=(const self_type &other) noexcept
Assignment operator for basic_any.
Definition: mn_any.hpp:208
basic_any(self_type &&other) noexcept
Copy constructor, works with both empty and initialized Any values.
Definition: mn_any.hpp:134
void construct(const T &other)
Helper function to construct the basic_any from value.
Definition: mn_any.hpp:252
Basic algorithmens This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniT...
const T * any_cast(const basic_any *other) noexcept
Definition: mn_any.hpp:292
void swap(basic_any &x, basic_any &y) noexcept
Definition: mn_any.hpp:272
basic_any make_any(Args &&...args)
Definition: mn_any.hpp:282
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
Definition: mn_allocator_typetraits.hpp:25
void swap(TAssignable &a, TAssignable &b)
Definition: mn_algorithm.hpp:312
void move(const T *src, const T *last, T *dest)
Definition: mn_algorithm.hpp:100