/*============================================================================= Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_GENERATOR_GENERATOR_ACCESS_TRAITS_HPP #define SPROUT_GENERATOR_GENERATOR_ACCESS_TRAITS_HPP #include #include #include #include #include #include namespace sprout { namespace generators { namespace detail { template struct has_mem_generated_value_test { public: template< typename U = T, typename = typename sprout::identity().generated_value())>::type > static sprout::true_type test(int); static sprout::false_type test(...); }; #if defined(_MSC_VER) && (_MSC_VER > 1900) template::test(0))>::type> struct has_mem_generated_value : public Base_ {}; #else template struct has_mem_generated_value : public sprout::identity::test(0))>::type {}; #endif template struct generator_access_traits_generated_value_impl; template struct generator_access_traits_generated_value_impl< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return t.generated_value(); } static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return t.generated_value(); } static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return t.generated_value(); } }; template struct generator_access_traits_generated_value_impl< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) get_generated_value(Gen& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(t); } static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) get_generated_value(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(t); } static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) get_generated_value(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(t); } }; template struct has_mem_next_generator_test { public: template< typename U = T, typename = typename sprout::identity().next_generator())>::type > static sprout::true_type test(int); static sprout::false_type test(...); }; #if defined(_MSC_VER) && (_MSC_VER > 1900) template::test(0))>::type> struct has_mem_next_generator : public Base_ {}; #else template struct has_mem_next_generator : public sprout::identity::test(0))>::type {}; #endif template struct generator_access_traits_next_generator_impl; template struct generator_access_traits_next_generator_impl< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) get_next_generator(Gen& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return t.next_generator(); } static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) get_next_generator(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return t.next_generator(); } static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) get_next_generator(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return t.next_generator(); } }; template struct generator_access_traits_next_generator_impl< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) get_next_generator(Gen& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(t); } static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) get_next_generator(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(t); } static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) get_next_generator(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(t); } }; } // namespace detail // // generator_access_traits // template struct generator_access_traits : public sprout::generators::detail::generator_access_traits_generated_value_impl , public sprout::generators::detail::generator_access_traits_next_generator_impl {}; template struct generator_access_traits { public: static SPROUT_CONSTEXPR decltype(sprout::generators::generator_access_traits::get_generated_value(std::declval())) get_generated_value(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_access_traits::get_generated_value(std::declval())) { return sprout::generators::generator_access_traits::get_generated_value(t); } static SPROUT_CONSTEXPR decltype(sprout::generators::generator_access_traits::get_next_generator(std::declval())) get_next_generator(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_access_traits::get_next_generator(std::declval())) { return sprout::generators::generator_access_traits::get_next_generator(t); } }; } // namespace generators using sprout::generators::generator_access_traits; } // namespace sprout #endif // #ifndef SPROUT_GENERATOR_GENERATOR_ACCESS_TRAITS_HPP