]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_index/examples/constexpr14_namespace_check.cpp
1 // Copyright 2013-2016 Antony Polukhin
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>.)
7 #include <boost/config.hpp>
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
)
20 //[type_index_constexpr14_namespace_example
22 The following example shows that `boost::typeindex::ctti_type_index` is usable at compile time on
23 a C++14 compatible compilers.
25 In this example we'll create and use a constexpr function that checks namespace of the provided type.
28 #include <boost/type_index/ctti_type_index.hpp>
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
;
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();
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;
47 return starts_with(name
, ns
) && starts_with(name
+ N
- 1, "::");
51 Now when we have that wonderfull function, we can do static assertions and other compile-time validations:
54 namespace my_project
{
57 void serialize(const T
& value
) {
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`"
63 // Actual implementation of the serialization goes below
72 } // namespace my_project
75 my_project::serializer s
;
76 my_project::types::foo f
;
77 my_project::types::bar b
;
83 // s.serialize(sh); // Fails the static_assert!
85 //] [/type_index_constexpr14_namespace_example]
87 #else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)