variant.h
Go to the documentation of this file.
1 /************************************************************************************
2 * *
3 * Copyright (c) 2014 Axel Menzel <info@axelmenzel.de> *
4 * *
5 * This file is part of RTTR (Run Time Type Reflection) *
6 * License: MIT License *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining *
9 * a copy of this software and associated documentation files (the "Software"), *
10 * to deal in the Software without restriction, including without limitation *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
12 * and/or sell copies of the Software, and to permit persons to whom the *
13 * Software is furnished to do so, subject to the following conditions: *
14 * *
15 * The above copyright notice and this permission notice shall be included in *
16 * all copies or substantial portions of the Software. *
17 * *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
24 * SOFTWARE. *
25 * *
26 *************************************************************************************/
27 
28 #ifndef __RTTR_VARIANT_H__
29 #define __RTTR_VARIANT_H__
30 
32 #include "rttr/type.h"
33 
34 #include <type_traits>
35 #include <cstddef>
36 #include <algorithm>
37 
38 namespace rttr
39 {
40 
41 class variant_array;
42 
43 namespace detail
44 {
45  RTTR_LOCAL variant create_void_variant();
46  class argument;
47  class instance;
48  class array_container_base;
49 }
50 
126 {
127  public:
133  variant();
134 
139  template<typename T>
140  variant(const T& param);
141 
146  template<typename T>
147  variant(T&& param
148 #ifndef DOXYGEN
149  , typename std::enable_if<!std::is_same<variant&, T>::value >::type* = 0
150  , typename std::enable_if<!std::is_const<T>::value >::type* = 0
151 #endif
152  );
153 
157  variant(const variant& other);
158 
162  variant(variant&& other);
163 
167  ~variant();
168 
172  void swap(variant& other);
173 
179  template<typename T>
180  variant& operator=(T&& other);
181 
187  variant& operator=(variant&& other);
188 
194  variant& operator=(const variant& other);
195 
201  template<typename T>
202  bool is_type() const;
203 
211  type get_type() const;
212 
220  bool is_valid() const;
221 
228  template<typename T>
229  bool can_convert() const;
230 
237  bool can_convert(const type& target_type) const;
238 
251  bool convert(const type& target_type);
252 
265  template<typename T>
266  T& get_value() const;
267 
268 
282  template<typename T>
283  T convert(bool* ok = nullptr) const;
284 
296  int to_int(bool *ok = nullptr) const;
297 
309  std::string to_string(bool *ok = nullptr) const;
310 
325  bool to_bool() const;
326 
338  float to_float(bool* ok = nullptr);
339 
351  double to_double(bool* ok = nullptr);
352 
371  variant_array to_array() const;
372 
373 
374  private:
375  template<typename T, typename SourceType>
376  static T get_value_with_default_value(const SourceType& source, T default_value, bool* ok);
377 
385  void* get_ptr() const;
386 
394  void* get_raw_ptr() const;
395 
403  type get_raw_type() const;
404 
405  class variant_container_base
406  {
407  public:
408  virtual ~variant_container_base();
409 
410  virtual type get_type() const = 0;
411 
412  virtual void* get_ptr() const = 0;
413 
414  virtual type get_raw_type() const = 0;
415 
416  virtual void* get_raw_ptr() const = 0;
417 
418  virtual bool is_array() const = 0;
419 
420  virtual detail::array_container_base* to_array() const = 0;
421 
422  virtual std::string to_string(bool* ok) const = 0;
423  virtual int to_int(bool* ok) const = 0;
424  virtual bool to_bool(bool* ok) const = 0;
425  virtual float to_float(bool* ok) const = 0;
426  virtual double to_double(bool* ok) const = 0;
427 
428  std::size_t to_size_t(bool* ok) const;
429 
430  virtual variant_container_base* clone() const = 0;
431 
432  virtual bool can_convert(const type& target_type) const = 0;
433  };
434 
435  template<typename T, typename Enable = void>
436  class variant_container : public variant_container_base
437  {
438  public:
439  variant_container(const T& arg);
440 
441  variant_container(T&& arg);
442 
443  variant_container_base* clone() const;
444 
445  type get_type() const;
446 
447  void* get_ptr() const;
448 
449  type get_raw_type() const;
450 
451  void* get_raw_ptr() const;
452 
453  bool is_array() const;
454 
455  detail::array_container_base* to_array() const;
456 
457  bool can_convert(const type& target_type) const;
458 
459  std::string to_string(bool* ok) const;
460  int to_int(bool* ok) const;
461  bool to_bool(bool* ok) const;
462  float to_float(bool* ok) const;
463  double to_double(bool* ok) const;
464 
465  T _value; // the stored data
466 
467  private: // unimplemented
468  variant_container & operator=(const variant_container &);
469  };
470 
471  template<typename T>
472  class variant_container<T, typename std::enable_if<detail::is_array_and_not_one_dim_char_array<T>::value>::type> : public variant_container_base
473  {
474  public:
475  variant_container(const T& arg);
476 
477  variant_container_base* clone() const;
478 
479  type get_type() const;
480 
481  void* get_ptr() const;
482 
483  type get_raw_type() const;
484 
485  void* get_raw_ptr() const;
486 
487  bool can_convert(const type& target_type) const;
488 
489  bool is_array() const;
490 
491  detail::array_container_base* to_array() const;
492 
493  std::string to_string(bool* ok) const;
494  int to_int(bool* ok) const;
495  bool to_bool(bool* ok) const;
496  float to_float(bool* ok) const;
497  double to_double(bool* ok) const;
498 
499  T _value; // the stored data
500 
501  private: // unimplemented
502  variant_container & operator=(const variant_container &);
503  };
504 
505  template<std::size_t N>
506  class variant_container<char[N]> : public variant_container_base
507  {
508  public:
509  variant_container(const char (&arg)[N]);
510 
511  variant_container_base* clone() const;
512 
513  type get_type() const;
514 
515  void* get_ptr() const;
516 
517  type get_raw_type() const;
518 
519  void* get_raw_ptr() const;
520 
521  bool can_convert(const type& target_type) const;
522 
523  bool is_array() const;
524 
525  detail::array_container_base* to_array() const;
526 
527  std::string to_string(bool* ok) const;
528  int to_int(bool* ok) const;
529  bool to_bool(bool* ok) const;
530  float to_float(bool* ok) const;
531  double to_double(bool* ok) const;
532 
533  char _value[N]; // the stored data
534 
535  private: // unimplemented
536  variant_container & operator=(const variant_container &);
537  };
538 
539  private:
540  friend variant detail::create_void_variant();
541  friend detail::argument;
542  friend detail::instance;
543  variant_container_base* _holder;
544 };
545 
546 #ifndef DOXYGEN
547 template<> RTTR_API std::string variant::convert<std::string>(bool* ok) const;
548 template<> RTTR_API int variant::convert<int>(bool* ok) const;
549 template<> RTTR_API bool variant::convert<bool>(bool* ok) const;
550 template<> RTTR_API float variant::convert<float>(bool* ok) const;
551 template<> RTTR_API double variant::convert<double>(bool* ok) const;
552 template<> RTTR_API variant_array variant::convert<variant_array>(bool* ok) const;
553 
554 template<> RTTR_API bool variant::can_convert<variant_array>() const;
555 #endif
556 
557 namespace detail
558 {
559  RTTR_API extern variant void_variant;
560 } // end namespace impl
561 
562 } // end namespace rttr
563 
564 #include "rttr/impl/variant_impl.h"
565 #include "rttr/impl/variant_default_types_impl.h"
566 
567 #endif // __RTTR_VARIANT_H__
The namespace for all rttr components.
Definition: core_prerequisites.h:33
This class holds the type information for any arbitrary object.
Definition: type.h:165
#define RTTR_LOCAL
Definition: core_prerequisites.h:125
The variant class allows to store data of any type and convert between these types transparently...
Definition: variant.h:125
The variant_array class is a specialization of a variant, but for array types.
Definition: variant_array.h:169
#define RTTR_API
Definition: core_prerequisites.h:124