]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / libs / type_index / examples / constexpr14_namespace_check.cpp
1 // Copyright 2013-2020 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 #include <boost/config.hpp>
8
9 template <class T>
10 void do_something(const T&) {}
11
12
13 #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)
14 // Implementation of this function is not essential for the example
15 template <std::size_t N>
16 constexpr bool starts_with(const char* name, const char (&ns)[N]) noexcept {
17 for (std::size_t i = 0; i < N - 1; ++i)
18 if (name[i] != ns[i])
19 return false;
20
21 return true;
22 }
23
24 //[type_index_constexpr14_namespace_example
25 /*`
26 The following example shows that `boost::typeindex::ctti_type_index` is usable at compile time on
27 a C++14 compatible compilers.
28
29 In this example we'll create and use a constexpr function that checks namespace of the provided type.
30 */
31
32 #include <boost/type_index/ctti_type_index.hpp>
33
34 // Helper function that returns true if `name` starts with `substr`
35 template <std::size_t N>
36 constexpr bool starts_with(const char* name, const char (&substr)[N]) noexcept;
37
38
39 // Function that returns true if `T` declared in namespace `ns`
40 template <class T, std::size_t N>
41 constexpr bool in_namespace(const char (&ns)[N]) noexcept {
42 const char* name = boost::typeindex::ctti_type_index::type_id<T>().raw_name();
43
44 // Some compilers add `class ` or `struct ` before the namespace, so we need to skip those words first
45 if (starts_with(name, "class ")) {
46 name += sizeof("class ") - 1;
47 } else if (starts_with(name, "struct ")) {
48 name += sizeof("struct ") - 1;
49 }
50
51 return starts_with(name, ns) && starts_with(name + N - 1, "::");
52 }
53
54 /*`
55 Now when we have that wonderfull function, we can do static assertions and other compile-time validations:
56 */
57
58 namespace my_project {
59 struct serializer {
60 template <class T>
61 void serialize(const T& value) {
62 static_assert(
63 in_namespace<T>("my_project::types") || in_namespace<T>("my_project::types_ext"),
64 "Only types from namespaces `my_project::types` and `my_project::types_ext` are allowed to be serialized using `my_project::serializer`"
65 );
66
67 // Actual implementation of the serialization goes below
68 // ...
69 do_something(value);
70 }
71 };
72
73 namespace types {
74 struct foo{};
75 struct bar{};
76 }
77 } // namespace my_project
78
79 int main() {
80 my_project::serializer s;
81 my_project::types::foo f;
82 my_project::types::bar b;
83
84 s.serialize(f);
85 s.serialize(b);
86
87 // short sh = 0;
88 // s.serialize(sh); // Fails the static_assert!
89 }
90 //] [/type_index_constexpr14_namespace_example]
91
92 #else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)
93
94 int main() {}
95
96 #endif
97