// Copyright 2013-2016 Antony Polukhin // Distributed under the Boost Software License, Version 1.0. // (See the accompanying file LICENSE_1_0.txt // or a copy at .) #include #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) // Implementation of this function is not essential for the example template constexpr bool starts_with(const char* name, const char (&ns)[N]) noexcept { for (std::size_t i = 0; i < N - 1; ++i) if (name[i] != ns[i]) return false; return true; } //[type_index_constexpr14_namespace_example /*` The following example shows that `boost::typeindex::ctti_type_index` is usable at compile time on a C++14 compatible compilers. In this example we'll create and use a constexpr function that checks namespace of the provided type. */ #include // Helper function that returns true if `name` starts with `substr` template constexpr bool starts_with(const char* name, const char (&substr)[N]) noexcept; // Function that returns true if `T` declared in namespace `ns` template constexpr bool in_namespace(const char (&ns)[N]) noexcept { const char* name = boost::typeindex::ctti_type_index::type_id().raw_name(); // Some compilers add `class ` or `struct ` before the namespace, so we need to skip those words first if (starts_with(name, "class ")) { name += sizeof("class ") - 1; } else if (starts_with(name, "struct ")) { name += sizeof("struct ") - 1; } return starts_with(name, ns) && starts_with(name + N - 1, "::"); } /*` Now when we have that wonderfull function, we can do static assertions and other compile-time validations: */ namespace my_project { struct serializer { template void serialize(const T& value) { static_assert( in_namespace("my_project::types") || in_namespace("my_project::types_ext"), "Only types from namespaces `my_project::types` and `my_project::types_ext` are allowed to be serialized using `my_project::serializer`" ); // Actual implementation of the serialization goes below // ... } }; namespace types { struct foo{}; struct bar{}; } } // namespace my_project int main() { my_project::serializer s; my_project::types::foo f; my_project::types::bar b; s.serialize(f); s.serialize(b); // short sh = 0; // s.serialize(sh); // Fails the static_assert! } //] [/type_index_constexpr14_namespace_example] #else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) int main() {} #endif