]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_index/examples/user_defined_typeinfo.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / type_index / examples / user_defined_typeinfo.hpp
1 // Copyright 2013-2014 Antony Polukhin
2
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See the accompanying file LICENSE_1_0.txt
5 // or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
6
7 #ifndef USER_DEFINED_TYPEINFO_HPP
8 #define USER_DEFINED_TYPEINFO_HPP
9
10 //[type_index_userdefined_usertypes
11 /*`
12 The following example shows how a user defined type_info can be created and used.
13 Example works with and without RTTI.
14
15 Consider situation when user uses only those types in `typeid()`:
16 */
17
18 #include <vector>
19 #include <string>
20
21 namespace my_namespace {
22
23 class my_class;
24 struct my_struct;
25
26 typedef std::vector<my_class> my_classes;
27 typedef std::string my_string;
28
29 } // namespace my_namespace
30
31 //] [/type_index_userdefined_usertypes]
32
33
34 //[type_index_userdefined_enum
35 /*`
36 In that case user may wish to save space in binary and create it's own type system.
37 For that case `detail::typenum<>` meta function is added. Depending on the input type T
38 this function will return different numeric values.
39 */
40 #include <boost/type_index/type_index_facade.hpp>
41
42 namespace my_namespace { namespace detail {
43 template <class T> struct typenum;
44 template <> struct typenum<void>{ enum {value = 0}; };
45 template <> struct typenum<my_class>{ enum {value = 1}; };
46 template <> struct typenum<my_struct>{ enum {value = 2}; };
47 template <> struct typenum<my_classes>{ enum {value = 3}; };
48 template <> struct typenum<my_string>{ enum {value = 4}; };
49
50 // my_typeinfo structure is used to save type number
51 struct my_typeinfo {
52 const char* const type_;
53 };
54
55 const my_typeinfo infos[5] = {
56 {"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
57 };
58
59 template <class T>
60 inline const my_typeinfo& my_typeinfo_construct() {
61 return infos[typenum<T>::value];
62 }
63 }} // my_namespace::detail
64
65 //] [/type_index_userdefined_usertypes]
66
67
68 //[type_index_my_type_index
69 /*`
70 `my_type_index` is a user created type_index class. If in doubt during this phase, you can always
71 take a look at the `<boost/type_index/ctti_type_index.hpp>` or `<boost/type_index/stl_type_index.hpp>`
72 files. Documentation for `type_index_facade` could be also useful.
73
74 See implementation of `my_type_index`:
75 */
76 namespace my_namespace {
77
78 class my_type_index: public boost::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
79 const detail::my_typeinfo* data_;
80
81 public:
82 typedef detail::my_typeinfo type_info_t;
83
84 inline my_type_index() BOOST_NOEXCEPT
85 : data_(&detail::my_typeinfo_construct<void>())
86 {}
87
88 inline my_type_index(const type_info_t& data) BOOST_NOEXCEPT
89 : data_(&data)
90 {}
91
92 inline const type_info_t& type_info() const BOOST_NOEXCEPT {
93 return *data_;
94 }
95
96 inline const char* raw_name() const BOOST_NOEXCEPT {
97 return data_->type_;
98 }
99
100 inline std::string pretty_name() const {
101 return data_->type_;
102 }
103
104 template <class T>
105 inline static my_type_index type_id() BOOST_NOEXCEPT {
106 return detail::my_typeinfo_construct<T>();
107 }
108
109 template <class T>
110 inline static my_type_index type_id_with_cvr() BOOST_NOEXCEPT {
111 return detail::my_typeinfo_construct<T>();
112 }
113
114 template <class T>
115 inline static my_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
116 };
117
118 } // namespace my_namespace
119
120 /*`
121 Note that we have used the boost::typeindex::type_index_facade class as base.
122 That class took care about all the helper function and operators (comparison, hashing, ostreaming and others).
123 */
124
125 //] [/type_index_my_type_index]
126
127 //[type_index_my_type_index_register_class
128 /*`
129 Usually to allow runtime type info we need to register class with some macro.
130 Let's see how a `MY_TYPEINDEX_REGISTER_CLASS` macro could be implemented for our `my_type_index` class:
131 */
132 namespace my_namespace { namespace detail {
133
134 template <class T>
135 inline const my_typeinfo& my_typeinfo_construct_ref(const T*) {
136 return my_typeinfo_construct<T>();
137 }
138
139 #define MY_TYPEINDEX_REGISTER_CLASS \
140 virtual const my_namespace::detail::my_typeinfo& type_id_runtime() const { \
141 return my_namespace::detail::my_typeinfo_construct_ref(this); \
142 }
143
144 }} // namespace my_namespace::detail
145
146 //] [/type_index_my_type_index_register_class]
147
148 //[type_index_my_type_index_type_id_runtime_implmentation
149 /*`
150 Now when we have a MY_TYPEINDEX_REGISTER_CLASS, let's implement a `my_type_index::type_id_runtime` method:
151 */
152 namespace my_namespace {
153 template <class T>
154 my_type_index my_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
155 // Classes that were marked with `MY_TYPEINDEX_REGISTER_CLASS` will have a
156 // `type_id_runtime()` method.
157 return variable.type_id_runtime();
158 }
159 }
160 //] [/type_index_my_type_index_type_id_runtime_implmentation]
161
162 //[type_index_my_type_index_type_id_runtime_classes
163 /*`
164 Consider the situation, when `my_class` and `my_struct` are polymorphic classes:
165 */
166
167 namespace my_namespace {
168
169 class my_class {
170 public:
171 MY_TYPEINDEX_REGISTER_CLASS
172 virtual ~my_class() {}
173 };
174
175 struct my_struct: public my_class {
176 MY_TYPEINDEX_REGISTER_CLASS
177 };
178
179 } // namespace my_namespace
180
181 //] [/type_index_my_type_index_type_id_runtime_classes]
182
183
184 //[type_index_my_type_index_worldwide_typedefs
185 /*`
186 You'll also need to add some typedefs and macro to your "user_defined_typeinfo.hpp" header file:
187 */
188 #define BOOST_TYPE_INDEX_REGISTER_CLASS MY_TYPEINDEX_REGISTER_CLASS
189 namespace boost { namespace typeindex {
190 typedef my_namespace::my_type_index type_index;
191 }}
192 //] [/type_index_my_type_index_worldwide_typedefs]
193
194
195 #endif // USER_DEFINED_TYPEINFO_HPP
196