From 51614b1356be8f6cf7c4f4af4e1c02b84e3eb537 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 28 Apr 2016 08:42:13 +0900 Subject: [PATCH] add generators::next_value function --- sprout/generator/access_functions.hpp | 15 + sprout/generator/access_functions_fwd.hpp | 39 +++ sprout/generator/detail/generated_value.hpp | 70 ++-- sprout/generator/detail/next_generator.hpp | 105 +++--- sprout/generator/detail/next_value.hpp | 317 ++++++++++++++++++ sprout/generator/functions.hpp | 4 +- sprout/generator/generate_functions.hpp | 14 + sprout/generator/generate_functions_fwd.hpp | 30 ++ sprout/generator/generated_value.hpp | 2 - sprout/generator/generator_access_traits.hpp | 1 + .../generator/generator_generate_traits.hpp | 97 ++++++ sprout/generator/next_generator.hpp | 4 +- sprout/generator/next_value.hpp | 42 +++ sprout/generator/results.hpp | 16 +- sprout/generator/traits.hpp | 16 + sprout/generator/traits_fwd.hpp | 7 + 16 files changed, 681 insertions(+), 98 deletions(-) create mode 100644 sprout/generator/access_functions.hpp create mode 100644 sprout/generator/access_functions_fwd.hpp create mode 100644 sprout/generator/detail/next_value.hpp create mode 100644 sprout/generator/generate_functions.hpp create mode 100644 sprout/generator/generate_functions_fwd.hpp create mode 100644 sprout/generator/generator_generate_traits.hpp create mode 100644 sprout/generator/next_value.hpp create mode 100644 sprout/generator/traits.hpp diff --git a/sprout/generator/access_functions.hpp b/sprout/generator/access_functions.hpp new file mode 100644 index 00000000..33769ce3 --- /dev/null +++ b/sprout/generator/access_functions.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + 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_ACCESS_FUNCTIONS_HPP +#define SPROUT_GENERATOR_ACCESS_FUNCTIONS_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_GENERATOR_ACCESS_FUNCTIONS_HPP diff --git a/sprout/generator/access_functions_fwd.hpp b/sprout/generator/access_functions_fwd.hpp new file mode 100644 index 00000000..0bcebfd2 --- /dev/null +++ b/sprout/generator/access_functions_fwd.hpp @@ -0,0 +1,39 @@ +/*============================================================================= + 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_ACCESS_FUNCTIONS_FWD_HPP +#define SPROUT_GENERATOR_ACCESS_FUNCTIONS_FWD_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace generators { + // + // generated_value + // + template + SPROUT_CONSTEXPR decltype(sprout::generators::generator_access_traits::type>::get_generated_value(std::declval())) + generated_value(T&& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_access_traits::type>::get_generated_value(std::declval())); + + // + // next_generator + // + template + SPROUT_CONSTEXPR decltype(sprout::generators::generator_access_traits::type>::get_next_generator(std::declval())) + next_generator(T&& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_access_traits::type>::get_next_generator(std::declval())); + } // namespace generators + + using sprout::generators::generated_value; + using sprout::generators::next_generator; +} // namespace sprout + +#endif // #ifndef SPROUT_GENERATOR_ACCESS_FUNCTIONS_FWD_HPP diff --git a/sprout/generator/detail/generated_value.hpp b/sprout/generator/detail/generated_value.hpp index cb946f09..9f3f8b8d 100644 --- a/sprout/generator/detail/generated_value.hpp +++ b/sprout/generator/detail/generated_value.hpp @@ -67,11 +67,11 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) - get_generated_value(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) + 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; + typedef decltype(std::declval().generated_value()) type; return sprout::const_reference_cast(sprout::as_const(gen).generated_value()); } }; @@ -85,9 +85,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) - get_generated_value(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) + 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(); } @@ -103,9 +103,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(*std::declval()) - get_generated_value(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(*std::declval()) + static SPROUT_CONSTEXPR decltype(*std::declval()) + get_generated_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(*std::declval()) { return *gen; } @@ -121,9 +121,9 @@ namespace sprout { >::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())) + 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); } @@ -138,11 +138,11 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) - get_generated_value(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) + 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; + typedef decltype(std::declval().generated_value()) type; return sprout::const_reference_cast(sprout::as_const(sprout::move(gen)).generated_value()); } }; @@ -156,9 +156,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) - get_generated_value(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) + 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(); } @@ -174,9 +174,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(*std::declval()) - get_generated_value(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(*std::declval()) + static SPROUT_CONSTEXPR decltype(*std::declval()) + get_generated_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(*std::declval()) { return *sprout::move(gen); } @@ -192,9 +192,9 @@ namespace sprout { >::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())) + 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)); } @@ -209,9 +209,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().generated_value()) - get_generated_value(Gen const& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().generated_value()) + 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(); } @@ -226,9 +226,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(*std::declval()) - get_generated_value(Gen const& gen) - SPROUT_NOEXCEPT_IF_EXPR(*std::declval()) + static SPROUT_CONSTEXPR decltype(*std::declval()) + get_generated_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(*std::declval()) { return *gen; } @@ -243,9 +243,9 @@ namespace sprout { >::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())) + 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); } diff --git a/sprout/generator/detail/next_generator.hpp b/sprout/generator/detail/next_generator.hpp index e9c42794..fe103b74 100644 --- a/sprout/generator/detail/next_generator.hpp +++ b/sprout/generator/detail/next_generator.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -68,11 +67,11 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) - get_next_generator(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) + static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { - typedef decltype(std::declval().next_generator()) type; + typedef decltype(std::declval().next_generator()) type; return sprout::const_reference_cast(sprout::as_const(gen).next_generator()); } }; @@ -86,32 +85,14 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) - get_next_generator(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) + static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return gen.next_generator(); } }; template - struct get_next_generator_impl< - Gen, - typename std::enable_if< - std::is_lvalue_reference::value && !std::is_const::type>::value - && !sprout::detail::is_substitutable_const_next_generator::value - && !sprout::detail::has_mem_next_generator::value - && !sprout::is_input_iterator::value - >::type - > { - public: - static SPROUT_CONSTEXPR decltype(sprout::next(std::declval())) - get_next_generator(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(sprout::next(std::declval())) - { - return sprout::next(gen); - } - }; - template struct get_next_generator_impl< Gen, typename std::enable_if< @@ -122,9 +103,27 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) - get_next_generator(Gen& gen) - SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) + static SPROUT_CONSTEXPR decltype(std::declval()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval()) + { + return gen; + } + }; + template + struct get_next_generator_impl< + Gen, + typename std::enable_if< + std::is_lvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::is_substitutable_const_next_generator::value + && !sprout::detail::has_mem_next_generator::value + && !sprout::is_input_iterator::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(gen); } @@ -139,11 +138,11 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) - get_next_generator(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) + static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { - typedef decltype(std::declval().next_generator()) type; + typedef decltype(std::declval().next_generator()) type; return sprout::const_reference_cast(sprout::as_const(sprout::move(gen)).next_generator()); } }; @@ -157,9 +156,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) - get_next_generator(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) + static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return sprout::move(gen).next_generator(); } @@ -175,11 +174,11 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(sprout::next(std::declval())) - get_next_generator(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(sprout::next(std::declval())) + static SPROUT_CONSTEXPR decltype(std::declval()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval()) { - return sprout::next(sprout::move(gen)); + return sprout::move(gen); } }; template @@ -193,9 +192,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) - get_next_generator(Gen&& gen) - SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) + static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(sprout::move(gen)); } @@ -210,9 +209,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) - get_next_generator(Gen const& gen) - SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) + static SPROUT_CONSTEXPR decltype(std::declval().next_generator()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_generator()) { return gen.next_generator(); } @@ -227,11 +226,11 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(sprout::next(std::declval())) - get_next_generator(Gen const& gen) - SPROUT_NOEXCEPT_IF_EXPR(sprout::next(std::declval())) + static SPROUT_CONSTEXPR decltype(std::declval()) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval()) { - return sprout::next(gen); + return gen; } }; template @@ -244,9 +243,9 @@ namespace sprout { >::type > { public: - static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) - get_next_generator(Gen const& gen) - SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) + static SPROUT_CONSTEXPR decltype(sprout::tuples::get<1>(std::declval())) + get_next_generator(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<1>(std::declval())) { return sprout::tuples::get<1>(gen); } diff --git a/sprout/generator/detail/next_value.hpp b/sprout/generator/detail/next_value.hpp new file mode 100644 index 00000000..a89241f6 --- /dev/null +++ b/sprout/generator/detail/next_value.hpp @@ -0,0 +1,317 @@ +/*============================================================================= + 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_NEXT_VALUE_HPP +#define SPROUT_GENERATOR_DETAIL_NEXT_VALUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout_adl { + sprout::not_found_via_adl generate_next_value(...); +} // namespace sprout_adl + +namespace sprout { + namespace detail { + template + struct has_mem_next_value_test { + public: + template< + typename U = T, + typename = typename sprout::identity().next_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_next_value + : public Base_ + {}; +#else + template + struct has_mem_next_value + : public sprout::identity::test(0))>::type + {}; +#endif + + template + struct has_function_call_test { + public: + template< + typename U = T, + typename = typename sprout::identity()())>::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_function_call + : public Base_ + {}; +#else + template + struct has_function_call + : public sprout::identity::test(0))>::type + {}; +#endif + + template + struct generate_next_value_impl; + + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_lvalue_reference::value && !std::is_const::type>::value + && sprout::detail::has_mem_next_value::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(std::declval().next_value()) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_value()) + { + return gen.next_value(); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_lvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && sprout::is_input_iterator::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::next(std::declval())) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::next(std::declval())) + { + return sprout::next(gen); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_lvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && !sprout::is_input_iterator::value + && sprout::detail::has_function_call::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(std::declval()()) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval()()) + { + return gen(); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_lvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && !sprout::is_input_iterator::value + && !sprout::detail::has_function_call::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::generators::next_value(sprout::generators::next_generator(std::declval()))) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::next_value(sprout::generators::next_generator(std::declval()))) + { + return sprout::generators::next_value(sprout::generators::next_generator(gen)); + } + }; + + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_rvalue_reference::value && !std::is_const::type>::value + && sprout::detail::has_mem_next_value::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(std::declval().next_value()) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_value()) + { + return sprout::move(gen).next_value(); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_rvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && sprout::is_input_iterator::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::next(std::declval())) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::next(std::declval())) + { + return sprout::next(sprout::move(gen)); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_rvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && !sprout::is_input_iterator::value + && sprout::detail::has_function_call::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(std::declval()()) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval()()) + { + return sprout::move(gen)(); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_rvalue_reference::value && !std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && !sprout::is_input_iterator::value + && !sprout::detail::has_function_call::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::generators::next_value(sprout::generators::next_generator(std::declval()))) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::next_value(sprout::generators::next_generator(std::declval()))) + { + return sprout::generators::next_value(sprout::generators::next_generator(sprout::move(gen))); + } + }; + + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_reference::value && std::is_const::type>::value + && sprout::detail::has_mem_next_value::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(std::declval().next_value()) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval().next_value()) + { + return gen.next_value(); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_reference::value && std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && sprout::is_input_iterator::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::next(std::declval())) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::next(std::declval())) + { + return sprout::next(gen); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_reference::value && std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && !sprout::is_input_iterator::value + && sprout::detail::has_function_call::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(std::declval()()) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(std::declval()()) + { + return gen(); + } + }; + template + struct generate_next_value_impl< + Gen, + typename std::enable_if< + std::is_reference::value && std::is_const::type>::value + && !sprout::detail::has_mem_next_value::value + && !sprout::is_input_iterator::value + && !sprout::detail::has_function_call::value + >::type + > { + public: + static SPROUT_CONSTEXPR decltype(sprout::generators::next_value(sprout::generators::next_generator(std::declval()))) + generate_next_value(Gen gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::next_value(sprout::generators::next_generator(std::declval()))) + { + return sprout::generators::next_value(sprout::generators::next_generator(gen)); + } + }; + } // namespace detail +} // namespace sprout + +namespace sprout_generator_detail { + template + inline SPROUT_CONSTEXPR decltype(sprout::detail::generate_next_value_impl::generate_next_value(std::declval())) + generate_next_value(Gen& gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::detail::generate_next_value_impl::generate_next_value(std::declval())) + { + return sprout::detail::generate_next_value_impl::generate_next_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::generate_next_value_impl::generate_next_value(std::declval())) + >::type + generate_next_value(Gen&& gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::detail::generate_next_value_impl::generate_next_value(std::declval())) + { + return sprout::detail::generate_next_value_impl::generate_next_value(sprout::move(gen)); + } + template + inline SPROUT_CONSTEXPR decltype(sprout::detail::generate_next_value_impl::generate_next_value(std::declval())) + generate_next_value(Gen const& gen) + SPROUT_NOEXCEPT_IF_EXPR(sprout::detail::generate_next_value_impl::generate_next_value(std::declval())) + { + return sprout::detail::generate_next_value_impl::generate_next_value(gen); + } +} // namespace sprout_generator_detail + +#endif // #ifndef SPROUT_GENERATOR_DETAIL_NEXT_VALUE_HPP diff --git a/sprout/generator/functions.hpp b/sprout/generator/functions.hpp index 105d7cd2..d808b4ac 100644 --- a/sprout/generator/functions.hpp +++ b/sprout/generator/functions.hpp @@ -9,7 +9,7 @@ #define SPROUT_GENERATOR_FUNCTIONS_HPP #include -#include -#include +#include +#include #endif // #ifndef SPROUT_GENERATOR_FUNCTIONS_HPP diff --git a/sprout/generator/generate_functions.hpp b/sprout/generator/generate_functions.hpp new file mode 100644 index 00000000..256b9724 --- /dev/null +++ b/sprout/generator/generate_functions.hpp @@ -0,0 +1,14 @@ +/*============================================================================= + 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_GENERATE_FUNCTIONS_HPP +#define SPROUT_GENERATOR_GENERATE_FUNCTIONS_HPP + +#include +#include + +#endif // #ifndef SPROUT_GENERATOR_GENERATE_FUNCTIONS_HPP diff --git a/sprout/generator/generate_functions_fwd.hpp b/sprout/generator/generate_functions_fwd.hpp new file mode 100644 index 00000000..3805fef1 --- /dev/null +++ b/sprout/generator/generate_functions_fwd.hpp @@ -0,0 +1,30 @@ +/*============================================================================= + 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_GENERATE_FUNCTIONS_FWD_HPP +#define SPROUT_GENERATOR_GENERATE_FUNCTIONS_FWD_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace generators { + // + // next_value + // + template + SPROUT_CONSTEXPR decltype(sprout::generators::generator_generate_traits::type>::generate_next_value(std::declval())) + next_value(T&& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_generate_traits::type>::generate_next_value(std::declval())); + } // namespace generators + + using sprout::generators::next_value; +} // namespace sprout + +#endif // #ifndef SPROUT_GENERATOR_GENERATE_FUNCTIONS_FWD_HPP diff --git a/sprout/generator/generated_value.hpp b/sprout/generator/generated_value.hpp index e0abea59..d5b54a38 100644 --- a/sprout/generator/generated_value.hpp +++ b/sprout/generator/generated_value.hpp @@ -39,8 +39,6 @@ namespace sprout { return sprout::generators::generator_access_traits::type>::get_generated_value(SPROUT_FORWARD(T, t)); } } // namespace generators - - using sprout::generators::generated_value; } // namespace sprout #endif // #ifndef SPROUT_GENERATOR_GENERATED_VALUE_HPP diff --git a/sprout/generator/generator_access_traits.hpp b/sprout/generator/generator_access_traits.hpp index 7c34561f..64a29c22 100644 --- a/sprout/generator/generator_access_traits.hpp +++ b/sprout/generator/generator_access_traits.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/sprout/generator/generator_generate_traits.hpp b/sprout/generator/generator_generate_traits.hpp new file mode 100644 index 00000000..40087746 --- /dev/null +++ b/sprout/generator/generator_generate_traits.hpp @@ -0,0 +1,97 @@ +/*============================================================================= + 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_GENERATE_TRAITS_HPP +#define SPROUT_GENERATOR_GENERATOR_GENERATE_TRAITS_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout_generator_detail { + using sprout_adl::generate_next_value; + + template + inline SPROUT_CONSTEXPR decltype(generate_next_value(std::declval())) + call_generate_next_value(Gen&& gen) + SPROUT_NOEXCEPT_IF_EXPR(generate_next_value(std::declval())) + { + return generate_next_value(SPROUT_FORWARD(Gen, gen)); + } +} // namespace sprout_generator_detail + +namespace sprout { + namespace generators { + namespace detail { + template + struct generator_generate_traits_const_default { + public: + // generate_next_value + static SPROUT_CONSTEXPR decltype(sprout::generators::generator_generate_traits::generate_next_value(std::declval())) + generate_next_value(Gen const& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_generate_traits::generate_next_value(std::declval())) + { + return sprout::generators::generator_generate_traits::generate_next_value(t); + } + }; + } // namespace detail + + // + // generator_generate_generate_next_value_default + // + template + struct generator_generate_generate_next_value_default { + public: + static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_generate_next_value(std::declval())) + generate_next_value(Gen& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_generate_next_value(std::declval())) + { + return sprout_generator_detail::call_generate_next_value(t); + } + static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_generate_next_value(std::declval())) + generate_next_value(Gen&& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_generate_next_value(std::declval())) + { + return sprout_generator_detail::call_generate_next_value(sprout::move(t)); + } + static SPROUT_CONSTEXPR decltype(sprout_generator_detail::call_generate_next_value(std::declval())) + generate_next_value(Gen const& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout_generator_detail::call_generate_next_value(std::declval())) + { + return sprout_generator_detail::call_generate_next_value(t); + } + }; + + // + // generator_generate_traits_default + // + template + struct generator_generate_traits_default + : public sprout::generators::generator_generate_generate_next_value_default + {}; + + // + // generator_generate_traits + // + template + struct generator_generate_traits + : public sprout::generators::generator_generate_traits_default + {}; + template + struct generator_generate_traits + : public sprout::generators::detail::generator_generate_traits_const_default + {}; + } // namespace generators +} // namespace sprout + +#include +#include + +#endif // #ifndef SPROUT_GENERATOR_GENERATOR_GENERATE_TRAITS_HPP diff --git a/sprout/generator/next_generator.hpp b/sprout/generator/next_generator.hpp index bb50de83..4b13d580 100644 --- a/sprout/generator/next_generator.hpp +++ b/sprout/generator/next_generator.hpp @@ -28,7 +28,7 @@ namespace sprout { // && callable sprout::as_const(t).next_generator() // -> sprout::const_reference_cast().next_generator())>(sprout::as_const(cont).next_generator()) // otherwise, callable t.next_generator() -> t.next_generator() - // otherwise, T is InputIterator -> sprout::next(t) + // otherwise, T is InputIterator -> t // otherwise -> sprout::tuples::get<0>(t) // template @@ -39,8 +39,6 @@ namespace sprout { return sprout::generators::generator_access_traits::type>::get_next_generator(SPROUT_FORWARD(T, t)); } } // namespace generators - - using sprout::generators::next_generator; } // namespace sprout #endif // #ifndef SPROUT_GENERATOR_NEXT_GENERATOR_HPP diff --git a/sprout/generator/next_value.hpp b/sprout/generator/next_value.hpp new file mode 100644 index 00000000..885acce3 --- /dev/null +++ b/sprout/generator/next_value.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + 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_NEXT_VALUE_HPP +#define SPROUT_GENERATOR_NEXT_VALUE_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace generators { + // + // next_value + // + // effect: + // sprout::generators::generator_generate_traits::generate_next_value(t) + // [default] + // ADL callable generate_next_value(t) -> generate_next_value(t) + // [default] + // otherwise, callable t.next_value() -> t.next_value() + // otherwise, T is InputIterator -> sprout::next(t) + // otherwise, callable t() -> t() + // otherwise -> sprout::generators::next_value(sprout::generators::next_generator(t)) + // + template + inline SPROUT_CONSTEXPR decltype(sprout::generators::generator_generate_traits::type>::generate_next_value(std::declval())) + next_value(T&& t) + SPROUT_NOEXCEPT_IF_EXPR(sprout::generators::generator_generate_traits::type>::generate_next_value(std::declval())) + { + return sprout::generators::generator_generate_traits::type>::generate_next_value(SPROUT_FORWARD(T, t)); + } + } // namespace generators +} // namespace sprout + +#endif // #ifndef SPROUT_GENERATOR_NEXT_VALUE_HPP diff --git a/sprout/generator/results.hpp b/sprout/generator/results.hpp index d2f5d71c..d5b6a380 100644 --- a/sprout/generator/results.hpp +++ b/sprout/generator/results.hpp @@ -8,11 +8,12 @@ #ifndef SPROUT_GENERATOR_RESULTS_HPP #define SPROUT_GENERATOR_RESULTS_HPP -#include #include +#include #include #include #include +#include namespace sprout { namespace generators { @@ -32,12 +33,21 @@ namespace sprout { struct next_generator : public std::decay()()))> {}; + + // + // next_value + // + template + struct next_value + : public std::decay()()))> + {}; } // namespace results } // namespace generators namespace results { - using sprout::generators::generated_value; - using sprout::generators::next_generator; + using sprout::generators::results::generated_value; + using sprout::generators::results::next_generator; + using sprout::generators::results::next_value; } // namespace results } // namespace sprout diff --git a/sprout/generator/traits.hpp b/sprout/generator/traits.hpp new file mode 100644 index 00000000..0c4a2044 --- /dev/null +++ b/sprout/generator/traits.hpp @@ -0,0 +1,16 @@ +/*============================================================================= + 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_TRAITS_HPP +#define SPROUT_GENERATOR_TRAITS_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_GENERATOR_TRAITS_HPP diff --git a/sprout/generator/traits_fwd.hpp b/sprout/generator/traits_fwd.hpp index 676e8dab..924e0557 100644 --- a/sprout/generator/traits_fwd.hpp +++ b/sprout/generator/traits_fwd.hpp @@ -17,9 +17,16 @@ namespace sprout { // template struct generator_access_traits; + + // + // generator_generate_traits + // + template + struct generator_generate_traits; } // namespace generators using sprout::generators::generator_access_traits; + using sprout::generators::generator_generate_traits; } // namespace sprout #endif // #ifndef SPROUT_GENERATOR_TRAITS_FWD_HPP