diff --git a/.travis.yml b/.travis.yml index a888e72..48fc3f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -81,6 +81,16 @@ matrix: sources: - ubuntu-toolchain-r-test + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++11 + addons: + apt: + packages: + - clang-3.5 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.5 + - os: linux env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11 addons: @@ -131,6 +141,36 @@ matrix: - ubuntu-toolchain-r-test - llvm-toolchain-precise-3.8 + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++11 + addons: + apt: + packages: + - clang-3.9 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.9 + + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++14 + addons: + apt: + packages: + - clang-3.9 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.9 + + - os: linux + env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++1z + addons: + apt: + packages: + - clang-3.9 + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.9 + - os: osx env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index ac19959..8930660 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -498,7 +498,37 @@ namespace detail template struct mp_find_impl; -#if !defined( BOOST_MP11_NO_CONSTEXPR ) +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +struct mp_index_holder +{ + std::size_t i_; + bool f_; +}; + +constexpr inline mp_index_holder operator+( mp_index_holder const & v, bool f ) +{ + if( v.f_ ) + { + return v; + } + else if( f ) + { + return { v.i_, true }; + } + else + { + return { v.i_ + 1, false }; + } +} + +template class L, class... T, class V> struct mp_find_impl, V> +{ + static constexpr mp_index_holder _v{ 0, false }; + using type = mp_size_t< (_v + ... + std::is_same::value).i_ >; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) template class L, class V> struct mp_find_impl, V> { @@ -558,7 +588,15 @@ namespace detail template class P> struct mp_find_if_impl; -#if !defined( BOOST_MP11_NO_CONSTEXPR ) +#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) + +template class L, class... T, template class P> struct mp_find_if_impl, P> +{ + static constexpr mp_index_holder _v{ 0, false }; + using type = mp_size_t< (_v + ... + P::value).i_ >; +}; + +#elif !defined( BOOST_MP11_NO_CONSTEXPR ) template class L, template class P> struct mp_find_if_impl, P> { diff --git a/include/boost/mp11/detail/config.hpp b/include/boost/mp11/detail/config.hpp index 69539aa..3992cdc 100644 --- a/include/boost/mp11/detail/config.hpp +++ b/include/boost/mp11/detail/config.hpp @@ -21,4 +21,12 @@ #endif +#if defined(BOOST_CLANG) && defined(__has_cpp_attribute) +# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode + +# define BOOST_MP11_HAS_FOLD_EXPRESSIONS + +# endif +#endif + #endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED