/*============================================================================= 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 #include #include #include namespace sprout_adl { sprout::not_found_via_adl get_generated_value(...); sprout::not_found_via_adl get_next_generator(...); } // namespace sprout_adl 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 get_generated_value_helper; template struct get_generated_value_helper< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) call(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return SPROUT_FORWARD(Gen, t).generated_value(); } }; template struct get_generated_value_helper< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) call(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(SPROUT_FORWARD(Gen, t)); } }; template inline SPROUT_CONSTEXPR decltype(sprout::generators::detail::get_generated_value_helper::call(std::declval())) get_generated_value_impl(Gen&& t) { return sprout::generators::detail::get_generated_value_helper::call(SPROUT_FORWARD(Gen, 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 get_next_generator_helper; template struct get_next_generator_helper< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) call(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return t.next_generator(); } }; template struct get_next_generator_helper< Gen, typename std::enable_if::value>::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) call(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(SPROUT_FORWARD(Gen, t)); } }; template inline SPROUT_CONSTEXPR decltype(sprout::generators::detail::get_next_generator_helper::call(std::declval())) get_next_generator_impl(Gen&& t) { return sprout::generators::detail::get_next_generator_helper::call(SPROUT_FORWARD(Gen, t)); } } // namespace detail } // namespace generators } // namespace sprout namespace sprout_generator_detail { using sprout_adl::get_generated_value; using sprout_adl::get_next_generator; template inline SPROUT_CONSTEXPR decltype(sprout::generators::detail::get_generated_value_impl(std::declval())) get_generated_value(Gen& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::detail::get_generated_value_impl(std::declval())) { return sprout::generators::detail::get_generated_value_impl(gen); } template inline SPROUT_CONSTEXPR typename std::enable_if< !std::is_const::value && !std::is_volatile::value && !std::is_reference::value, decltype(sprout::generators::detail::get_generated_value_impl(std::declval())) >::type get_generated_value(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::detail::get_generated_value_impl(std::declval())) { return sprout::generators::detail::get_generated_value_impl(sprout::move(gen)); } template inline SPROUT_CONSTEXPR decltype(sprout::generators::detail::get_generated_value_impl(std::declval())) get_generated_value(Gen const& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::detail::get_generated_value_impl(std::declval())) { return sprout::generators::detail::get_generated_value_impl(gen); } template inline SPROUT_CONSTEXPR decltype(get_generated_value(std::declval())) call_get_generated_value(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(get_generated_value(std::declval())) { return get_generated_value(SPROUT_FORWARD(Gen, gen)); } template inline SPROUT_CONSTEXPR decltype(sprout::generators::detail::get_next_generator_impl(std::declval())) get_next_generator(Gen& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::detail::get_next_generator_impl(std::declval())) { return sprout::generators::detail::get_next_generator_impl(gen); } template inline SPROUT_CONSTEXPR typename std::enable_if< !std::is_const::value && !std::is_volatile::value && !std::is_reference::value, decltype(sprout::generators::detail::get_next_generator_impl(std::declval())) >::type get_next_generator(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::detail::get_next_generator_impl(std::declval())) { return sprout::generators::detail::get_next_generator_impl(sprout::move(gen)); } template inline SPROUT_CONSTEXPR decltype(sprout::generators::detail::get_next_generator_impl(std::declval())) get_next_generator(Gen const& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::detail::get_next_generator_impl(std::declval())) { return sprout::generators::detail::get_next_generator_impl(gen); } template inline SPROUT_CONSTEXPR decltype(get_next_generator(std::declval())) call_get_next_generator(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(get_next_generator(std::declval())) { return get_next_generator(SPROUT_FORWARD(Gen, gen)); } } // namespace sprout_generator_detail namespace sprout { namespace generators { // // generator_access_traits // template struct generator_access_traits { public: // get_generated_value static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_get_generated_value(std::declval())) get_generated_value(Gen& t) SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_get_generated_value(std::declval())) { return sprout_generator_detail::call_get_generated_value(t); } static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_get_generated_value(std::declval())) get_generated_value(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_get_generated_value(std::declval())) { return sprout_generator_detail::call_get_generated_value(sprout::move(t)); } static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_get_generated_value(std::declval())) get_generated_value(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_get_generated_value(std::declval())) { return sprout_generator_detail::call_get_generated_value(t); } // get_next_generator static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_get_next_generator(std::declval())) get_next_generator(Gen& t) SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_get_next_generator(std::declval())) { return sprout_generator_detail::call_get_next_generator(t); } static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_get_next_generator(std::declval())) get_next_generator(Gen&& t) SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_get_next_generator(std::declval())) { return sprout_generator_detail::call_get_next_generator(sprout::move(t)); } static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_get_next_generator(std::declval())) get_next_generator(Gen const& t) SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_get_next_generator(std::declval())) { return sprout_generator_detail::call_get_next_generator(t); } }; template struct generator_access_traits { public: // get_generated_value 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); } // get_next_generator 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