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