]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / type_index / examples / constexpr14_namespace_check.cpp
CommitLineData
b32b8144 1// Copyright 2013-2017 Antony Polukhin
7c673cae
FG
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
b32b8144
FG
9template <class T>
10void do_something(const T&) {}
11
12
7c673cae
FG
13#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)
14// Implementation of this function is not essential for the example
15template <std::size_t N>
16constexpr 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`
35template <std::size_t N>
36constexpr bool starts_with(const char* name, const char (&substr)[N]) noexcept;
37
38
39// Function that returns true if `T` declared in namespace `ns`
40template <class T, std::size_t N>
41constexpr 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
58namespace 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 // ...
b32b8144 69 do_something(value);
7c673cae
FG
70 }
71 };
72
73 namespace types {
74 struct foo{};
75 struct bar{};
76 }
77} // namespace my_project
78
79int 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
94int main() {}
95
96#endif
97