1//
2// Copyright (c) Antony Polukhin, 2013-2015.
3//
4//
5// Distributed under the Boost Software License, Version 1.0. (See accompanying
6// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7//
8
9#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
10#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
11
12#include <boost/config.hpp>
13#include <string>
14#include <cstring>
15
16#if !defined(BOOST_NO_IOSTREAM)
17#if !defined(BOOST_NO_IOSFWD)
18#include <iosfwd> // for std::basic_ostream
19#else
20#include <ostream>
21#endif
22#endif
23
24#ifdef BOOST_HAS_PRAGMA_ONCE
25# pragma once
26#endif
27
28// Forward declaration from #include <boost/functional/hash_fwd.hpp>
29namespace boost {
30 template <class It> std::size_t hash_range(It, It);
31}
32
33namespace boost { namespace typeindex {
34
35/// \class type_index_facade
36///
37/// This class takes care about the comparison operators, hash functions and
38/// ostream operators. Use this class as a public base class for defining new
39/// type_info-conforming classes.
40///
41/// \b Example:
42/// \code
43/// class stl_type_index: public type_index_facade<stl_type_index, std::type_info>
44/// {
45/// public:
46/// typedef std::type_info type_info_t;
47/// private:
48/// const type_info_t* data_;
49///
50/// public:
51/// stl_type_index(const type_info_t& data) noexcept
52/// : data_(&data)
53/// {}
54/// // ...
55/// };
56/// \endcode
57///
58/// \tparam Derived Class derived from type_index_facade.
59/// \tparam TypeInfo Class that will be used as a base type_info class.
60/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade.
61/// Protected member functions raw_name() \b must be defined in Derived class. All the other
62/// methods are mandatory.
63/// \see 'Making a custom type_index' section for more information about
64/// creating your own type_index using type_index_facade.
65template <class Derived, class TypeInfo>
66class type_index_facade {
67private:
68 /// @cond
69 const Derived & derived() const BOOST_NOEXCEPT {
70 return *static_cast<Derived const*>(this);
71 }
72 /// @endcond
73public:
74 typedef TypeInfo type_info_t;
75
76 /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
77 /// \return Name of a type. By default returns Derived::raw_name().
78 inline const char* name() const BOOST_NOEXCEPT {
79 return derived().raw_name();
80 }
81
82 /// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
83 /// \return Human readable type name. By default returns Derived::name().
84 inline std::string pretty_name() const {
85 return derived().name();
86 }
87
88 /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
89 /// \return True if two types are equal. By default compares types by raw_name().
90 inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
91 const char* const left = derived().raw_name();
92 const char* const right = rhs.raw_name();
93 return left == right || !std::strcmp(s1: left, s2: right);
94 }
95
96 /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
97 /// \return True if rhs is greater than this. By default compares types by raw_name().
98 inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
99 const char* const left = derived().raw_name();
100 const char* const right = rhs.raw_name();
101 return left != right && std::strcmp(s1: left, s2: right) < 0;
102 }
103
104 /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
105 /// \return Hash code of a type. By default hashes types by raw_name().
106 /// \note <boost/functional/hash.hpp> has to be included if this function is used.
107 inline std::size_t hash_code() const BOOST_NOEXCEPT {
108 const char* const name_raw = derived().raw_name();
109 return boost::hash_range(name_raw, name_raw + std::strlen(s: name_raw));
110 }
111
112#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
113protected:
114 /// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
115 /// \return Pointer to unredable/raw type name.
116 inline const char* raw_name() const BOOST_NOEXCEPT;
117
118 /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
119 /// \return Const reference to underlying low level type_info_t.
120 inline const type_info_t& type_info() const BOOST_NOEXCEPT;
121
122 /// This is a factory method that is used to create instances of Derived classes.
123 /// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
124 ///
125 /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
126 /// Overrides \b must remove const, volatile && and & modifiers from T.
127 /// \tparam T Type for which type_index must be created.
128 /// \return type_index for type T.
129 template <class T>
130 static Derived type_id() BOOST_NOEXCEPT;
131
132 /// This is a factory method that is used to create instances of Derived classes.
133 /// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
134 ///
135 /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
136 /// Overrides \b must \b not remove const, volatile && and & modifiers from T.
137 /// \tparam T Type for which type_index must be created.
138 /// \return type_index for type T.
139 template <class T>
140 static Derived type_id_with_cvr() BOOST_NOEXCEPT;
141
142 /// This is a factory method that is used to create instances of Derived classes.
143 /// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
144 ///
145 /// \b Override: This function \b may be redefined and made public in Derived class.
146 /// \param variable Variable which runtime type will be stored in type_index.
147 /// \return type_index with runtime type of variable.
148 template <class T>
149 static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT;
150
151#endif
152
153};
154
155/// @cond
156template <class Derived, class TypeInfo>
157inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
158 return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
159}
160
161template <class Derived, class TypeInfo>
162inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
163 return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));;
164}
165
166
167
168template <class Derived, class TypeInfo>
169inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
170 return rhs < lhs;
171}
172
173template <class Derived, class TypeInfo>
174inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
175 return !(lhs > rhs);
176}
177
178template <class Derived, class TypeInfo>
179inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
180 return !(lhs < rhs);
181}
182
183template <class Derived, class TypeInfo>
184inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
185 return !(lhs == rhs);
186}
187
188// ######################### COMPARISONS with Derived ############################ //
189template <class Derived, class TypeInfo>
190inline bool operator == (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
191 return Derived(lhs) == rhs;
192}
193
194template <class Derived, class TypeInfo>
195inline bool operator < (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
196 return Derived(lhs) < rhs;
197}
198
199template <class Derived, class TypeInfo>
200inline bool operator > (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
201 return rhs < Derived(lhs);
202}
203
204template <class Derived, class TypeInfo>
205inline bool operator <= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
206 return !(Derived(lhs) > rhs);
207}
208
209template <class Derived, class TypeInfo>
210inline bool operator >= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
211 return !(Derived(lhs) < rhs);
212}
213
214template <class Derived, class TypeInfo>
215inline bool operator != (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
216 return !(Derived(lhs) == rhs);
217}
218
219
220template <class Derived, class TypeInfo>
221inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
222 return lhs == Derived(rhs);
223}
224
225template <class Derived, class TypeInfo>
226inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
227 return lhs < Derived(rhs);
228}
229
230template <class Derived, class TypeInfo>
231inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
232 return Derived(rhs) < lhs;
233}
234
235template <class Derived, class TypeInfo>
236inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
237 return !(lhs > Derived(rhs));
238}
239
240template <class Derived, class TypeInfo>
241inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
242 return !(lhs < Derived(rhs));
243}
244
245template <class Derived, class TypeInfo>
246inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
247 return !(lhs == Derived(rhs));
248}
249
250// ######################### COMPARISONS with Derived END ############################ //
251
252/// @endcond
253
254#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
255
256/// noexcept comparison operators for type_index_facade classes.
257bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
258
259/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
260bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
261
262/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
263bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
264
265#endif
266
267#ifndef BOOST_NO_IOSTREAM
268#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
269/// @cond
270/// Ostream operator that will output demangled name
271template <class Derived, class TypeInfo>
272inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
273 ostr << static_cast<Derived const&>(ind).pretty_name();
274 return ostr;
275}
276/// @endcond
277#else
278/// Ostream operator that will output demangled name.
279template <class CharT, class TriatT, class Derived, class TypeInfo>
280inline std::basic_ostream<CharT, TriatT>& operator<<(
281 std::basic_ostream<CharT, TriatT>& ostr,
282 const type_index_facade<Derived, TypeInfo>& ind)
283{
284 ostr << static_cast<Derived const&>(ind).pretty_name();
285 return ostr;
286}
287#endif // BOOST_NO_TEMPLATED_IOSTREAMS
288#endif // BOOST_NO_IOSTREAM
289
290/// This free function is used by Boost's unordered containers.
291/// \note <boost/functional/hash.hpp> has to be included if this function is used.
292template <class Derived, class TypeInfo>
293inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
294 return static_cast<Derived const&>(lhs).hash_code();
295}
296
297}} // namespace boost::typeindex
298
299#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
300
301

source code of boost/boost/type_index/type_index_facade.hpp