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
// Copyright 2009-2018, Jason Turner (jason@emptycrate.com)
5
// http://www.chaiscript.com
6

7
// This is an open source non-commercial project. Dear PVS-Studio, please check it.
8
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
9

10

11
#ifndef CHAISCRIPT_TYPE_INFO_HPP_
12
#define CHAISCRIPT_TYPE_INFO_HPP_
13

14
#include <memory>
15
#include <type_traits>
16
#include <typeinfo>
17
#include <string>
18

19
namespace chaiscript
20
{
21

22
  namespace detail
23
  {
24
    template<typename T>
25
      struct Bare_Type
26
      {
27
        using type = typename std::remove_cv<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::type;
28
      };
29
  }
30

31

32
  /// \brief Compile time deduced information about a type
33
  class Type_Info
34
  {
35
    public:
36 1
      constexpr Type_Info(const bool t_is_const, const bool t_is_reference, const bool t_is_pointer, const bool t_is_void, 
37
          const bool t_is_arithmetic, const std::type_info *t_ti, const std::type_info *t_bare_ti) noexcept
38 1
        : m_type_info(t_ti), m_bare_type_info(t_bare_ti),
39 1
          m_flags((static_cast<unsigned int>(t_is_const) << is_const_flag)
40 1
                + (static_cast<unsigned int>(t_is_reference) << is_reference_flag)
41 1
                + (static_cast<unsigned int>(t_is_pointer) << is_pointer_flag)
42 1
                + (static_cast<unsigned int>(t_is_void) << is_void_flag)
43 1
                + (static_cast<unsigned int>(t_is_arithmetic) << is_arithmetic_flag))
44
      {
45
      }
46

47 1
      constexpr Type_Info() noexcept = default;
48

49 1
      bool operator<(const Type_Info &ti) const noexcept
50
      {
51 1
        return m_type_info->before(*ti.m_type_info);
52
      }
53

54 1
      constexpr bool operator!=(const Type_Info &ti) const noexcept
55
      {
56 1
        return !(operator==(ti));
57
      }
58

59
      constexpr bool operator!=(const std::type_info &ti) const noexcept
60
      {
61
        return !(operator==(ti));
62
      }
63

64 1
      constexpr bool operator==(const Type_Info &ti) const noexcept
65
      {
66 1
        return ti.m_type_info == m_type_info
67 1
           || *ti.m_type_info == *m_type_info;
68
      }
69

70 1
      constexpr bool operator==(const std::type_info &ti) const noexcept
71
      {
72 1
        return !is_undef() && (*m_type_info) == ti;
73
      }
74

75 1
      constexpr bool bare_equal(const Type_Info &ti) const noexcept
76
      {
77 1
        return ti.m_bare_type_info == m_bare_type_info
78 1
           || *ti.m_bare_type_info == *m_bare_type_info;
79
      }
80

81 1
      constexpr bool bare_equal_type_info(const std::type_info &ti) const noexcept
82
      {
83 1
        return !is_undef() && (*m_bare_type_info) == ti;
84
      }
85

86 1
      constexpr bool is_const() const noexcept { return (m_flags & (1 << is_const_flag)) != 0; }
87 1
      constexpr bool is_reference() const noexcept { return (m_flags & (1 << is_reference_flag)) != 0; }
88 1
      constexpr bool is_void() const noexcept { return (m_flags & (1 << is_void_flag)) != 0; }
89 1
      constexpr bool is_arithmetic() const noexcept { return (m_flags & (1 << is_arithmetic_flag)) != 0; }
90 1
      constexpr bool is_undef() const noexcept { return (m_flags & (1 << is_undef_flag)) != 0; }
91 1
      constexpr bool is_pointer() const noexcept { return (m_flags & (1 << is_pointer_flag)) != 0; }
92

93 1
      const char * name() const noexcept
94
      {
95 1
        if (!is_undef())
96
        {
97 1
          return m_type_info->name();
98
        } else {
99 1
          return "";
100
        }
101
      }
102

103 1
      const char * bare_name() const noexcept
104
      {
105 1
        if (!is_undef())
106
        {
107 1
          return m_bare_type_info->name();
108
        } else {
109 1
          return "";
110
        }
111
      }
112

113 1
      constexpr const std::type_info *bare_type_info() const noexcept
114
      {
115 1
        return m_bare_type_info;
116
      }
117

118
    private:
119
      struct Unknown_Type {};
120

121
      const std::type_info *m_type_info = &typeid(Unknown_Type);
122
      const std::type_info *m_bare_type_info = &typeid(Unknown_Type);
123
      static const int is_const_flag = 0;
124
      static const int is_reference_flag = 1;
125
      static const int is_pointer_flag = 2;
126
      static const int is_void_flag = 3;
127
      static const int is_arithmetic_flag = 4;
128
      static const int is_undef_flag = 5;
129
      unsigned int m_flags = (1 << is_undef_flag);
130
  };
131

132
  namespace detail
133
  {
134
    /// Helper used to create a Type_Info object
135
    template<typename T>
136
      struct Get_Type_Info
137
      {
138 1
        constexpr static Type_Info get() noexcept
139
        {
140
          return Type_Info(std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value, 
141
              std::is_reference<T>::value, std::is_pointer<T>::value, 
142
              std::is_void<T>::value,
143
              (std::is_arithmetic<T>::value || std::is_arithmetic<typename std::remove_reference<T>::type>::value)
144
                && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
145
              &typeid(T),
146 1
              &typeid(typename Bare_Type<T>::type));
147
        }
148
      };
149

150
    template<typename T>
151
      struct Get_Type_Info<std::shared_ptr<T> >
152
      {
153
//        typedef T type;
154

155 1
        constexpr static Type_Info get() noexcept
156
        {
157
          return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value, 
158
              std::is_void<T>::value,
159
              std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
160
              &typeid(std::shared_ptr<T> ), 
161 1
              &typeid(typename Bare_Type<T>::type));
162
        }
163
      };
164

165
    template<typename T>
166
      struct Get_Type_Info<std::shared_ptr<T> &> : Get_Type_Info<std::shared_ptr<T>>
167
      {
168
      };
169

170
    template<typename T>
171
      struct Get_Type_Info<const std::shared_ptr<T> &>
172
      {
173 1
        constexpr static Type_Info get() noexcept
174
        {
175
          return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value, 
176
              std::is_void<T>::value,
177
              std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
178
              &typeid(const std::shared_ptr<T> &), 
179 1
              &typeid(typename Bare_Type<T>::type));
180
        }
181
      };
