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

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