/*============================================================================= 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_DETAIL_GENERATED_VALUE_HPP #define SPROUT_GENERATOR_DETAIL_GENERATED_VALUE_HPP #include #include #include #include #include #include #include #include #include #include namespace sprout_adl { sprout::not_found_via_adl get_generated_value(...); } // namespace sprout_adl namespace sprout { 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 is_substitutable_const_generated_value : public sprout::bool_constant< sprout::detail::has_mem_generated_value::value > {}; template struct get_generated_value_impl; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_lvalue_reference::value && !std::is_const::type>::value && sprout::detail::is_substitutable_const_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen& gen) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { typedef decltype(std::declval().generated_value()) type; return sprout::const_reference_cast(sprout::as_const(gen).generated_value()); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_lvalue_reference::value && !std::is_const::type>::value && !sprout::detail::is_substitutable_const_generated_value::value && sprout::detail::has_mem_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen& gen) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return gen.generated_value(); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_lvalue_reference::value && !std::is_const::type>::value && !sprout::detail::is_substitutable_const_generated_value::value && !sprout::detail::has_mem_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) get_generated_value(Gen& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(gen); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_rvalue_reference::value && !std::is_const::type>::value && sprout::detail::is_substitutable_const_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { typedef decltype(std::declval().generated_value()) type; return sprout::const_reference_cast(sprout::as_const(sprout::move(gen)).generated_value()); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_rvalue_reference::value && !std::is_const::type>::value && !sprout::detail::is_substitutable_const_generated_value::value && sprout::detail::has_mem_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return sprout::move(gen).generated_value(); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_rvalue_reference::value && !std::is_const::type>::value && !sprout::detail::is_substitutable_const_generated_value::value && !sprout::detail::has_mem_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) get_generated_value(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(sprout::move(gen)); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_reference::value && std::is_const::type>::value && sprout::detail::has_mem_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) get_generated_value(Gen const& gen) SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) { return gen.generated_value(); } }; template struct get_generated_value_impl< Gen, typename std::enable_if< std::is_reference::value && std::is_const::type>::value && !sprout::detail::has_mem_generated_value::value >::type > { public: static SPROUT_CONSTEXPR decltype(sprout::tuples::get<0>(std::declval())) get_generated_value(Gen const& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<0>(std::declval())) { return sprout::tuples::get<0>(gen); } }; } // namespace detail } // namespace sprout namespace sprout_generator_detail { template inline SPROUT_CONSTEXPR decltype(sprout::detail::get_generated_value_impl::get_generated_value(std::declval())) get_generated_value(Gen& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::detail::get_generated_value_impl::get_generated_value(std::declval())) { return sprout::detail::get_generated_value_impl::get_generated_value(gen); } template inline SPROUT_CONSTEXPR typename std::enable_if< !std::is_const::value && !std::is_volatile::value && !std::is_reference::value, decltype(sprout::detail::get_generated_value_impl::get_generated_value(std::declval())) >::type get_generated_value(Gen&& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::detail::get_generated_value_impl::get_generated_value(std::declval())) { return sprout::detail::get_generated_value_impl::get_generated_value(sprout::move(gen)); } template inline SPROUT_CONSTEXPR decltype(sprout::detail::get_generated_value_impl::get_generated_value(std::declval())) get_generated_value(Gen const& gen) SPROUT_NOEXCEPT_IF_EXPR(sprout::detail::get_generated_value_impl::get_generated_value(std::declval())) { return sprout::detail::get_generated_value_impl::get_generated_value(gen); } } // namespace sprout_generator_detail #endif // #ifndef SPROUT_GENERATOR_DETAIL_GENERATED_VALUE_HPP