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