// Copyright 2013-2017 Antony Polukhin

// Distributed under the Boost Software License, Version 1.0.
// (See the accompanying file LICENSE_1_0.txt
// or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)

#include <boost/config.hpp>

template <class T>
void do_something(const T&) {}


#if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR)
// Implementation of this function is not essential for the example
template <std::size_t N>
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 <boost/type_index/ctti_type_index.hpp>

// Helper function that returns true if `name` starts with `substr`
template <std::size_t N>
constexpr bool starts_with(const char* name, const char (&substr)[N]) noexcept;


// Function that returns true if `T` declared in namespace `ns`
template <class T, std::size_t N>
constexpr bool in_namespace(const char (&ns)[N]) noexcept {
    const char* name = boost::typeindex::ctti_type_index::type_id<T>().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 <class T>
        void serialize(const T& value) {
            static_assert(
                in_namespace<T>("my_project::types") || in_namespace<T>("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
            // ...
            do_something(value);
        }
    };

    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

