ChaiScript / ChaiScript
1
// This file is distributed under the BSD License.
2
// See "license.txt" for details.
3
// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
4
// and Jason Turner (jason@emptycrate.com)
5
// http://www.chaiscript.com
6

7
#ifndef CHAISCRIPT_ANY_HPP_
8
#define CHAISCRIPT_ANY_HPP_
9

10
#include <utility>
11

12
namespace chaiscript {
13
  namespace detail {
14
    namespace exception
15
    {
16
      /// \brief Thrown in the event that an Any cannot be cast to the desired type
17
      ///
18
      /// It is used internally during function dispatch.
19
      ///
20
      /// \sa chaiscript::detail::Any
21
      class bad_any_cast : public std::bad_cast
22
      {
23
        public:
24
          /// \brief Description of what error occurred
25 0
          const char * what() const noexcept override
26
          {
27 0
            return "bad any cast";
28
          }
29
      };
30
    }
31
  
32

33
    class Any {
34
      private:
35
        struct Data
36
        {
37 1
          constexpr explicit Data(const std::type_info &t_type) noexcept
38 1
            : m_type(t_type)
39
          {
40
          }
41

42
          Data &operator=(const Data &) = delete;
43

44 1
          virtual ~Data() noexcept = default;
45

46
          virtual void *data() noexcept = 0;
47

48 1
          const std::type_info &type() const noexcept
49
          {
50 1
            return m_type;
51
          }
52

53
          virtual std::unique_ptr<Data> clone() const = 0;
54
          const std::type_info &m_type;
55
        };
56

57
        template<typename T>
58
          struct Data_Impl : Data
59
          {
60 1
            explicit Data_Impl(T t_type)
61
              : Data(typeid(T)),
62 1
                m_data(std::move(t_type))
63
            {
64
            }
65

66 1
            void *data() noexcept override 
67
            {
68 1
              return &m_data;
69
            }
70

71 1
            std::unique_ptr<Data> clone() const override
72
            {
73 1
              return std::make_unique<Data_Impl<T>>(m_data);
74
            }
75

76
            Data_Impl &operator=(const Data_Impl&) = delete;
77

78
            T m_data;
79
          };
80

81
        std::unique_ptr<Data> m_data;
82

83
      public:
84
        // construct/copy/destruct
85 1
        constexpr Any() noexcept = default;
86 1
        Any(Any &&) noexcept = default;
87
        Any &operator=(Any &&t_any) = default;
88

89 1
        Any(const Any &t_any)
90 0
          : m_data(t_any.empty() ? nullptr : t_any.m_data->clone())
91
        {
92
        }
93

94
        template<typename ValueType,
95
          typename = std::enable_if_t<!std::is_same_v<Any, std::decay_t<ValueType>>>>
96 1
        explicit Any(ValueType &&t_value)
97 1
          : m_data(std::make_unique<Data_Impl<std::decay_t<ValueType>>>(std::forward<ValueType>(t_value)))
98
        {
99
        }
100

101

102 1
        Any & operator=(const Any &t_any)
103
        {
104 1
          Any copy(t_any);
105 1
          swap(copy);
106 1
          return *this; 
107
        }
108

109
        template<typename ToType>
110 1
          ToType &cast() const
111
          {
112 1
            if (m_data && typeid(ToType) == m_data->type())
113
            {
114 1
              return *static_cast<ToType *>(m_data->data());
115
            } else {
116 1
              throw chaiscript::detail::exception::bad_any_cast();
117
            }
118
          }
119

120

121
        // modifiers
122 1
        Any & swap(Any &t_other)
123
        {
124 1
          std::swap(t_other.m_data, m_data);
125 1
          return *this;
126
        }
127

128
        // queries
129
        bool empty() const noexcept
130
        {
131
          return !static_cast<bool>(m_data);
132
        }
133

134
        const std::type_info & type() const noexcept
135
        {
136
          if (m_data) {
137
            return m_data->type();
138
          } else {
139
            return typeid(void);
140
          }
141
        }
142
    };
143

144
  }
145
}
146

147
#endif
148

149

Read our documentation on viewing source code .

Loading