]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_index/examples/user_defined_typeinfo.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / type_index / examples / user_defined_typeinfo.hpp
CommitLineData
7c673cae
FG
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
21namespace my_namespace {
22
23class my_class;
24struct my_struct;
25
26typedef std::vector<my_class> my_classes;
27typedef 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
42namespace 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
b32b8144
FG
50#ifdef BOOST_MSVC
51#pragma warning(push)
52#pragma warning(disable: 4510 4512 4610) // non-copyable non-constructable type
53#endif
54
7c673cae
FG
55 // my_typeinfo structure is used to save type number
56 struct my_typeinfo {
57 const char* const type_;
58 };
59
b32b8144
FG
60#ifdef BOOST_MSVC
61#pragma warning(pop)
62#endif
63
7c673cae
FG
64 const my_typeinfo infos[5] = {
65 {"void"}, {"my_class"}, {"my_struct"}, {"my_classes"}, {"my_string"}
66 };
67
68 template <class T>
69 inline const my_typeinfo& my_typeinfo_construct() {
70 return infos[typenum<T>::value];
71 }
72}} // my_namespace::detail
73
74//] [/type_index_userdefined_usertypes]
75
76
77//[type_index_my_type_index
78/*`
79 `my_type_index` is a user created type_index class. If in doubt during this phase, you can always
80 take a look at the `<boost/type_index/ctti_type_index.hpp>` or `<boost/type_index/stl_type_index.hpp>`
81 files. Documentation for `type_index_facade` could be also useful.
b32b8144 82*/
7c673cae 83
b32b8144
FG
84/*`
85 Since we are not going to override `type_index_facade::hash_code()` we must additionally include
86 `<boost/functional/hash.hpp>`.
87*/
88#include <boost/functional/hash.hpp>
89
90/*`
7c673cae
FG
91 See implementation of `my_type_index`:
92*/
93namespace my_namespace {
94
95class my_type_index: public boost::typeindex::type_index_facade<my_type_index, detail::my_typeinfo> {
96 const detail::my_typeinfo* data_;
97
98public:
99 typedef detail::my_typeinfo type_info_t;
100
101 inline my_type_index() BOOST_NOEXCEPT
102 : data_(&detail::my_typeinfo_construct<void>())
103 {}
104
105 inline my_type_index(const type_info_t& data) BOOST_NOEXCEPT
106 : data_(&data)
107 {}
108
109 inline const type_info_t& type_info() const BOOST_NOEXCEPT {
110 return *data_;
111 }
112
113 inline const char* raw_name() const BOOST_NOEXCEPT {
114 return data_->type_;
115 }
116
117 inline std::string pretty_name() const {
118 return data_->type_;
119 }
120
121 template <class T>
122 inline static my_type_index type_id() BOOST_NOEXCEPT {
123 return detail::my_typeinfo_construct<T>();
124 }
125
126 template <class T>
127 inline static my_type_index type_id_with_cvr() BOOST_NOEXCEPT {
128 return detail::my_typeinfo_construct<T>();
129 }
130
131 template <class T>
132 inline static my_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
133};
134
135} // namespace my_namespace
136
137/*`
138 Note that we have used the boost::typeindex::type_index_facade class as base.
139 That class took care about all the helper function and operators (comparison, hashing, ostreaming and others).
140*/
141
142//] [/type_index_my_type_index]
143
144//[type_index_my_type_index_register_class
145/*`
146 Usually to allow runtime type info we need to register class with some macro.
147 Let's see how a `MY_TYPEINDEX_REGISTER_CLASS` macro could be implemented for our `my_type_index` class:
148*/
149namespace my_namespace { namespace detail {
150
151 template <class T>
152 inline const my_typeinfo& my_typeinfo_construct_ref(const T*) {
153 return my_typeinfo_construct<T>();
154 }
155
156#define MY_TYPEINDEX_REGISTER_CLASS \
157 virtual const my_namespace::detail::my_typeinfo& type_id_runtime() const { \
158 return my_namespace::detail::my_typeinfo_construct_ref(this); \
159 }
160
161}} // namespace my_namespace::detail
162
163//] [/type_index_my_type_index_register_class]
164
165//[type_index_my_type_index_type_id_runtime_implmentation
166/*`
167 Now when we have a MY_TYPEINDEX_REGISTER_CLASS, let's implement a `my_type_index::type_id_runtime` method:
168*/
169namespace my_namespace {
170 template <class T>
171 my_type_index my_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
172 // Classes that were marked with `MY_TYPEINDEX_REGISTER_CLASS` will have a
173 // `type_id_runtime()` method.
174 return variable.type_id_runtime();
175 }
176}
177//] [/type_index_my_type_index_type_id_runtime_implmentation]
178
179//[type_index_my_type_index_type_id_runtime_classes
180/*`
181 Consider the situation, when `my_class` and `my_struct` are polymorphic classes:
182*/
183
184namespace my_namespace {
185
186class my_class {
187public:
188 MY_TYPEINDEX_REGISTER_CLASS
189 virtual ~my_class() {}
190};
191
192struct my_struct: public my_class {
193 MY_TYPEINDEX_REGISTER_CLASS
194};
195
196} // namespace my_namespace
197
198//] [/type_index_my_type_index_type_id_runtime_classes]
199
200
201//[type_index_my_type_index_worldwide_typedefs
202/*`
203 You'll also need to add some typedefs and macro to your "user_defined_typeinfo.hpp" header file:
204*/
205#define BOOST_TYPE_INDEX_REGISTER_CLASS MY_TYPEINDEX_REGISTER_CLASS
206namespace boost { namespace typeindex {
207 typedef my_namespace::my_type_index type_index;
208}}
209//] [/type_index_my_type_index_worldwide_typedefs]
210
211
212#endif // USER_DEFINED_TYPEINFO_HPP
213