| // Copyright 2013-2021 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> |
| |
| #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(_MSC_VER) || (_MSC_VER > 1916)) |
| |
| //[type_index_constexpr14_sort_check_example |
| /*` |
| The following example shows that `boost::typeindex::ctti_type_index` is usable at compile time on |
| a C++14 compatible compilers to check order of template parameters. |
| |
| Consider the situation when we have a function that accepts std::tuple, boost::variant or some other class that uses variadic templates: |
| */ |
| |
| template <class... T> class types{}; |
| |
| template <class... T> |
| void do_something(const types<T...>& t) noexcept; |
| |
| /*` |
| Such functions may be very usefull, however they may significantly increase the size of the resulting program. Each instantionation of such function with different templates order |
| consumes space in the resulting program: |
| |
| // Types are same, but different order leads to new instantionation of do_something function. |
| types<bool, double, int> |
| types<bool, int, double> |
| types<int, bool, double> |
| types<int, double, bool> |
| types<double, int, bool> |
| types<double, bool, int> |
| |
| One of the ways to reduce instantinations count is to force the types to have some order: |
| */ |
| |
| |
| #include <boost/type_index/ctti_type_index.hpp> |
| |
| // Implementing type trait that returns true if the types are sorted lexographicaly |
| template <class... T> |
| constexpr bool is_asc_sorted(types<T...>) noexcept { |
| return true; |
| } |
| |
| template <class Lhs, class Rhs, class... TN> |
| constexpr bool is_asc_sorted(types<Lhs, Rhs, TN...>) noexcept { |
| using namespace boost::typeindex; |
| return ctti_type_index::type_id<Lhs>() <= ctti_type_index::type_id<Rhs>() |
| && is_asc_sorted(types<Rhs, TN...>()); |
| } |
| |
| |
| // Using the newly created `is_asc_sorted` trait: |
| template <class... T> |
| void do_something(const types<T...>& /*value*/) noexcept { |
| static_assert( |
| is_asc_sorted( types<T...>() ), |
| "T... for do_something(const types<T...>& t) must be sorted ascending" |
| ); |
| } |
| |
| int main() { |
| do_something( types<bool, double, int>() ); |
| // do_something( types<bool, int, double>() ); // Fails the static_assert! |
| } |
| //] [/type_index_constexpr14_sort_check_example] |
| |
| #else // #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(_MSC_VER) || (_MSC_VER > 1916)) |
| |
| int main() {} |
| |
| #endif |
| |