182

183
    template<typename T>
184
      struct Get_Type_Info<std::reference_wrapper<T> >
185
      {
186 0
        constexpr static Type_Info get() noexcept
187
        {
188
          return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value, 
189
              std::is_void<T>::value,
190
              std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
191
              &typeid(std::reference_wrapper<T> ), 
192 0
              &typeid(typename Bare_Type<T>::type));
193
        }
194
      };
195

196
    template<typename T>
197
      struct Get_Type_Info<const std::reference_wrapper<T> &>
198
      {
199 0
        constexpr static Type_Info get() noexcept
200
        {
201
          return Type_Info(std::is_const<T>::value, std::is_reference<T>::value, std::is_pointer<T>::value, 
202
              std::is_void<T>::value,
203
              std::is_arithmetic<T>::value && !std::is_same<typename std::remove_const<typename std::remove_reference<T>::type>::type, bool>::value,
204
              &typeid(const std::reference_wrapper<T> &), 
205 0
              &typeid(typename Bare_Type<T>::type));
206
        }
207
      };
208

209
  }
210

211
  /// \brief Creates a Type_Info object representing the type passed in
212
  /// \tparam T Type of object to get a Type_Info for, derived from the passed in parameter
213
  /// \return Type_Info for T
214
  /// 
215
  /// \b Example:
216
  /// \code
217
  /// int i;
218
  /// chaiscript::Type_Info ti = chaiscript::user_type(i);
219
  /// \endcode
220
  template<typename T>
221
  constexpr Type_Info user_type(const T &/*t*/) noexcept
222
  {
223
    return detail::Get_Type_Info<T>::get();
224
  }
225

226

227
  /// \brief Creates a Type_Info object representing the templated type
228
  /// \tparam T Type of object to get a Type_Info for
229
  /// \return Type_Info for T
230
  /// 
231
  /// \b Example:
232
  /// \code
233
  /// chaiscript::Type_Info ti = chaiscript::user_type<int>();
234
  /// \endcode
235
  template<typename T>
236
  constexpr Type_Info user_type() noexcept
237
  {
238
    return detail::Get_Type_Info<T>::get();
239
  }
240

241
}
242

243
#endif
244

Read our documentation on viewing source code .

Loading