From 73ead93fe5fcfc8f50d7ca2de526d22c3b840abd Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Fri, 21 Sep 2012 15:43:30 +0900 Subject: [PATCH] destructive change sprout::generate -> sprout::unfold add range adapter reversed, replaced, filtered --- libs/algorithm/test/generate.cpp | 26 +- libs/algorithm/test/generate_n.cpp | 26 +- libs/algorithm/test/modifying.cpp | 8 +- libs/algorithm/test/unfold.cpp | 80 ++ libs/algorithm/test/unfold_n.cpp | 84 +++ sprout/algorithm/fit.hpp | 2 + sprout/algorithm/fit/generate.hpp | 14 +- sprout/algorithm/fit/generate_n.hpp | 27 +- sprout/algorithm/fit/unfold.hpp | 44 ++ sprout/algorithm/fit/unfold_n.hpp | 47 ++ sprout/algorithm/fixed.hpp | 2 + sprout/algorithm/fixed/generate.hpp | 164 ++--- sprout/algorithm/fixed/generate_n.hpp | 13 +- sprout/algorithm/fixed/unfold.hpp | 167 +++++ sprout/algorithm/fixed/unfold_n.hpp | 29 + sprout/algorithm/unfold.hpp | 8 + sprout/algorithm/unfold_n.hpp | 8 + sprout/array/array.hpp | 3 +- sprout/brainfuck.hpp | 9 + sprout/brainfuck/brainfuck.hpp | 211 ++++++ sprout/brainfuck/detail/convert.hpp | 30 + sprout/brainfuck/misa.hpp | 92 +++ sprout/brainfuck/ook.hpp | 92 +++ sprout/complex.hpp | 588 ++++++++++++++- sprout/cstring/memchr.hpp | 2 +- sprout/darkroom/objects.hpp | 1 - sprout/darkroom/objects/polygon/triangle.hpp | 4 +- sprout/functional/hash/hash.hpp | 138 ++-- sprout/generator.hpp | 6 + sprout/generator/functions.hpp | 7 + sprout/generator/generated_value.hpp | 209 ++++++ sprout/generator/next_generator.hpp | 209 ++++++ sprout/iterator.hpp | 2 + sprout/iterator/adaptor.hpp | 11 + sprout/iterator/filter_iterator.hpp | 202 ++++++ sprout/iterator/next.hpp | 6 +- sprout/iterator/prev.hpp | 6 +- sprout/iterator/reverse_iterator.hpp | 9 + sprout/iterator/wave.hpp | 10 + sprout/pit/hash.hpp | 2 +- sprout/pit/pit.hpp | 3 +- sprout/range/adaptor.hpp | 4 + sprout/range/adaptor/filtered.hpp | 139 ++++ sprout/range/adaptor/replaced.hpp | 160 ++++ sprout/range/adaptor/replaced_if.hpp | 164 +++++ sprout/range/adaptor/reversed.hpp | 106 +++ sprout/rational.hpp | 727 ++++++++++++++++++- sprout/rational/arithmetic.hpp | 2 +- sprout/rational/comparison.hpp | 2 +- sprout/rational/conversion.hpp | 2 +- sprout/rational/exceptions.hpp | 2 +- sprout/rational/hash.hpp | 2 +- sprout/rational/io.hpp | 2 +- sprout/rational/rational.hpp | 2 +- sprout/rational/values.hpp | 2 +- sprout/tpp/algorithm.hpp | 95 +++ sprout/utility/pair.hpp | 12 +- sprout/uuid/uuid.hpp | 3 +- sprout/weed/parser/directive/replace.hpp | 108 +++ testspr/tools.hpp | 23 + 60 files changed, 3840 insertions(+), 318 deletions(-) create mode 100644 libs/algorithm/test/unfold.cpp create mode 100644 libs/algorithm/test/unfold_n.cpp create mode 100644 sprout/algorithm/fit/unfold.hpp create mode 100644 sprout/algorithm/fit/unfold_n.hpp create mode 100644 sprout/algorithm/fixed/unfold.hpp create mode 100644 sprout/algorithm/fixed/unfold_n.hpp create mode 100644 sprout/algorithm/unfold.hpp create mode 100644 sprout/algorithm/unfold_n.hpp create mode 100644 sprout/brainfuck.hpp create mode 100644 sprout/brainfuck/brainfuck.hpp create mode 100644 sprout/brainfuck/detail/convert.hpp create mode 100644 sprout/brainfuck/misa.hpp create mode 100644 sprout/brainfuck/ook.hpp create mode 100644 sprout/generator.hpp create mode 100644 sprout/generator/functions.hpp create mode 100644 sprout/generator/generated_value.hpp create mode 100644 sprout/generator/next_generator.hpp create mode 100644 sprout/iterator/adaptor.hpp create mode 100644 sprout/iterator/filter_iterator.hpp create mode 100644 sprout/iterator/wave.hpp create mode 100644 sprout/range/adaptor/filtered.hpp create mode 100644 sprout/range/adaptor/replaced.hpp create mode 100644 sprout/range/adaptor/replaced_if.hpp create mode 100644 sprout/range/adaptor/reversed.hpp create mode 100644 sprout/tpp/algorithm.hpp create mode 100644 sprout/weed/parser/directive/replace.hpp diff --git a/libs/algorithm/test/generate.cpp b/libs/algorithm/test/generate.cpp index 51feb1e6..9ecbd2ca 100644 --- a/libs/algorithm/test/generate.cpp +++ b/libs/algorithm/test/generate.cpp @@ -11,29 +11,27 @@ namespace testspr { static void algorithm_generate_test() { using namespace sprout; { - SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{0}}; // 生成 { SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate( arr1, - testspr::x2(), - 2 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}} + array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}} )); } { SPROUT_STATIC_CONSTEXPR auto generated = sprout::fit::generate( arr1, - testspr::x2(), - 2 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}} + array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}} )); } // 生成 @@ -41,31 +39,29 @@ namespace testspr { { SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate( sprout::sub(arr1, 2, 8), - testspr::x2(), - 2 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{2, 4, 8, 16, 32, 64}} + array{{1, 2, 3, 4, 5, 6}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(generated), - array{{1, 2, 2, 4, 8, 16, 32, 64, 9, 10}} + array{{0, 0, 1, 2, 3, 4, 5, 6, 0, 0}} )); } { SPROUT_STATIC_CONSTEXPR auto generated = sprout::fit::generate( sprout::sub(arr1, 2, 8), - testspr::x2(), - 2 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{2, 4, 8, 16, 32, 64}} + array{{1, 2, 3, 4, 5, 6}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(generated), - array{{1, 2, 2, 4, 8, 16, 32, 64, 9, 10}} + array{{0, 0, 1, 2, 3, 4, 5, 6, 0, 0}} )); } } diff --git a/libs/algorithm/test/generate_n.cpp b/libs/algorithm/test/generate_n.cpp index f07df9c5..9d8af43a 100644 --- a/libs/algorithm/test/generate_n.cpp +++ b/libs/algorithm/test/generate_n.cpp @@ -11,31 +11,29 @@ namespace testspr { static void algorithm_generate_n_test() { using namespace sprout; { - SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{0}}; // 生成 { SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate_n( arr1, 4, - testspr::x2(), - 1 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{1, 2, 4, 8, 5, 6, 7, 8, 9, 10}} + array{{1, 2, 3, 4, 0, 0, 0, 0, 0, 0}} )); } { SPROUT_STATIC_CONSTEXPR auto generated = sprout::fit::generate_n( arr1, 4, - testspr::x2(), - 1 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{1, 2, 4, 8}} + array{{1, 2, 3, 4}} )); } // 生成 @@ -44,32 +42,30 @@ namespace testspr { SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate_n( sprout::sub(arr1, 2, 8), 4, - testspr::x2(), - 1 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{1, 2, 4, 8, 7, 8}} + array{{1, 2, 3, 4, 0, 0}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(generated), - array{{1, 2, 1, 2, 4, 8, 7, 8, 9, 10}} + array{{0, 0, 1, 2, 3, 4, 0, 0, 0, 0}} )); } { SPROUT_STATIC_CONSTEXPR auto generated = sprout::fit::generate_n( sprout::sub(arr1, 2, 8), 4, - testspr::x2(), - 1 + testspr::gen_iota(1) ); TESTSPR_BOTH_ASSERT(testspr::equal( generated, - array{{1, 2, 4, 8}} + array{{1, 2, 3, 4}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(generated), - array{{1, 2, 1, 2, 4, 8, 7, 8, 9, 10}} + array{{0, 0, 1, 2, 3, 4, 0, 0, 0, 0}} )); } } diff --git a/libs/algorithm/test/modifying.cpp b/libs/algorithm/test/modifying.cpp index 8ada63f8..dc76b6e7 100644 --- a/libs/algorithm/test/modifying.cpp +++ b/libs/algorithm/test/modifying.cpp @@ -19,6 +19,8 @@ #include "./fill_n.cpp" #include "./generate.cpp" #include "./generate_n.cpp" +#include "./unfold.cpp" +#include "./unfold_n.cpp" #include "./remove.cpp" #include "./remove_if.cpp" #include "./remove_copy.cpp" @@ -76,10 +78,12 @@ namespace testspr { testspr::algorithm_replace_if_test(); testspr::algorithm_replace_copy_test(); testspr::algorithm_replace_copy_if_test(); - testspr::algorithm_fill_test(); - testspr::algorithm_fill_n_test(); testspr::algorithm_generate_test(); testspr::algorithm_generate_n_test(); + testspr::algorithm_fill_test(); + testspr::algorithm_fill_n_test(); + testspr::algorithm_unfold_test(); + testspr::algorithm_unfold_n_test(); testspr::algorithm_remove_test(); testspr::algorithm_remove_if_test(); testspr::algorithm_remove_copy_test(); diff --git a/libs/algorithm/test/unfold.cpp b/libs/algorithm/test/unfold.cpp new file mode 100644 index 00000000..0346177b --- /dev/null +++ b/libs/algorithm/test/unfold.cpp @@ -0,0 +1,80 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_CPP + +#include +#include +#include +#include +#include + +namespace testspr { + static void algorithm_unfold_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + + // 生成 + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold( + arr1, + testspr::x2(), + 2 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::fit::unfold( + arr1, + testspr::x2(), + 2 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}} + )); + } + // 生成 + // 範囲の切り出し + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold( + sprout::sub(arr1, 2, 8), + testspr::x2(), + 2 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{2, 4, 8, 16, 32, 64}} + )); + TESTSPR_BOTH_ASSERT(testspr::equal( + sprout::get_internal(unfolded), + array{{1, 2, 2, 4, 8, 16, 32, 64, 9, 10}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::fit::unfold( + sprout::sub(arr1, 2, 8), + testspr::x2(), + 2 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{2, 4, 8, 16, 32, 64}} + )); + TESTSPR_BOTH_ASSERT(testspr::equal( + sprout::get_internal(unfolded), + array{{1, 2, 2, 4, 8, 16, 32, 64, 9, 10}} + )); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_unfold_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_CPP diff --git a/libs/algorithm/test/unfold_n.cpp b/libs/algorithm/test/unfold_n.cpp new file mode 100644 index 00000000..f8163764 --- /dev/null +++ b/libs/algorithm/test/unfold_n.cpp @@ -0,0 +1,84 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_N_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_N_CPP + +#include +#include +#include +#include +#include + +namespace testspr { + static void algorithm_unfold_n_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + + // 生成 + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold_n( + arr1, + 4, + testspr::x2(), + 1 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{1, 2, 4, 8, 5, 6, 7, 8, 9, 10}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::fit::unfold_n( + arr1, + 4, + testspr::x2(), + 1 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{1, 2, 4, 8}} + )); + } + // 生成 + // 範囲の切り出し + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold_n( + sprout::sub(arr1, 2, 8), + 4, + testspr::x2(), + 1 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{1, 2, 4, 8, 7, 8}} + )); + TESTSPR_BOTH_ASSERT(testspr::equal( + sprout::get_internal(unfolded), + array{{1, 2, 1, 2, 4, 8, 7, 8, 9, 10}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::fit::unfold_n( + sprout::sub(arr1, 2, 8), + 4, + testspr::x2(), + 1 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + unfolded, + array{{1, 2, 4, 8}} + )); + TESTSPR_BOTH_ASSERT(testspr::equal( + sprout::get_internal(unfolded), + array{{1, 2, 1, 2, 4, 8, 7, 8, 9, 10}} + )); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_unfold_n_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_N_CPP diff --git a/sprout/algorithm/fit.hpp b/sprout/algorithm/fit.hpp index ab342abd..a9fb0d70 100644 --- a/sprout/algorithm/fit.hpp +++ b/sprout/algorithm/fit.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/sprout/algorithm/fit/generate.hpp b/sprout/algorithm/fit/generate.hpp index 95684707..35caa726 100644 --- a/sprout/algorithm/fit/generate.hpp +++ b/sprout/algorithm/fit/generate.hpp @@ -11,16 +11,15 @@ namespace sprout { namespace fit { namespace detail { - template + template inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type generate_impl( Container const& cont, Generator gen, - typename sprout::container_traits::difference_type offset, - Inits const&... inits + typename sprout::container_traits::difference_type offset ) { return sprout::sub_copy( - sprout::get_internal(sprout::fixed::generate(cont, gen, inits...)), + sprout::get_internal(sprout::fixed::generate(cont, gen)), offset, offset + sprout::size(cont) ); @@ -29,14 +28,13 @@ namespace sprout { // // generate // - template + template inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type generate( Container const& cont, - Generator gen, - Inits const&... inits + Generator gen ) { - return sprout::fit::detail::generate_impl(cont, gen, sprout::internal_begin_offset(cont), inits...); + return sprout::fit::detail::generate_impl(cont, gen, sprout::internal_begin_offset(cont)); } } // namespace fit } // namespace sprout diff --git a/sprout/algorithm/fit/generate_n.hpp b/sprout/algorithm/fit/generate_n.hpp index 3b63be64..c1abf5f1 100644 --- a/sprout/algorithm/fit/generate_n.hpp +++ b/sprout/algorithm/fit/generate_n.hpp @@ -12,17 +12,15 @@ namespace sprout { namespace fit { namespace detail { - template - inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type generate_n_impl( - Container const& cont, - Size n, - Generator gen, - typename sprout::container_traits::difference_type offset, - Inits const&... inits + template + inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type + generate_n_impl( + Container const& cont, Size n, Generator gen, + typename sprout::container_traits::difference_type offset ) { return sprout::sub_copy( - sprout::get_internal(sprout::fixed::generate_n(cont, n, gen, inits...)), + sprout::get_internal(sprout::fixed::generate_n(cont, n, gen)), offset, offset + NS_SSCRISK_CEL_OR_SPROUT::min(n, sprout::size(cont)) ); @@ -31,15 +29,10 @@ namespace sprout { // // generate_n // - template - inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type generate_n( - Container const& cont, - Size n, - Generator gen, - Inits const&... inits - ) - { - return sprout::fit::detail::generate_n_impl(cont, n, gen, sprout::internal_begin_offset(cont), inits...); + template + inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type + generate_n(Container const& cont, Size n, Generator gen) { + return sprout::fit::detail::generate_n_impl(cont, n, gen, sprout::internal_begin_offset(cont)); } } // namespace fit } // namespace sprout diff --git a/sprout/algorithm/fit/unfold.hpp b/sprout/algorithm/fit/unfold.hpp new file mode 100644 index 00000000..0cac68e2 --- /dev/null +++ b/sprout/algorithm/fit/unfold.hpp @@ -0,0 +1,44 @@ +#ifndef SPROUT_ALGORITHM_FIT_UNFOLD_HPP +#define SPROUT_ALGORITHM_FIT_UNFOLD_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace fit { + namespace detail { + template + inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type unfold_impl( + Container const& cont, + Generator gen, + typename sprout::container_traits::difference_type offset, + Inits const&... inits + ) + { + return sprout::sub_copy( + sprout::get_internal(sprout::fixed::unfold(cont, gen, inits...)), + offset, + offset + sprout::size(cont) + ); + } + } // namespace detail + // + // unfold + // + template + inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type unfold( + Container const& cont, + Generator gen, + Inits const&... inits + ) + { + return sprout::fit::detail::unfold_impl(cont, gen, sprout::internal_begin_offset(cont), inits...); + } + } // namespace fit +} // namespace sprout + +#endif // #ifndef SPROUT_ALGORITHM_FIT_UNFOLD_HPP diff --git a/sprout/algorithm/fit/unfold_n.hpp b/sprout/algorithm/fit/unfold_n.hpp new file mode 100644 index 00000000..eb2682ee --- /dev/null +++ b/sprout/algorithm/fit/unfold_n.hpp @@ -0,0 +1,47 @@ +#ifndef SPROUT_ALGORITHM_FIT_UNFOLD_N_HPP +#define SPROUT_ALGORITHM_FIT_UNFOLD_N_HPP + +#include +#include +#include +#include +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + namespace fit { + namespace detail { + template + inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type unfold_n_impl( + Container const& cont, + Size n, + Generator gen, + typename sprout::container_traits::difference_type offset, + Inits const&... inits + ) + { + return sprout::sub_copy( + sprout::get_internal(sprout::fixed::unfold_n(cont, n, gen, inits...)), + offset, + offset + NS_SSCRISK_CEL_OR_SPROUT::min(n, sprout::size(cont)) + ); + } + } // namespace detail + // + // unfold_n + // + template + inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm::type unfold_n( + Container const& cont, + Size n, + Generator gen, + Inits const&... inits + ) + { + return sprout::fit::detail::unfold_n_impl(cont, n, gen, sprout::internal_begin_offset(cont), inits...); + } + } // namespace fit +} // namespace sprout + +#endif // #ifndef SPROUT_ALGORITHM_FIT_UNFOLD_N_HPP diff --git a/sprout/algorithm/fixed.hpp b/sprout/algorithm/fixed.hpp index 3a994b92..5b146948 100644 --- a/sprout/algorithm/fixed.hpp +++ b/sprout/algorithm/fixed.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/sprout/algorithm/fixed/generate.hpp b/sprout/algorithm/fixed/generate.hpp index d523f796..59b6efd5 100644 --- a/sprout/algorithm/fixed/generate.hpp +++ b/sprout/algorithm/fixed/generate.hpp @@ -1,163 +1,83 @@ #ifndef SPROUT_ALGORITHM_FIXED_GENERATE_HPP #define SPROUT_ALGORITHM_FIXED_GENERATE_HPP -#include #include #include #include #include -#include #include +#include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { namespace detail { - template + template inline SPROUT_CONSTEXPR typename std::enable_if< - InitSize == 0, - typename sprout::container_traits::value_type - >::type call_gen( - Generator gen, + sprout::container_traits::static_size == sizeof...(Args) + 1, + typename sprout::fixed::result_of::algorithm::type + >::type generate_impl_1( + Container const& cont, Gen const& gen, + typename sprout::container_traits::size_type size, Args const&... args ) { - return gen(); + return sprout::remake(cont, size, args..., sprout::generators::generated_value(gen)); } - template + template inline SPROUT_CONSTEXPR typename std::enable_if< - InitSize != 0 && InitSize == sizeof...(Args) + 1, - typename sprout::container_traits::value_type - >::type call_gen( - Generator gen, - Head const& head, + sprout::container_traits::static_size != sizeof...(Args) + 1, + typename sprout::fixed::result_of::algorithm::type + >::type + generate_impl_1( + Container const& cont, Gen const& gen, + typename sprout::container_traits::size_type size, Args const&... args ) { - return gen(head, args...); - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - InitSize != 0 && InitSize != sizeof...(Args) + 1, - typename sprout::container_traits::value_type - >::type call_gen( - Generator gen, - Head const& head, - Args const&... args - ) - { - return call_gen(gen, args...); + return sizeof...(Args) + 1 < size + ? sprout::fixed::detail::generate_impl_1( + cont, sprout::generators::next_generator(gen)(), size, + args..., sprout::generators::generated_value(gen) + ) + : sprout::detail::container_complate(cont, args..., sprout::generators::generated_value(gen)) + ; } template - inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type generate_impl_drop( - Container const& cont, - Generator gen, + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::container_traits::static_size == 0, + typename sprout::fixed::result_of::algorithm::type + >::type generate_impl( + Container const& cont, Generator gen, typename sprout::container_traits::size_type size ) { - return sprout::detail::container_complate(cont); + return sprout::remake(cont, size); } - template + template inline SPROUT_CONSTEXPR typename std::enable_if< - (sprout::container_traits::static_size >= sizeof...(Inits) + 1), + sprout::container_traits::static_size != 0, typename sprout::fixed::result_of::algorithm::type - >::type generate_impl_drop( - Container const& cont, - Generator gen, - typename sprout::container_traits::size_type size, - Head const& head, - Inits const&... inits + >::type + generate_impl( + Container const& cont, Generator gen, + typename sprout::container_traits::size_type size ) { - return size < sizeof...(Inits) + 1 - ? sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...) - : sprout::detail::container_complate(cont, head, inits...) + return size != 0 + ? sprout::fixed::detail::generate_impl_1(cont, gen(), size) + : sprout::detail::container_complate(cont) ; } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - (sprout::container_traits::static_size < sizeof...(Inits) + 1), - typename sprout::fixed::result_of::algorithm::type - >::type generate_impl_drop( - Container const& cont, - Generator gen, - typename sprout::container_traits::size_type size, - Head const& head, - Inits const&... inits - ) - { - return sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...); - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - sprout::container_traits::static_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type generate_impl_1( - Container const& cont, - Generator gen, - typename sprout::container_traits::size_type size, - Args const&... args - ) - { - return sprout::remake(cont, sprout::size(cont), args...); - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - sprout::container_traits::static_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type generate_impl_1( - Container const& cont, - Generator gen, - typename sprout::container_traits::size_type size, - Args const&... args - ) - { - return sizeof...(Args) < size - ? sprout::fixed::detail::generate_impl_1(cont, gen, size, args..., sprout::fixed::detail::call_gen(gen, args...)) - : sprout::detail::container_complate(cont, args...) - ; - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - (sprout::container_traits::static_size > sizeof...(Inits)), - typename sprout::fixed::result_of::algorithm::type - >::type generate_impl( - Container const& cont, - Generator gen, - typename sprout::container_traits::size_type size, - Inits const&... inits - ) - { - return sizeof...(Inits) < size - ? sprout::fixed::detail::generate_impl_1(cont, gen, size, inits...) - : sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...) - ; - } - template - inline SPROUT_CONSTEXPR typename std::enable_if< - (sprout::container_traits::static_size <= sizeof...(Inits)), - typename sprout::fixed::result_of::algorithm::type - >::type generate_impl( - Container const& cont, - Generator gen, - typename sprout::container_traits::size_type size, - Inits const&... inits - ) - { - return sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...); - } } // namespace detail // // generate // - template - inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type generate( - Container const& cont, - Generator gen, - Inits const&... inits - ) - { - return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont), inits...); + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + generate(Container const& cont, Generator gen) { + return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont)); } } // namespace fixed diff --git a/sprout/algorithm/fixed/generate_n.hpp b/sprout/algorithm/fixed/generate_n.hpp index d7264d6d..d98f47a9 100644 --- a/sprout/algorithm/fixed/generate_n.hpp +++ b/sprout/algorithm/fixed/generate_n.hpp @@ -11,15 +11,10 @@ namespace sprout { // // generate_n // - template - inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type generate_n( - Container const& cont, - Size n, - Generator gen, - Inits const&... inits - ) - { - return sprout::fixed::detail::generate_impl(cont, gen, n, inits...); + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + generate_n(Container const& cont, Size n, Generator gen) { + return sprout::fixed::detail::generate_impl(cont, gen, n); } } // namespace fixed diff --git a/sprout/algorithm/fixed/unfold.hpp b/sprout/algorithm/fixed/unfold.hpp new file mode 100644 index 00000000..f6b55bb6 --- /dev/null +++ b/sprout/algorithm/fixed/unfold.hpp @@ -0,0 +1,167 @@ +#ifndef SPROUT_ALGORITHM_FIXED_UNFOLD_HPP +#define SPROUT_ALGORITHM_FIXED_UNFOLD_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace fixed { + namespace detail { + template + inline SPROUT_CONSTEXPR typename std::enable_if< + InitSize == 0, + typename sprout::container_traits::value_type + >::type call_gen( + Generator gen, + Args const&... args + ) + { + return gen(); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + InitSize != 0 && InitSize == sizeof...(Args) + 1, + typename sprout::container_traits::value_type + >::type call_gen( + Generator gen, + Head const& head, + Args const&... args + ) + { + return gen(head, args...); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + InitSize != 0 && InitSize != sizeof...(Args) + 1, + typename sprout::container_traits::value_type + >::type call_gen( + Generator gen, + Head const& head, + Args const&... args + ) + { + return call_gen(gen, args...); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type unfold_impl_drop( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size + ) + { + return sprout::detail::container_complate(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (sprout::container_traits::static_size >= sizeof...(Inits) + 1), + typename sprout::fixed::result_of::algorithm::type + >::type unfold_impl_drop( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size, + Head const& head, + Inits const&... inits + ) + { + return size < sizeof...(Inits) + 1 + ? sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...) + : sprout::detail::container_complate(cont, head, inits...) + ; + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (sprout::container_traits::static_size < sizeof...(Inits) + 1), + typename sprout::fixed::result_of::algorithm::type + >::type unfold_impl_drop( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size, + Head const& head, + Inits const&... inits + ) + { + return sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::container_traits::static_size == sizeof...(Args), + typename sprout::fixed::result_of::algorithm::type + >::type unfold_impl_1( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size, + Args const&... args + ) + { + return sprout::remake(cont, sprout::size(cont), args...); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::container_traits::static_size != sizeof...(Args), + typename sprout::fixed::result_of::algorithm::type + >::type unfold_impl_1( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size, + Args const&... args + ) + { + return sizeof...(Args) < size + ? sprout::fixed::detail::unfold_impl_1(cont, gen, size, args..., sprout::fixed::detail::call_gen(gen, args...)) + : sprout::detail::container_complate(cont, args...) + ; + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (sprout::container_traits::static_size > sizeof...(Inits)), + typename sprout::fixed::result_of::algorithm::type + >::type unfold_impl( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size, + Inits const&... inits + ) + { + return sizeof...(Inits) < size + ? sprout::fixed::detail::unfold_impl_1(cont, gen, size, inits...) + : sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...) + ; + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + (sprout::container_traits::static_size <= sizeof...(Inits)), + typename sprout::fixed::result_of::algorithm::type + >::type unfold_impl( + Container const& cont, + Generator gen, + typename sprout::container_traits::size_type size, + Inits const&... inits + ) + { + return sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...); + } + } // namespace detail + // + // unfold + // + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type unfold( + Container const& cont, + Generator gen, + Inits const&... inits + ) + { + return sprout::fixed::detail::unfold_impl(cont, gen, sprout::size(cont), inits...); + } + } // namespace fixed + + using sprout::fixed::unfold; +} // namespace sprout + +#endif // #ifndef SPROUT_ALGORITHM_FIXED_UNFOLD_HPP diff --git a/sprout/algorithm/fixed/unfold_n.hpp b/sprout/algorithm/fixed/unfold_n.hpp new file mode 100644 index 00000000..827ec2e7 --- /dev/null +++ b/sprout/algorithm/fixed/unfold_n.hpp @@ -0,0 +1,29 @@ +#ifndef SPROUT_ALGORITHM_FIXED_UNFOLD_N_HPP +#define SPROUT_ALGORITHM_FIXED_UNFOLD_N_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace fixed { + // + // unfold_n + // + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type unfold_n( + Container const& cont, + Size n, + Generator gen, + Inits const&... inits + ) + { + return sprout::fixed::detail::unfold_impl(cont, gen, n, inits...); + } + } // namespace fixed + + using sprout::fixed::unfold_n; +} // namespace sprout + +#endif // #ifndef SPROUT_ALGORITHM_FIXED_UNFOLD_N_HPP diff --git a/sprout/algorithm/unfold.hpp b/sprout/algorithm/unfold.hpp new file mode 100644 index 00000000..13d60c6e --- /dev/null +++ b/sprout/algorithm/unfold.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_ALGORITHM_UNFOLD_HPP +#define SPROUT_ALGORITHM_UNFOLD_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_ALGORITHM_UNFOLD_HPP diff --git a/sprout/algorithm/unfold_n.hpp b/sprout/algorithm/unfold_n.hpp new file mode 100644 index 00000000..d677e4d5 --- /dev/null +++ b/sprout/algorithm/unfold_n.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_ALGORITHM_UNFOLD_N_HPP +#define SPROUT_ALGORITHM_UNFOLD_N_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_ALGORITHM_UNFOLD_N_HPP diff --git a/sprout/array/array.hpp b/sprout/array/array.hpp index ff88e349..bdb13afe 100644 --- a/sprout/array/array.hpp +++ b/sprout/array/array.hpp @@ -9,7 +9,8 @@ #include #include #include -#include +#include +#include #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION # include diff --git a/sprout/brainfuck.hpp b/sprout/brainfuck.hpp new file mode 100644 index 00000000..c2ccdcee --- /dev/null +++ b/sprout/brainfuck.hpp @@ -0,0 +1,9 @@ +#ifndef SPROUT_BRAINFUCK_HPP +#define SPROUT_BRAINFUCK_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_BRAINFUCK_HPP diff --git a/sprout/brainfuck/brainfuck.hpp b/sprout/brainfuck/brainfuck.hpp new file mode 100644 index 00000000..f5811149 --- /dev/null +++ b/sprout/brainfuck/brainfuck.hpp @@ -0,0 +1,211 @@ +#ifndef SPROUT_BRAINFUCK_BRAINFUCK_HPP +#define SPROUT_BRAINFUCK_BRAINFUCK_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace brainfuck { + namespace detail { + template + inline SPROUT_CONSTEXPR InputIterator + find_scope_end(InputIterator first, std::size_t count = 0) { + typedef typename std::iterator_traits::value_type value_type; + return *first == value_type('[') ? sprout::brainfuck::detail::find_scope_end(sprout::next(first), count + 1) + : *first == value_type(']') ? count == 0 + ? first + : sprout::brainfuck::detail::find_scope_end(sprout::next(first), count - 1) + : sprout::brainfuck::detail::find_scope_end(sprout::next(first), count) + ; + } + + template + inline SPROUT_CONSTEXPR BidirectionalIterator + find_scope_start(BidirectionalIterator first, std::size_t count = 0) { + typedef typename std::iterator_traits::value_type value_type; + return *first == value_type(']') ? sprout::brainfuck::detail::find_scope_start(sprout::prev(first), count + 1) + : *first == value_type('[') ? count == 0 + ? first + : sprout::brainfuck::detail::find_scope_start(sprout::prev(first), count - 1) + : sprout::brainfuck::detail::find_scope_start(sprout::prev(first), count) + ; + } + + template + inline SPROUT_CONSTEXPR bool + is_well_formed(InputIterator first, InputIterator last, std::size_t count = 0) { + typedef typename std::iterator_traits::value_type value_type; + return first == last ? count == 0 + : *first == value_type('[') + ? sprout::brainfuck::detail::is_well_formed(sprout::next(first), last, count + 1) + : *first == value_type(']') + ? count != 0 && sprout::brainfuck::detail::is_well_formed(sprout::next(first), last, count - 1) + : sprout::brainfuck::detail::is_well_formed(sprout::next(first), last, count) + ; + } + + template< + typename SourceBidirectionalIterator, typename Output, typename InputInputIterator, + typename Buffer, typename OutputBuffer + > + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_impl( + SourceBidirectionalIterator first, SourceBidirectionalIterator last, + Output const& output, InputInputIterator in_first, InputInputIterator in_last, + Buffer const& buffer, OutputBuffer const& out_buffer, std::size_t pos = 0, std::size_t out_pos = 0 + ) + { + typedef typename std::iterator_traits::value_type value_type; + typedef typename sprout::container_traits::value_type out_value_type; + return first == last ? sprout::fixed::copy(out_buffer.begin(), out_buffer.end(), output) + : *first == value_type('>') + ? sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + buffer, out_buffer, pos + 1, out_pos + ) + : *first == value_type('<') + ? sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + buffer, out_buffer, pos - 1, out_pos + ) + : *first == value_type('+') + ? sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + sprout::fixed::set(buffer, pos, value_type(buffer.at(pos) + 1)), out_buffer, pos, out_pos + ) + : *first == value_type('-') + ? sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + sprout::fixed::set(buffer, pos, value_type(buffer.at(pos) - 1)), out_buffer, pos, out_pos + ) + : *first == value_type('.') ? out_pos != out_buffer.size() + ? sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + buffer, sprout::fixed::set(out_buffer, out_pos, out_value_type(buffer.at(pos))), pos, out_pos + 1 + ) + : throw std::out_of_range("output out of range") + : *first == value_type(',') ? in_first != in_last + ? sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, sprout::next(in_first), in_last, + sprout::fixed::set(buffer, pos, value_type(*in_first)), out_buffer, pos, out_pos + ) + : throw std::out_of_range("input out of range") + : *first == value_type('[') ? buffer.at(pos) == 0 + ? sprout::brainfuck::detail::exec_impl( + sprout::next(sprout::brainfuck::detail::find_scope_end(sprout::next(first))), last, output, in_first, in_last, + buffer, out_buffer, pos, out_pos + ) + : sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + buffer, out_buffer, pos, out_pos + ) + : *first == value_type(']') ? buffer.at(pos) != 0 + ? sprout::brainfuck::detail::exec_impl( + sprout::next(sprout::brainfuck::detail::find_scope_start(sprout::prev(first))), last, output, in_first, in_last, + buffer, out_buffer, pos, out_pos + ) + : sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + buffer, out_buffer, pos, out_pos + ) + : sprout::brainfuck::detail::exec_impl( + sprout::next(first), last, output, in_first, in_last, + buffer, out_buffer, pos, out_pos + ) + ; + } + } // namespace detail + + // + // exec + // + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec( + SourceBidirectionalIterator first, SourceBidirectionalIterator last, + Output const& output, InputInputIterator in_first, InputInputIterator in_last + ) + { + typedef typename std::iterator_traits::value_type value_type; + typedef sprout::container_traits out_traits; + return sprout::brainfuck::detail::exec_impl( + first, last, output, in_first, in_last, + sprout::array{{}}, sprout::array{{}} + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec( + SourceBidirectionalIterator first, SourceBidirectionalIterator last, + Output const& output + ) + { + typedef typename std::iterator_traits::value_type value_type; + return sprout::brainfuck::exec( + first, last, output, sprout::value_iterator(value_type()), sprout::value_iterator() + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm< + sprout::array::value_type, BufferSize> + >::type + exec( + SourceBidirectionalIterator first, SourceBidirectionalIterator last + ) + { + typedef typename std::iterator_traits::value_type value_type; + return sprout::brainfuck::exec( + first, last, sprout::pit >() + ); + } + + // + // exec_range + // + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_range(Source const& source, Output const& output, Input const& input) { + return sprout::brainfuck::exec( + sprout::begin(source), sprout::end(source), output, sprout::begin(input), sprout::end(input) + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_range(Source const& source, Output const& output) { + return sprout::brainfuck::exec( + sprout::begin(source), sprout::end(source), output + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm< + sprout::array::value_type, BufferSize> + >::type + exec_range(Source const& source) { + return sprout::brainfuck::exec( + sprout::begin(source), sprout::end(source) + ); + } + + // + // is_well_formed + // + template + inline SPROUT_CONSTEXPR bool + is_well_formed(InputIterator first, InputIterator last) { + return sprout::brainfuck::detail::is_well_formed(first, last); + } + } // namespace brainfuck +} // namespace sprout + +#endif // #ifndef SPROUT_BRAINFUCK_BRAINFUCK_HPP diff --git a/sprout/brainfuck/detail/convert.hpp b/sprout/brainfuck/detail/convert.hpp new file mode 100644 index 00000000..69993397 --- /dev/null +++ b/sprout/brainfuck/detail/convert.hpp @@ -0,0 +1,30 @@ +#ifndef SPROUT_BRAINFUCK_DETAIL_CONVERT_HPP +#define SPROUT_BRAINFUCK_DETAIL_CONVERT_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace brainfuck { + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::pair::type, bool> + parsed_to_brainfuck(Parsed const& parsed, Result const& result) { + return parsed.success() + ? sprout::pair::type, bool>( + sprout::fixed::copy(sprout::begin(parsed.attr()), sprout::end(parsed.attr()), result), + true + ) + : sprout::pair::type, bool>( + sprout::deep_copy(result), + false + ) + ; + } + } // namespace detail + } // namespace brainfuck +} // namespace sprout + +#endif // #ifndef SPROUT_BRAINFUCK_DETAIL_CONVERT_HPP diff --git a/sprout/brainfuck/misa.hpp b/sprout/brainfuck/misa.hpp new file mode 100644 index 00000000..a1e588fb --- /dev/null +++ b/sprout/brainfuck/misa.hpp @@ -0,0 +1,92 @@ +#ifndef SPROUT_BRAINFUCK_MISA_HPP +#define SPROUT_BRAINFUCK_MISA_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace brainfuck { + namespace misa { + // + // to_brainfuck + // + template + inline SPROUT_CONSTEXPR sprout::pair::type, bool> + to_brainfuck(InputIterator first, InputIterator last, Result const& result) { + return sprout::brainfuck::detail::parsed_to_brainfuck( + sprout::weed::parse( + first, last, + *sprout::weed::lim::static_size>( + sprout::weed::replace('>') + [sprout::weed::lit('>') | "→" | "〜" | "ー"] + | sprout::weed::replace('<') + [sprout::weed::lit('<') | "←" | "★" | "☆"] + | sprout::weed::replace('+') + [sprout::weed::lit('+') | "あ" | "ぁ" | "お" | "ぉ"] + | sprout::weed::replace('-') + [sprout::weed::lit('-') | "っ" | "ッ"] + | sprout::weed::replace('.') + [sprout::weed::lit('.') | "!"] + | sprout::weed::replace(',') + [sprout::weed::lit(',') | "?"] + | sprout::weed::replace('[') + [sprout::weed::lit('[') | "「" | "『"] + | sprout::weed::replace(']') + [sprout::weed::lit(']') | "」" | "』"] + | sprout::weed::replace(' ') + [sprout::weed::char_] + ) + ), + result + ); + } + + // + // exec_range + // + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_range(Source const& source, Output const& output, Input const& input) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return sprout::brainfuck::exec_range( + sprout::brainfuck::misa::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit()).first, + output, input + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_range(Source const& source, Output const& output) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return sprout::brainfuck::exec_range( + sprout::brainfuck::misa::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit()).first, + output + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm< + sprout::array::value_type, BufferSize> + >::type + exec_range(Source const& source) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return sprout::brainfuck::exec_range( + sprout::brainfuck::misa::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit()).first + ); + } + } // namespace misa + } // namespace brainfuck +} // namespace sprout + +#endif // #ifndef SPROUT_BRAINFUCK_MISA_HPP diff --git a/sprout/brainfuck/ook.hpp b/sprout/brainfuck/ook.hpp new file mode 100644 index 00000000..75a6692b --- /dev/null +++ b/sprout/brainfuck/ook.hpp @@ -0,0 +1,92 @@ +#ifndef SPROUT_BRAINFUCK_OOK_HPP +#define SPROUT_BRAINFUCK_OOK_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace brainfuck { + namespace ook { + // + // to_brainfuck + // + template + inline SPROUT_CONSTEXPR sprout::pair::type, bool> + to_brainfuck(InputIterator first, InputIterator last, Result const& result) { + return sprout::brainfuck::detail::parsed_to_brainfuck( + sprout::weed::parse( + first, last, + *sprout::weed::lim::static_size>( + sprout::weed::replace('>') + ["Ook." >> *sprout::weed::space_ >> "Ook?"] + | sprout::weed::replace('>') + ["Ook?" >> *sprout::weed::space_ >> "Ook."] + | sprout::weed::replace('>') + ["Ook." >> *sprout::weed::space_ >> "Ook."] + | sprout::weed::replace('>') + ["Ook!" >> *sprout::weed::space_ >> "Ook!"] + | sprout::weed::replace('>') + ["Ook!" >> *sprout::weed::space_ >> "Ook."] + | sprout::weed::replace('>') + ["Ook." >> *sprout::weed::space_ >> "Ook!"] + | sprout::weed::replace('>') + ["Ook!" >> *sprout::weed::space_ >> "Ook?"] + | sprout::weed::replace('>') + ["Ook?" >> *sprout::weed::space_ >> "Ook!"] + | sprout::weed::replace(' ') + [sprout::weed::char_] + ) + ), + result + ); + } + + // + // exec_range + // + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_range(Source const& source, Output const& output, Input const& input) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return sprout::brainfuck::exec_range( + sprout::brainfuck::ook::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit()).first, + output, input + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + exec_range(Source const& source, Output const& output) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return sprout::brainfuck::exec_range( + sprout::brainfuck::ook::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit()).first, + output + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm< + sprout::array::value_type, BufferSize> + >::type + exec_range(Source const& source) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return sprout::brainfuck::exec_range( + sprout::brainfuck::ook::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit()).first + ); + } + } // namespace ook + } // namespace brainfuck +} // namespace sprout + +#endif // #ifndef SPROUT_BRAINFUCK_OOK_HPP diff --git a/sprout/complex.hpp b/sprout/complex.hpp index af66e015..34dfff14 100644 --- a/sprout/complex.hpp +++ b/sprout/complex.hpp @@ -1,12 +1,588 @@ #ifndef SPROUT_COMPLEX_HPP #define SPROUT_COMPLEX_HPP +#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + template + class complex; + template + SPROUT_CONSTEXPR T norm(sprout::complex const& x); + // + // complex + // + template + class complex { + public: + typedef T value_type; + private: + T re_; + T im_; + public: + SPROUT_CONSTEXPR complex(T const& re = T(), T const& im = T()) + : re_(re) + , im_(im) + {} + SPROUT_CONSTEXPR complex(complex const&) = default; + template + SPROUT_CONSTEXPR complex(complex const& other) + : re_(other.real()) + , im_(other.imag()) + {} + SPROUT_CONSTEXPR T real() const { + return re_; + } + void real(T re) { + re_ = re; + } + SPROUT_CONSTEXPR T imag() const{ + return im_; + } + void imag(T im) { + im_ = im; + } + complex& operator=(T const& rhs) { + re_ = rhs; + im_ = T(); + return *this; + } + complex& operator+=(T const& rhs) { + re_ += rhs; + return *this; + } + complex& operator-=(T const& rhs) { + re_ -= rhs; + return *this; + } + complex& operator*=(T const& rhs) { + re_ *= rhs; + im_ *= rhs; + return *this; + } + complex& operator/=(T const& rhs) { + re_ /= rhs; + im_ /= rhs; + return *this; + } + complex& operator=(complex const&) = default; + template + complex& operator=(complex const& rhs) { + re_ = rhs.real(); + im_ = rhs.imag(); + return *this; + } + template + complex& operator+=(complex const& rhs) { + re_ += rhs.real(); + im_ += rhs.imag(); + return *this; + } + template + complex& operator-=(complex const& rhs) { + re_ -= rhs.real(); + im_ -= rhs.imag(); + return *this; + } + template + complex& operator*=(complex const& rhs) { + return *this = complex( + re_ * rhs.real() - im_ * rhs.imag(), + re_ * rhs.imag() + im_ * rhs.real() + ); + } + template + complex& operator/=(complex const& rhs) { + T n = sprout::norm(rhs); + return *this = complex( + (re_ * rhs.real() + im_ * rhs.imag()) / n, + (im_ * rhs.real() - re_ * rhs.imag()) / n + ); + } + }; + // 26.4.6, operators: + template + inline SPROUT_CONSTEXPR sprout::complex operator+(sprout::complex const& lhs, sprout::complex const& rhs) { + return sprout::complex( + lhs.real() + rhs.real(), + lhs.imag() + rhs.imag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator+(sprout::complex const& lhs, T const& rhs) { + return sprout::complex( + lhs.real() + rhs, + lhs.imag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator+(T const& lhs, sprout::complex const& rhs) { + return sprout::complex( + lhs + rhs.real(), + rhs.imag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator-(sprout::complex const& lhs, sprout::complex const& rhs) { + return sprout::complex( + lhs.real() - rhs.real(), + lhs.imag() - rhs.imag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator-(sprout::complex const& lhs, T const& rhs) { + return sprout::complex( + lhs.real() - rhs, + lhs.imag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator-(T const& lhs, sprout::complex const& rhs) { + return sprout::complex( + lhs - rhs.real(), + -rhs.imag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator*(sprout::complex const& lhs, sprout::complex const& rhs) { + return sprout::complex( + lhs.real() * rhs.real() - lhs.imag() * rhs.imag(), + lhs.real() * rhs.imag() + lhs.imag() * rhs.real() + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator*(sprout::complex const& lhs, T const& rhs) { + return sprout::complex( + lhs.real() * rhs, + lhs.imag() * rhs + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator*(T const& lhs, sprout::complex const& rhs) { + return sprout::complex( + lhs * rhs.real(), + lhs * rhs.imag() + ); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex divides_impl( + sprout::complex const& lhs, + sprout::complex const& rhs, + T const& n + ) + { + return sprout::complex( + (lhs.real() * rhs.real() + lhs.imag() * rhs.imag()) / n, + (lhs.imag() * rhs.real() - lhs.real() * rhs.imag()) / n + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex divides_impl( + T const& lhs, + sprout::complex const& rhs, + T const& n + ) + { + return sprout::complex( + lhs * rhs.real() / n, + -lhs * rhs.imag() / n + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex operator/(sprout::complex const& lhs, sprout::complex const& rhs) { + return sprout::detail::divides_impl(lhs, rhs, sprout::norm(rhs)); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator/(sprout::complex const& lhs, T const& rhs) { + return sprout::complex( + lhs.real() / rhs, + lhs.imag() / rhs + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator/(T const& lhs, sprout::complex const& rhs) { + return sprout::detail::divides_impl(lhs, rhs, sprout::norm(rhs)); + } + template + inline SPROUT_CONSTEXPR sprout::complex operator+(sprout::complex const& x) { + return x; + } + template + inline SPROUT_CONSTEXPR sprout::complex operator-(sprout::complex const& x) { + return sprout::complex(-x.real(), -x.imag()); + } + template + inline SPROUT_CONSTEXPR bool operator==(sprout::complex const& lhs, sprout::complex const& rhs) { + return lhs.real() == rhs.real() && lhs.imag() == rhs.imag(); + } + template + inline SPROUT_CONSTEXPR bool operator==(sprout::complex const& lhs, T const& rhs) { + return lhs.real() == rhs && lhs.imag() == T(); + } + template + inline SPROUT_CONSTEXPR bool operator==(T const& lhs, sprout::complex const& rhs) { + return lhs == rhs.real() && T() == rhs.imag(); + } + template + inline SPROUT_CONSTEXPR bool operator!=(sprout::complex const& lhs, sprout::complex const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool operator!=(sprout::complex const& lhs, T const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool operator!=(T const& lhs, sprout::complex const& rhs) { + return !(lhs == rhs); + } + template + std::basic_istream& operator>>(std::basic_istream& lhs, sprout::complex& rhs) { + T re, im; + Char ch; + lhs >> ch; + if (ch == '(') { + lhs >> re >> ch; + if (ch == ',') { + lhs >> im >> ch; + if (ch == ')') { + rhs = sprout::complex(re, im); + } else { + lhs.setstate(std::ios_base::failbit); + } + } else if (ch == ')') { + rhs = re; + } else { + lhs.setstate(std::ios_base::failbit); + } + } else { + lhs.putback(ch); + lhs >> re; + rhs = re; + } + return lhs; + } + template + std::basic_ostream& operator<<(std::basic_ostream& lhs, sprout::complex const& rhs) { + return lhs << '(' << rhs.real() << ',' << rhs.imag() << ')'; + } + // 26.4.7, values: + template + inline SPROUT_CONSTEXPR T real(sprout::complex const& x) { + return x.real(); + } + template + inline SPROUT_CONSTEXPR T imag(sprout::complex const& x) { + return x.imag(); + } + template + inline SPROUT_CONSTEXPR T abs(sprout::complex const& x) { + return sprout::sqrt(sprout::norm(x)); + } + template + inline SPROUT_CONSTEXPR T arg(sprout::complex const& x) { + return sprout::atan2(x.imag(), x.real()); + } + template + inline SPROUT_CONSTEXPR T norm(sprout::complex const& x) { + return x.real() * x.real() + x.imag() * x.imag(); + } + template + inline SPROUT_CONSTEXPR sprout::complex conj(sprout::complex const& x) { + return sprout::complex(x.real(), -x.imag()); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex proj_impl(sprout::complex const& x, T const& den) { + return sprout::complex( + T(2) * x.real() / den, + T(2) * x.imag() / den + ); + } + } // detail + template + inline SPROUT_CONSTEXPR sprout::complex proj(sprout::complex const& x) { + return sprout::detail::proj_impl( + x, + sprout::norm(x) + T(1) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex polar(T const& rho, T const& theta = 0) { + return sprout::complex(rho * sprout::cos(theta), rho * sprout::sin(theta)); + } + // 26.4.8, transcendentals: + template + SPROUT_CONSTEXPR sprout::complex acos(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex asin(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex atan(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex acosh(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex asinh(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex atanh(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex cos(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex cosh(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex exp(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex log(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex log10(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex pow(sprout::complex const& x, T const& y); + template + SPROUT_CONSTEXPR sprout::complex pow(sprout::complex const& x, sprout::complex const& y); + template + SPROUT_CONSTEXPR sprout::complex pow(T const& x, sprout::complex const& y); + template + SPROUT_CONSTEXPR sprout::complex sin(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex sinh(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex sqrt(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex tan(sprout::complex const& x); + template + SPROUT_CONSTEXPR sprout::complex tanh(sprout::complex const& x); + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex acos_impl(sprout::complex const& t) { + return sprout::complex(sprout::math::half_pi() - t.real(), -t.imag()); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex acos(sprout::complex const& x) { + return sprout::detail::acos_impl(sprout::asin(x)); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex asin_impl(sprout::complex const& t) { + return sprout::complex(t.imag(), -t.real()); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex asin(sprout::complex const& x) { + return sprout::detail::asin_impl(sprout::asinh(sprout::complex(-x.imag(), x.real()))); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex atan_impl_1( + sprout::complex const& x, + T const& r2, + T const& z, + T const& num, + T const& den + ) + { + return sprout::complex( + T(0.5) * sprout::atan2(T(2) * x.real(), z), + T(0.25) * sprout::log((r2 + num * num) / (r2 + den * den)) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex atan_impl( + sprout::complex const& x, + T const& r2 + ) + { + return sprout::detail::atan_impl_1( + x, + r2, + T(1) - r2 - x.imag() * x.imag(), + x.imag() + T(1), + x.imag() - T(1) + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex atan(sprout::complex const& x) { + return sprout::detail::atan_impl(x, x.real() * x.real()); + } + template + inline SPROUT_CONSTEXPR sprout::complex acosh(sprout::complex const& x) { + return T(2) * sprout::log(sprout::sqrt(T(0.5) * (x + T(1))) + sprout::sqrt(T(0.5) * (x - T(1)))); + } + template + inline SPROUT_CONSTEXPR sprout::complex asinh(sprout::complex const& x) { + return sprout::log( + sprout::sqrt( + sprout::complex( + (x.real() - x.imag()) * (x.real() + x.imag()) + T(1), + T(2) * x.real() * x.imag() + ) + ) + + x + ); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex atanh_impl_1( + sprout::complex const& x, + T const& i2, + T const& z, + T const& num, + T const& den + ) + { + return sprout::complex( + T(0.25) * (sprout::log(i2 + num * num) - sprout::log(i2 + den * den)), + T(0.5) * sprout::atan2(T(2) * x.imag(), z) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex atanh_impl( + sprout::complex const& x, + T const& i2 + ) + { + return sprout::detail::atanh_impl_1( + x, + i2, + T(1) - i2 - x.real() * x.real(), + T(1) + x.imag(), + T(1) - x.imag() + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex atanh(sprout::complex const& x) { + return sprout::detail::atanh_impl(x, x.imag() * x.imag()); + } + template + inline SPROUT_CONSTEXPR sprout::complex cos(sprout::complex const& x) { + return sprout::complex( + sprout::cos(x.real()) * sprout::cosh(x.imag()), + -(sprout::sin(x.real()) * sprout::sinh(x.imag())) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex cosh(sprout::complex const& x) { + return sprout::complex( + sprout::cosh(x.real()) * sprout::cos(x.imag()), + sprout::sinh(x.real()) * sprout::sin(x.imag()) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex exp(sprout::complex const& x) { + return sprout::polar(sprout::exp(x.real()), x.imag()); + } + template + inline SPROUT_CONSTEXPR sprout::complex log(sprout::complex const& x) { + return sprout::complex(sprout::log(sprout::abs(x)), sprout::arg(x)); + } + template + inline SPROUT_CONSTEXPR sprout::complex log10(sprout::complex const& x) { + return sprout::log(x) / sprout::log(T(10)); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex pow_impl(sprout::complex const& t, T const& y) { + return sprout::polar(sprout::exp(y * t.real()), y * t.imag()); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex pow(sprout::complex const& x, T const& y) { + return x == T() ? T() + : x.imag() == T() && x.real() > T() ? sprout::pow(x.real(), y) + : sprout::detail::pow_impl(sprout::log(x), y) + ; + } + template + inline SPROUT_CONSTEXPR sprout::complex pow(sprout::complex const& x, sprout::complex const& y) { + return x == T() ? T() + : sprout::exp(y * sprout::log(x)) + ; + } + template + inline SPROUT_CONSTEXPR sprout::complex pow(T const& x, sprout::complex const& y) { + return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * sprout::log(x)) + : sprout::pow(sprout::complex(x), y) + ; + } + template + inline SPROUT_CONSTEXPR sprout::complex sin(sprout::complex const& x) { + return sprout::complex( + sprout::sin(x.real()) * sprout::cosh(x.imag()), + sprout::cos(x.real()) * sprout::sinh(x.imag()) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex sinh(sprout::complex const& x) { + return sprout::complex( + sprout::sinh(x.real()) * sprout::cos(x.imag()), + sprout::cosh(x.real()) * sprout::sin(x.imag()) + ); + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex sqrt_impl_1(sprout::complex const& x, T const& t) { + return sprout::complex(t, x.imag() < T() ? -t : t); + } + template + inline SPROUT_CONSTEXPR sprout::complex sqrt_impl_2_1(sprout::complex const& x, T const& t, T const& u) { + return x.real() > T() ? sprout::complex(u, x.imag() / t) + : sprout::complex(sprout::abs(x.imag()) / t, x.imag() < T() ? -u : u) + ; + } + template + inline SPROUT_CONSTEXPR sprout::complex sqrt_impl_2(sprout::complex const& x, T const& t) { + return sprout::detail::sqrt_impl_2_1(x, t, t / 2); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex sqrt(sprout::complex const& x) { + return x.real() == T() ? sprout::detail::sqrt_impl_1(x, sprout::sqrt(abs(x.imag()) / 2)) + : sprout::detail::sqrt_impl_2(x, sprout::sqrt(2 * (sprout::abs(x) + sprout::abs(x.real())))) + ; + } + template + inline SPROUT_CONSTEXPR sprout::complex tan(sprout::complex const& x) { + return sprout::sin(x) / sprout::cos(x); + } + template + inline SPROUT_CONSTEXPR sprout::complex tanh(sprout::complex const& x) { + return sprout::sinh(x) / sprout::cosh(x); + } + + template + inline SPROUT_CONSTEXPR sprout::complex ceil(sprout::complex const& x) { + return sprout::complex(sprout::ceil(x.real()), sprout::ceil(x.imag())); + } + template + inline SPROUT_CONSTEXPR sprout::complex floor(sprout::complex const& x) { + return sprout::complex(sprout::floor(x.real()), sprout::floor(x.imag())); + } + template + inline SPROUT_CONSTEXPR sprout::complex trunc(sprout::complex const& x) { + return sprout::complex(sprout::trunc(x.real()), sprout::trunc(x.imag())); + } + template + inline SPROUT_CONSTEXPR sprout::complex round(sprout::complex const& x) { + return sprout::complex(sprout::round(x.real()), sprout::round(x.imag())); + } +} // namespace sprout #endif // #ifndef SPROUT_COMPLEX_HPP diff --git a/sprout/cstring/memchr.hpp b/sprout/cstring/memchr.hpp index a888aa73..1abff2d8 100644 --- a/sprout/cstring/memchr.hpp +++ b/sprout/cstring/memchr.hpp @@ -12,7 +12,7 @@ namespace sprout { return !n ? 0 : *s == c ? s : sprout::detail::memchr_impl(s + 1, c, n - 1) - ; + ; } } // namespace detail diff --git a/sprout/darkroom/objects.hpp b/sprout/darkroom/objects.hpp index 0695a4d5..0b68c325 100644 --- a/sprout/darkroom/objects.hpp +++ b/sprout/darkroom/objects.hpp @@ -5,6 +5,5 @@ #include #include #include -#include #endif // #ifndef SPROUT_DARKROOM_OBJECTS_HPP diff --git a/sprout/darkroom/objects/polygon/triangle.hpp b/sprout/darkroom/objects/polygon/triangle.hpp index 252aad3b..30645add 100644 --- a/sprout/darkroom/objects/polygon/triangle.hpp +++ b/sprout/darkroom/objects/polygon/triangle.hpp @@ -69,7 +69,7 @@ namespace sprout { : position_type(0, 0, 0) , hit_side > 0 ? normal_ : sprout::darkroom::coords::negate(normal_), - sprout::darkroom::materials::calc_material(mat_, unit_type(0), unit_type(0)) // ! + sprout::darkroom::materials::calc_material(mat_, unit_type(0), unit_type(0)) // ??? ); } template @@ -132,7 +132,7 @@ namespace sprout { sprout::darkroom::coords::scale(sprout::darkroom::rays::direction(ray), t) ), hit_side, - // !!! + // ??? // hit_side > 0 && t >= 0 t >= 0 ); diff --git a/sprout/functional/hash/hash.hpp b/sprout/functional/hash/hash.hpp index 8645adbb..446f4702 100644 --- a/sprout/functional/hash/hash.hpp +++ b/sprout/functional/hash/hash.hpp @@ -10,76 +10,27 @@ #include namespace sprout { - namespace hash_detail { - struct enable_hash_value { - public: - typedef std::size_t type; - }; - - template - struct basic_numbers {}; - template - struct basic_numbers< - T, - typename std::enable_if< - (std::is_integral::value && sizeof(T) <= sizeof(std::size_t)) - >::type - > - : public sprout::hash_detail::enable_hash_value - {}; - - template - struct long_numbers {}; - template - struct long_numbers< - T, - typename std::enable_if< - (std::is_integral::value && std::is_signed::value && sizeof(T) > sizeof(std::size_t)) - >::type - > - : public sprout::hash_detail::enable_hash_value - {}; - - template - struct ulong_numbers {}; - template - struct ulong_numbers< - T, - typename std::enable_if< - (std::is_integral::value && std::is_unsigned::value && sizeof(T) > sizeof(std::size_t)) - >::type - > - : public sprout::hash_detail::enable_hash_value - {}; - - template - struct float_numbers {}; - template - struct float_numbers< - T, - typename std::enable_if< - (std::is_floating_point::value) - >::type - > - : public sprout::hash_detail::enable_hash_value - {}; - } // namespace hash_detail - // // hash_value // - template - inline SPROUT_CONSTEXPR typename sprout::hash_detail::basic_numbers::type - hash_value(T); - template - inline SPROUT_CONSTEXPR typename sprout::hash_detail::long_numbers::type - hash_value(T); - template - inline SPROUT_CONSTEXPR typename sprout::hash_detail::ulong_numbers::type - hash_value(T); -// template -// inline SPROUT_CONSTEXPR typename sprout::hash_detail::float_numbers::type -// hash_value(T); + inline SPROUT_CONSTEXPR std::size_t hash_value(bool v); + inline SPROUT_CONSTEXPR std::size_t hash_value(char v); + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned char v); + inline SPROUT_CONSTEXPR std::size_t hash_value(signed char v); + inline SPROUT_CONSTEXPR std::size_t hash_value(char16_t v); + inline SPROUT_CONSTEXPR std::size_t hash_value(char32_t v); + inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v); + inline SPROUT_CONSTEXPR std::size_t hash_value(short v); + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned short v); + inline SPROUT_CONSTEXPR std::size_t hash_value(int v); + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned int v); + inline SPROUT_CONSTEXPR std::size_t hash_value(long v); + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long v); + inline SPROUT_CONSTEXPR std::size_t hash_value(long long v); + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long long v); + //inline SPROUT_CONSTEXPR std::size_t hash_value(float v); + //inline SPROUT_CONSTEXPR std::size_t hash_value(double v); + //inline SPROUT_CONSTEXPR std::size_t hash_value(long double v); template< typename T, typename sprout::enabler_if::type>::value>::type @@ -153,26 +104,51 @@ namespace sprout { // // hash_value // - template - inline SPROUT_CONSTEXPR typename sprout::hash_detail::basic_numbers::type - hash_value(T v) { + inline SPROUT_CONSTEXPR std::size_t hash_value(bool v) { return static_cast(v); } - template - inline SPROUT_CONSTEXPR typename sprout::hash_detail::long_numbers::type - hash_value(T v) { + inline SPROUT_CONSTEXPR std::size_t hash_value(char v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned char v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(signed char v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(char16_t v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(char32_t v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(short v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned short v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(int v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned int v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(long v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long v) { + return static_cast(v); + } + inline SPROUT_CONSTEXPR std::size_t hash_value(long long v) { return sprout::hash_detail::hash_value_signed(v); } - template - inline SPROUT_CONSTEXPR typename sprout::hash_detail::ulong_numbers::type - hash_value(T v) { + inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long long v) { return sprout::hash_detail::hash_value_unsigned(v); } -// template -// inline SPROUT_CONSTEXPR typename sprout::hash_detail::float_numbers::type -// hash_value(T v) { -// return sprout::hash_detail::hash_value_float(v); -// } template< typename T, typename sprout::enabler_if::type>::value>::type = sprout::enabler diff --git a/sprout/generator.hpp b/sprout/generator.hpp new file mode 100644 index 00000000..d13c995d --- /dev/null +++ b/sprout/generator.hpp @@ -0,0 +1,6 @@ +#ifndef SPROUT_GENERATOR_HPP +#define SPROUT_GENERATOR_HPP + +#include + +#endif // #ifndef SPROUT_GENERATOR_HPP diff --git a/sprout/generator/functions.hpp b/sprout/generator/functions.hpp new file mode 100644 index 00000000..e06143d3 --- /dev/null +++ b/sprout/generator/functions.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_GENERATOR_FUNCTIONS_HPP +#define SPROUT_GENERATOR_FUNCTIONS_HPP + +#include +#include + +#endif // #ifndef SPROUT_GENERATOR_FUNCTIONS_HPP diff --git a/sprout/generator/generated_value.hpp b/sprout/generator/generated_value.hpp new file mode 100644 index 00000000..cfb82086 --- /dev/null +++ b/sprout/generator/generated_value.hpp @@ -0,0 +1,209 @@ +#ifndef SPROUT_GENERATOR_GENERATED_VALUE_HPP +#define SPROUT_GENERATOR_GENERATED_VALUE_HPP + +#include +#include +#include +#include +#include + +namespace sprout_generator_detail { + struct not_found_adl_generated_value {}; + + sprout_generator_detail::not_found_adl_generated_value generated_value(...); + + template + struct has_mem_generated_value_test { + public: + template< + typename U = T, + typename = decltype(std::declval().generated_value()) + > + static std::true_type test(int); + static std::false_type test(...); + }; + template + struct has_mem_generated_value + : public decltype(sprout_generator_detail::has_mem_generated_value_test::test(0)) + {}; + + template + struct has_adl_generated_value_test { + public: + template< + typename U = T, + typename sprout::enabler_if< + !std::is_same())), sprout_generator_detail::not_found_adl_generated_value>::value + >::type = sprout::enabler + > + static std::true_type test(int); + static std::false_type test(...); + }; + template + struct has_adl_generated_value + : public decltype(sprout_generator_detail::has_adl_generated_value_test::test(0)) + {}; + + template + struct has_tuple_get_generated_value_test { + public: + template< + typename U = T, + typename = decltype(sprout::tuples::get<0>(std::declval())) + > + static std::true_type test(int); + static std::false_type test(...); + }; + template + struct has_tuple_get_generated_value + : public decltype(sprout_generator_detail::has_tuple_get_generated_value_test::test(0)) + {}; + + template + struct select_mem_generated_value; + template + struct select_mem_generated_value< + T, + typename std::enable_if::value>::type + > + : public std::true_type + {}; + template + struct select_mem_generated_value< + T, + typename std::enable_if::value>::type + > + : public std::false_type + {}; + + template + struct select_adl_generated_value; + template + struct select_adl_generated_value< + T, + typename std::enable_if< + sprout_generator_detail::has_adl_generated_value::value + && !sprout_generator_detail::has_mem_generated_value::value + >::type + > + : public std::true_type + {}; + template + struct select_adl_generated_value< + T, + typename std::enable_if::value + && !sprout_generator_detail::has_mem_generated_value::value + )>::type + > + : public std::false_type + {}; + + template + struct select_tuple_get_generated_value; + template + struct select_tuple_get_generated_value< + T, + typename std::enable_if< + sprout_generator_detail::has_tuple_get_generated_value::value + && !sprout_generator_detail::has_mem_generated_value::value + && !sprout_generator_detail::has_adl_generated_value::value + >::type + > + : public std::true_type + {}; + template + struct select_tuple_get_generated_value< + T, + typename std::enable_if::value + && !sprout_generator_detail::has_mem_generated_value::value + && !sprout_generator_detail::has_adl_generated_value::value + )>::type + > + : public std::false_type + {}; + + template + struct noexcept_generated_value; + template + struct noexcept_generated_value::value>::type> + : public std::integral_constant().generated_value(), false)> + {}; + template + struct noexcept_generated_value::value>::type> + : public std::integral_constant()), false)> + {}; + template + struct noexcept_generated_value::value>::type> + : public std::integral_constant(std::declval()), false)> + {}; + + template + struct generated_value_result; + template + struct generated_value_result::value>::type> { + public: + typedef decltype(std::declval().generated_value()) type; + }; + template + struct generated_value_result::value>::type> { + public: + typedef decltype(generated_value(std::declval())) type; + }; + template + struct generated_value_result::value>::type> { + public: + typedef decltype(sprout::tuples::get<0>(std::declval())) type; + }; + + template< + typename T, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result::type + generated_value_impl(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value::value)) + { + return sprout::forward(t).generated_value(); + } + template< + typename T, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result::type + generated_value_impl(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value::value)) + { + return generated_value(sprout::forward(t)); + } + template< + typename T, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result::type + generated_value_impl(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value::value)) + { + return sprout::tuples::get<0>(sprout::forward(t)); + } +} // namespace sprout_generator_detail + +namespace sprout { + namespace generators { + // + // generated_value + // + template + inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result::type + generated_value(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value::value)) + { + return sprout_generator_detail::generated_value_impl(sprout::forward(t)); + } + } // namespace generators + + using sprout::generators::generated_value; +} // namespace sprout + +#endif // #ifndef SPROUT_GENERATOR_GENERATED_VALUE_HPP diff --git a/sprout/generator/next_generator.hpp b/sprout/generator/next_generator.hpp new file mode 100644 index 00000000..fcefd395 --- /dev/null +++ b/sprout/generator/next_generator.hpp @@ -0,0 +1,209 @@ +#ifndef SPROUT_GENERATOR_NEXT_GENERATOR_HPP +#define SPROUT_GENERATOR_NEXT_GENERATOR_HPP + +#include +#include +#include +#include +#include + +namespace sprout_generator_detail { + struct not_found_adl_next_generator {}; + + sprout_generator_detail::not_found_adl_next_generator next_generator(...); + + template + struct has_mem_next_generator_test { + public: + template< + typename U = T, + typename = decltype(std::declval().next_generator()) + > + static std::true_type test(int); + static std::false_type test(...); + }; + template + struct has_mem_next_generator + : public decltype(sprout_generator_detail::has_mem_next_generator_test::test(0)) + {}; + + template + struct has_adl_next_generator_test { + public: + template< + typename U = T, + typename sprout::enabler_if< + !std::is_same())), sprout_generator_detail::not_found_adl_next_generator>::value + >::type = sprout::enabler + > + static std::true_type test(int); + static std::false_type test(...); + }; + template + struct has_adl_next_generator + : public decltype(sprout_generator_detail::has_adl_next_generator_test::test(0)) + {}; + + template + struct has_tuple_get_next_generator_test { + public: + template< + typename U = T, + typename = decltype(sprout::tuples::get<1>(std::declval())) + > + static std::true_type test(int); + static std::false_type test(...); + }; + template + struct has_tuple_get_next_generator + : public decltype(sprout_generator_detail::has_tuple_get_next_generator_test::test(0)) + {}; + + template + struct select_mem_next_generator; + template + struct select_mem_next_generator< + T, + typename std::enable_if::value>::type + > + : public std::true_type + {}; + template + struct select_mem_next_generator< + T, + typename std::enable_if::value>::type + > + : public std::false_type + {}; + + template + struct select_adl_next_generator; + template + struct select_adl_next_generator< + T, + typename std::enable_if< + sprout_generator_detail::has_adl_next_generator::value + && !sprout_generator_detail::has_mem_next_generator::value + >::type + > + : public std::true_type + {}; + template + struct select_adl_next_generator< + T, + typename std::enable_if::value + && !sprout_generator_detail::has_mem_next_generator::value + )>::type + > + : public std::false_type + {}; + + template + struct select_tuple_get_next_generator; + template + struct select_tuple_get_next_generator< + T, + typename std::enable_if< + sprout_generator_detail::has_tuple_get_next_generator::value + && !sprout_generator_detail::has_mem_next_generator::value + && !sprout_generator_detail::has_adl_next_generator::value + >::type + > + : public std::true_type + {}; + template + struct select_tuple_get_next_generator< + T, + typename std::enable_if::value + && !sprout_generator_detail::has_mem_next_generator::value + && !sprout_generator_detail::has_adl_next_generator::value + )>::type + > + : public std::false_type + {}; + + template + struct noexcept_next_generator; + template + struct noexcept_next_generator::value>::type> + : public std::integral_constant().next_generator(), false)> + {}; + template + struct noexcept_next_generator::value>::type> + : public std::integral_constant()), false)> + {}; + template + struct noexcept_next_generator::value>::type> + : public std::integral_constant(std::declval()), false)> + {}; + + template + struct next_generator_result; + template + struct next_generator_result::value>::type> { + public: + typedef decltype(std::declval().next_generator()) type; + }; + template + struct next_generator_result::value>::type> { + public: + typedef decltype(next_generator(std::declval())) type; + }; + template + struct next_generator_result::value>::type> { + public: + typedef decltype(sprout::tuples::get<1>(std::declval())) type; + }; + + template< + typename T, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result::type + next_generator_impl(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator::value)) + { + return sprout::forward(t).next_generator(); + } + template< + typename T, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result::type + next_generator_impl(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator::value)) + { + return next_generator(sprout::forward(t)); + } + template< + typename T, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result::type + next_generator_impl(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator::value)) + { + return sprout::tuples::get<1>(sprout::forward(t)); + } +} // namespace sprout_generator_detail + +namespace sprout { + namespace generators { + // + // next_generator + // + template + inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result::type + next_generator(T&& t) + SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator::value)) + { + return sprout_generator_detail::next_generator_impl(sprout::forward(t)); + } + } // namespace generators + + using sprout::generators::next_generator; +} // namespace sprout + +#endif // #ifndef SPROUT_GENERATOR_NEXT_GENERATOR_HPP diff --git a/sprout/iterator.hpp b/sprout/iterator.hpp index c21a8e18..2505b216 100644 --- a/sprout/iterator.hpp +++ b/sprout/iterator.hpp @@ -4,5 +4,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_ITERATOR_HPP diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp new file mode 100644 index 00000000..8cf57b4d --- /dev/null +++ b/sprout/iterator/adaptor.hpp @@ -0,0 +1,11 @@ +#ifndef SPROUT_ITERATOR_ADAPTOR_HPP +#define SPROUT_ITERATOR_ADAPTOR_HPP + +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_ITERATOR_ADAPTOR_HPP diff --git a/sprout/iterator/filter_iterator.hpp b/sprout/iterator/filter_iterator.hpp new file mode 100644 index 00000000..b801261f --- /dev/null +++ b/sprout/iterator/filter_iterator.hpp @@ -0,0 +1,202 @@ +#ifndef SPROUT_ITERATOR_FILTER_ITERATOR_HPP +#define SPROUT_ITERATOR_FILTER_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // filter_iterator + // + template + class filter_iterator + : public std::iterator< + typename std::conditional< + std::is_convertible::iterator_category, std::random_access_iterator_tag>::value, + std::bidirectional_iterator_tag, + typename std::iterator_traits::iterator_category + >::type, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference + > + { + public: + typedef Predicate predicate_type; + typedef Iterator iterator_type; + typedef typename std::conditional< + std::is_convertible::iterator_category, std::random_access_iterator_tag>::value, + std::bidirectional_iterator_tag, + typename std::iterator_traits::iterator_category + >::type iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + private: + struct private_constructor_tag {}; + private: + static SPROUT_CONSTEXPR iterator_type find_next(iterator_type first, iterator_type last, predicate_type pred) { + return sprout::find_if(first, last, pred); + } + static SPROUT_CONSTEXPR iterator_type find_prev(iterator_type first, predicate_type pred) { + return pred(*first) != false ? first + : find_prev(sprout::prev(first), pred) + ; + } + protected: + iterator_type current; + iterator_type last; + predicate_type pred; + private: + iterator_type satisfy_predicate() { + while (current != last && !pred(current)) { + ++current; + } + } + iterator_type satisfy_predicate_backward() { + while (!pred(current)) { + --current; + } + } + SPROUT_CONSTEXPR filter_iterator(predicate_type pred, iterator_type it, iterator_type last, private_constructor_tag) + : current(it) + , last(last) + , pred(pred) + {} + public: + filter_iterator() = default; + filter_iterator(filter_iterator const&) = default; + SPROUT_CONSTEXPR filter_iterator(predicate_type pred, iterator_type it, iterator_type last = iterator_type()) + : current(find_next(it, last, pred)) + , last(last) + , pred(pred) + {} + template + SPROUT_CONSTEXPR filter_iterator(filter_iterator const& it) + : current(it.current) + , last(it.last) + , pred(it.pred) + {} + template + filter_iterator& operator=(filter_iterator const& it) { + filter_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR iterator_type end() const { + return last; + } + SPROUT_CONSTEXPR predicate_type predicate() const { + return pred; + } + SPROUT_CONSTEXPR reference operator*() const { + return *current; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*current; + } + + filter_iterator& operator++() { + ++current; + satisfy_predicate(); + return *this; + } + filter_iterator operator++(int) { + filter_iterator result(*this); + ++current; + satisfy_predicate(); + return result; + } + filter_iterator& operator--() { + --current; + satisfy_predicate_backward(); + return *this; + } + filter_iterator operator--(int) { + filter_iterator temp(*this); + --current; + satisfy_predicate_backward(); + return temp; + } + SPROUT_CONSTEXPR filter_iterator next() const { + return filter_iterator(pred, find_next(sprout::next(current)), last, private_constructor_tag()); + } + SPROUT_CONSTEXPR filter_iterator prev() const { + return filter_iterator(pred, find_prev(sprout::prev(current)), last, private_constructor_tag()); + } + void swap(filter_iterator& other) { + using std::swap; + swap(current, other.current); + swap(last, other.last); + swap(pred, other.pred); + } + }; + + template + inline SPROUT_CONSTEXPR bool operator==( + sprout::filter_iterator const& lhs, + sprout::filter_iterator const& rhs + ) + { + return lhs.base() == rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool operator!=( + sprout::filter_iterator const& lhs, + sprout::filter_iterator const& rhs + ) + { + return !(lhs == rhs); + } + + // + // make_filter_iterator + // + template + inline SPROUT_CONSTEXPR sprout::filter_iterator + make_filter_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) { + return sprout::filter_iterator(pred, it, last); + } + + // + // swap + // + template + inline void swap(sprout::filter_iterator& lhs, sprout::filter_iterator& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { + lhs.swap(rhs); + } + + // + // next + // + template + inline SPROUT_CONSTEXPR sprout::filter_iterator next( + sprout::filter_iterator const& it + ) + { + return it.next(); + } + + // + // prev + // + template + inline SPROUT_CONSTEXPR sprout::filter_iterator prev( + sprout::filter_iterator const& it + ) + { + return it.prev(); + } +} // namespace sprout + +#endif // SPROUT_ITERATOR_FILTER_ITERATOR_HPP diff --git a/sprout/iterator/next.hpp b/sprout/iterator/next.hpp index 1591b408..5f42f8da 100644 --- a/sprout/iterator/next.hpp +++ b/sprout/iterator/next.hpp @@ -25,8 +25,7 @@ namespace sprout { void* ) { - using std::next; - return next(sprout::forward(it)); + return std::next(sprout::forward(it)); } template @@ -48,8 +47,7 @@ namespace sprout { void* ) { - using std::next; - return next(sprout::forward(it), n); + return std::next(sprout::forward(it), n); } } // namespace detail // diff --git a/sprout/iterator/prev.hpp b/sprout/iterator/prev.hpp index 488c106a..f371045d 100644 --- a/sprout/iterator/prev.hpp +++ b/sprout/iterator/prev.hpp @@ -25,8 +25,7 @@ namespace sprout { void* ) { - using std::prev; - return prev(sprout::forward(it)); + return std::prev(sprout::forward(it)); } template @@ -48,8 +47,7 @@ namespace sprout { void* ) { - using std::prev; - return prev(sprout::forward(it), n); + return std::prev(sprout::forward(it), n); } } // namespace detail // diff --git a/sprout/iterator/reverse_iterator.hpp b/sprout/iterator/reverse_iterator.hpp index a8518f09..0b95a76a 100644 --- a/sprout/iterator/reverse_iterator.hpp +++ b/sprout/iterator/reverse_iterator.hpp @@ -182,6 +182,15 @@ namespace sprout { return it + n; } + // + // make_reverse_iterator + // + template + inline SPROUT_CONSTEXPR sprout::reverse_iterator + make_reverse_iterator(Iterator it) { + return sprout::reverse_iterator(it); + } + // // swap // diff --git a/sprout/iterator/wave.hpp b/sprout/iterator/wave.hpp new file mode 100644 index 00000000..923ffcbd --- /dev/null +++ b/sprout/iterator/wave.hpp @@ -0,0 +1,10 @@ +#ifndef SPROUT_ITERATOR_WAVE_HPP +#define SPROUT_ITERATOR_WAVE_HPP + +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_ITERATOR_WAVE_HPP diff --git a/sprout/pit/hash.hpp b/sprout/pit/hash.hpp index 5a35f759..fd78832a 100644 --- a/sprout/pit/hash.hpp +++ b/sprout/pit/hash.hpp @@ -9,7 +9,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR std::size_t hash_value(sprout::pit const& v) { - return sprout::hash_range(v.begin(), v.end()); + return sprout::to_hash(v.elem); } } // namespace sprout diff --git a/sprout/pit/pit.hpp b/sprout/pit/pit.hpp index 3dddbc4d..ce650c33 100644 --- a/sprout/pit/pit.hpp +++ b/sprout/pit/pit.hpp @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include namespace sprout { diff --git a/sprout/range/adaptor.hpp b/sprout/range/adaptor.hpp index 3433d306..743019f7 100644 --- a/sprout/range/adaptor.hpp +++ b/sprout/range/adaptor.hpp @@ -3,7 +3,11 @@ #include #include +#include #include +#include +#include +#include #include #include #include diff --git a/sprout/range/adaptor/filtered.hpp b/sprout/range/adaptor/filtered.hpp new file mode 100644 index 00000000..fb9c9a2a --- /dev/null +++ b/sprout/range/adaptor/filtered.hpp @@ -0,0 +1,139 @@ +#ifndef SPROUT_RANGE_ADAPTOR_FILTERED_HPP +#define SPROUT_RANGE_ADAPTOR_FILTERED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // filtered_range + // + template + class filtered_range + : public sprout::range::range_container< + sprout::filter_iterator< + Predicate, + typename sprout::container_traits::iterator + > + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Predicate predicate_type; + typedef Range range_type; + typedef sprout::range::range_container< + sprout::filter_iterator< + Predicate, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + public: + filtered_range() = default; + filtered_range(filtered_range const&) = default; + SPROUT_CONSTEXPR filtered_range(predicate_type pred, range_type& range) + : base_type( + iterator(pred, sprout::begin(range), sprout::end(range)), + iterator(pred, sprout::end(range), sprout::end(range)) + ) + {} + }; + + // + // filter_holder + // + template + class filter_holder { + public: + typedef Predicate predicate_type; + private: + predicate_type pred_; + public: + filter_holder() = default; + filter_holder(filter_holder const&) = default; + SPROUT_CONSTEXPR filter_holder(predicate_type pred) + : pred_(pred) + {} + SPROUT_CONSTEXPR predicate_type predicate() const { + return pred_; + } + }; + + // + // filtered_forwarder + // + class filtered_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::filter_holder + operator()(Predicate pred) { + return sprout::adaptors::filter_holder(pred); + } + }; + + // + // filtered + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::filtered_forwarder filtered{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::filtered_range< + Predicate, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::filter_holder const& rhs) { + return sprout::adaptors::filtered_range< + Predicate, + typename std::remove_reference::type>::type + >( + rhs.predicate(), + sprout::lvalue_forward(lhs) + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_FILTERED_HPP diff --git a/sprout/range/adaptor/replaced.hpp b/sprout/range/adaptor/replaced.hpp new file mode 100644 index 00000000..4faca60b --- /dev/null +++ b/sprout/range/adaptor/replaced.hpp @@ -0,0 +1,160 @@ +#ifndef SPROUT_RANGE_ADAPTOR_REPLACED_HPP +#define SPROUT_RANGE_ADAPTOR_REPLACED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + namespace detail { + template + class replace_value { + public: + typedef T const& result_type; + typedef T const& first_argument_type; + private: + T old_; + T new_; + public: + SPROUT_CONSTEXPR replace_value(T const& old_value, T const& new_value) + : old_(old_value) + , new_(new_value) + {} + T const& operator()(T const& value) const { + return (value == old_) ? new_ : value; + } + }; + } // namespace detail + // + // replaced_range + // + template + class replaced_range + : public sprout::range::range_container< + sprout::transform_iterator< + sprout::adaptors::detail::replace_value::value_type>, + typename sprout::container_traits::iterator + > + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::transform_iterator< + sprout::adaptors::detail::replace_value::value_type>, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + public: + replaced_range() = default; + replaced_range(replaced_range const&) = default; + explicit SPROUT_CONSTEXPR replaced_range(range_type& range, value_type const& old_value, value_type const& new_value) + : base_type( + iterator(sprout::begin(range), typename iterator::functor_type(old_value, new_value)), + iterator(sprout::end(range), typename iterator::functor_type(old_value, new_value)) + ) + {} + }; + + // + // replace_holder + // + template + class replace_holder { + public: + typedef T value_type; + private: + value_type old_; + value_type new_; + public: + SPROUT_CONSTEXPR replace_holder(value_type const& old_value, value_type const& new_value) + : old_(old_value) + , new_(new_value) + {} + SPROUT_CONSTEXPR value_type old_value() const { + return old_; + } + SPROUT_CONSTEXPR value_type new_value() const { + return new_; + } + }; + + // + // replaced_forwarder + // + class replaced_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::replace_holder + operator()(T const& old_value, T const& new_value) { + return sprout::adaptors::replace_holder(old_value, new_value); + } + }; + + // + // replaced + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::replaced_forwarder replaced{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::replaced_range< + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::replace_holder const& rhs) { + return sprout::adaptors::replaced_range< + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs), + rhs.old_value(), + rhs.new_value() + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_REPLACED_HPP diff --git a/sprout/range/adaptor/replaced_if.hpp b/sprout/range/adaptor/replaced_if.hpp new file mode 100644 index 00000000..1ae8ac95 --- /dev/null +++ b/sprout/range/adaptor/replaced_if.hpp @@ -0,0 +1,164 @@ +#ifndef SPROUT_RANGE_ADAPTOR_REPLACED_IF_HPP +#define SPROUT_RANGE_ADAPTOR_REPLACED_IF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + namespace detail { + template + class replace_value_if { + public: + typedef Predicate predicate_type; + typedef T const& result_type; + typedef T const& first_argument_type; + private: + Predicate pred_; + T new_; + public: + SPROUT_CONSTEXPR replace_value_if(Predicate pred, T const& new_value) + : pred_(pred) + , new_(new_value) + {} + T const& operator()(T const& value) const { + return pred(value) ? new_ : value; + } + }; + } // namespace detail + // + // replaced_if_range + // + template + class replaced_if_range + : public sprout::range::range_container< + sprout::transform_iterator< + sprout::adaptors::detail::replace_value_if::value_type>, + typename sprout::container_traits::iterator + > + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::transform_iterator< + sprout::adaptors::detail::replace_value_if::value_type>, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + public: + replaced_if_range() = default; + replaced_if_range(replaced_if_range const&) = default; + explicit SPROUT_CONSTEXPR replaced_if_range(range_type& range, Predicate pred, value_type const& new_value) + : base_type( + iterator(sprout::begin(range), typename iterator::functor_type(pred, new_value)), + iterator(sprout::end(range), typename iterator::functor_type(pred, new_value)) + ) + {} + }; + + // + // replace_if_holder + // + template + class replace_if_holder { + public: + typedef Predicate predicate_type; + typedef T value_type; + private: + predicate_type pred_; + value_type new_; + public: + SPROUT_CONSTEXPR replace_if_holder(predicate_type pred, value_type const& new_value) + : pred_(pred) + , new_(new_value) + {} + SPROUT_CONSTEXPR predicate_type predicate() const { + return pred_; + } + SPROUT_CONSTEXPR value_type new_value() const { + return new_; + } + }; + + // + // replaced_if_forwarder + // + class replaced_if_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::replace_if_holder + operator()(Predicate pred, T const& new_value) { + return sprout::adaptors::replace_if_holder(pred, new_value); + } + }; + + // + // replaced_if + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::replaced_if_forwarder replaced_if{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::replaced_if_range< + Predicate, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::replace_if_holder const& rhs) { + return sprout::adaptors::replaced_if_range< + Predicate, + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs), + rhs.predicate(), + rhs.new_value() + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_REPLACED_IF_HPP diff --git a/sprout/range/adaptor/reversed.hpp b/sprout/range/adaptor/reversed.hpp new file mode 100644 index 00000000..c0325c93 --- /dev/null +++ b/sprout/range/adaptor/reversed.hpp @@ -0,0 +1,106 @@ +#ifndef SPROUT_RANGE_ADAPTOR_REVERSED_HPP +#define SPROUT_RANGE_ADAPTOR_REVERSED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // reversed_range + // + template + class reversed_range + : public sprout::range::range_container< + sprout::reverse_iterator< + typename sprout::container_traits::iterator + > + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::reverse_iterator< + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + public: + reversed_range() = default; + reversed_range(reversed_range const&) = default; + explicit SPROUT_CONSTEXPR reversed_range(range_type& range) + : base_type( + iterator(sprout::end(range)), + iterator(sprout::begin(range)) + ) + {} + }; + + // + // reversed_forwarder + // + class reversed_forwarder {}; + + // + // reversed + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::reversed_forwarder reversed{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::reversed_range< + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::reversed_forwarder) { + return sprout::adaptors::reversed_range< + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs) + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_REVERSED_HPP diff --git a/sprout/rational.hpp b/sprout/rational.hpp index 8f0794db..df1da97c 100644 --- a/sprout/rational.hpp +++ b/sprout/rational.hpp @@ -1,14 +1,725 @@ #ifndef SPROUT_RATIONAL_HPP #define SPROUT_RATIONAL_HPP +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include + +namespace sprout { + // + // bad_rational + // + class bad_rational + : public std::domain_error + { + public: + explicit bad_rational() + : std::domain_error("bad rational: zero denominator") + {} + }; + + template + class rational; + + namespace detail { + struct rational_private_constructor_tag {}; + + template + inline SPROUT_CONSTEXPR sprout::rational make_rational( + typename sprout::detail::call_traits::param_type n, + typename sprout::detail::call_traits::param_type d, + sprout::detail::rational_private_constructor_tag + ); + } // namespace detail + + namespace detail { + template + class rational_impl { + protected: + typedef IntType int_type; + typedef typename sprout::detail::call_traits::param_type param_type; + protected: + IntType num_; + IntType den_; + protected: + SPROUT_CONSTEXPR rational_impl() + : num_(0) + , den_(1) + {} + rational_impl(rational_impl const&) = default; + SPROUT_CONSTEXPR rational_impl(param_type n) + : num_(n) + , den_(1) + {} + SPROUT_CONSTEXPR rational_impl(param_type n, param_type d) + : num_(n) + , den_(d) + {} + SPROUT_CONSTEXPR rational_impl(param_type n, param_type d, param_type g) + : num_(n / g) + , den_(d / g) + {} + }; + } // namespace detail + + // + // rational + // + template + class rational + : private sprout::detail::rational_impl + { + static_assert(std::numeric_limits::is_specialized, "std::numeric_limits::is_specialized"); + public: + typedef IntType int_type; + typedef typename sprout::detail::call_traits::param_type param_type; + private: + struct private_constructor_tag {}; + typedef sprout::detail::rational_impl base_type; + private: + static SPROUT_CONSTEXPR IntType normalize_g_1(IntType den, IntType g) { + return den / g < 0 ? -g : g; + } + static SPROUT_CONSTEXPR IntType normalize_g(IntType num, IntType den) { + return den == 0 ? throw sprout::bad_rational() + : num == 0 ? den + : normalize_g_1(den, sprout::math::gcd(num, den)) + ; + } + private: + using base_type::num_; + using base_type::den_; + private: + SPROUT_CONSTEXPR rational(param_type n, param_type d, private_constructor_tag) + : base_type(n, d) + {} + public: + SPROUT_CONSTEXPR rational() + : base_type() + {} + rational(rational const&) = default; + SPROUT_CONSTEXPR rational(param_type n) + : base_type(n) + {} + SPROUT_CONSTEXPR rational(param_type n, param_type d) + : base_type(n, d, normalize_g(n, d)) + {} + + rational& operator=(rational const&) = default; + rational& operator=(param_type n) { + return assign(n, 1); + } + rational& assign(param_type n, param_type d) { + using std::swap; + rational temp(n, d); + swap(temp, *this); + return *this; + } + + SPROUT_CONSTEXPR IntType numerator() const { + return num_; + } + SPROUT_CONSTEXPR IntType denominator() const { + return den_; + } + + rational& operator+=(rational const& rhs) { + IntType g = sprout::math::gcd(den_, rhs.den_); + den_ /= g; + num_ = num_ * (rhs.den_ / g) + rhs.num_ * den_; + g = sprout::math::gcd(num_, g); + num_ /= g; + den_ *= rhs.den_ / g; + return *this; + } + rational& operator-=(rational const& rhs) { + IntType g = sprout::math::gcd(den_, rhs.den_); + den_ /= g; + num_ = num_ * (rhs.den_ / g) - rhs.num_ * den_; + g = sprout::math::gcd(num_, g); + num_ /= g; + den_ *= rhs.den_ / g; + return *this; + } + rational& operator*=(rational const& rhs) { + IntType gcd1 = sprout::math::gcd(num_, rhs.den_); + IntType gcd2 = sprout::math::gcd(rhs.num_, den_); + num_ =(num_ / gcd1) * (rhs.num_ / gcd2); + den_ =(den_ / gcd2) * (rhs.den_ / gcd1); + return *this; + } + rational& operator/=(rational const& rhs) { + if (rhs.num_ == IntType(0)) { + throw bad_rational(); + } + if (num_ == IntType(0)) { + return *this; + } + IntType gcd1 = sprout::math::gcd(num_, rhs.num_); + IntType gcd2 = sprout::math::gcd(rhs.den_, den_); + num_ =(num_ / gcd1) * (rhs.den_ / gcd2); + den_ =(den_ / gcd2) * (rhs.num_ / gcd1); + if (den_ < IntType(0)) { + num_ = -num_; + den_ = -den_; + } + return *this; + } + rational& operator+=(param_type rhs) { + return *this += rational(rhs); + } + rational& operator-=(param_type rhs) { + return *this -= rational(rhs); + } + rational& operator*=(param_type rhs) { + return *this *= rational(rhs); + } + rational& operator/=(param_type rhs) { + return *this /= rational(rhs); + } + + rational& operator++() { + num_ += den_; + return *this; + } + rational& operator--() { + num_ -= den_; + return *this; + } + rational operator++(int) { + rational result(*this); + ++*this; + return result; + } + rational operator--(int) { + rational result(*this); + --*this; + return result; + } + + SPROUT_CONSTEXPR bool operator!() const { + return !num_; + } + SPROUT_CONSTEXPR operator bool() const { + return num_ != 0; + } + + public: + friend sprout::rational sprout::detail::make_rational( + typename sprout::detail::call_traits::param_type n, + typename sprout::detail::call_traits::param_type d, + sprout::detail::rational_private_constructor_tag + ); + }; + + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::rational make_rational( + typename sprout::detail::call_traits::param_type n, + typename sprout::detail::call_traits::param_type d, + sprout::detail::rational_private_constructor_tag + ) + { + return sprout::rational( + n, d, + typename sprout::rational::private_constructor_tag() + ); + } + } // namespace detail + + // + // operator+ + // operator- + // + template + inline SPROUT_CONSTEXPR sprout::rational + operator+(rational const& r) { + return r; + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator-(rational const& r) { + return sprout::detail::make_rational( + -r.numerator(), r.denominator(), + sprout::detail::rational_private_constructor_tag() + ); + } + + // + // operator+ + // operator- + // operator* + // operator/ + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::rational + rational_add_impl_3( + sprout::rational const& rhs, + IntType g, IntType den, IntType num + ) + { + return sprout::detail::make_rational( + num / g, den * (rhs.denominator() / g), + sprout::detail::rational_private_constructor_tag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_add_impl_2( + sprout::rational const& rhs, + IntType g, IntType den, IntType num + ) + { + return rational_add_impl_3( + rhs, + sprout::math::gcd(num, g), den, num + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_add_impl_1( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType g, IntType den + ) + { + return rational_add_impl_2( + rhs, + g, den, lhs.numerator() * (rhs.denominator() / g) + rhs.numerator() * den + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_add_impl( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType g + ) + { + return rational_add_impl_1( + lhs, rhs, + g, lhs.denominator() / g + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::rational + operator+(sprout::rational const& lhs, sprout::rational const& rhs) { + return sprout::detail::rational_add_impl( + lhs, rhs, + sprout::math::gcd(lhs.denominator(), rhs.denominator()) + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator+(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return lhs + sprout::rational(rhs); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator+(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return sprout::rational(lhs) + rhs; + } + + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::rational + rational_sub_impl_3( + sprout::rational const& rhs, + IntType g, IntType den, IntType num + ) + { + return sprout::detail::make_rational( + num / g, den * (rhs.denominator() / g), + sprout::detail::rational_private_constructor_tag() + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_sub_impl_2( + sprout::rational const& rhs, + IntType g, IntType den, IntType num + ) + { + return rational_sub_impl_3( + rhs, + sprout::math::gcd(num, g), den, num + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_sub_impl_1( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType g, IntType den + ) + { + return rational_sub_impl_2( + rhs, + g, den, lhs.numerator() * (rhs.denominator() / g) - rhs.numerator() * den + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_sub_impl( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType g + ) + { + return rational_sub_impl_1( + lhs, rhs, + g, lhs.denominator() / g + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::rational + operator-(sprout::rational const& lhs, sprout::rational const& rhs) { + return sprout::detail::rational_sub_impl( + lhs, rhs, + sprout::math::gcd(lhs.denominator(), rhs.denominator()) + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator-(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return lhs - sprout::rational(rhs); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator-(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return sprout::rational(lhs) - rhs; + } + + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::rational + rational_mul_impl( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType gcd1, IntType gcd2 + ) + { + return sprout::detail::make_rational( + (lhs.numerator() / gcd1) * (rhs.numerator() / gcd2), + (lhs.denominator() / gcd2) * (rhs.denominator() / gcd1), + sprout::detail::rational_private_constructor_tag() + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::rational + operator*(sprout::rational const& lhs, sprout::rational const& rhs) { + return sprout::detail::rational_mul_impl( + lhs, rhs, + sprout::math::gcd(lhs.numerator(), rhs.denominator()), + sprout::math::gcd(rhs.numerator(), lhs.denominator()) + ); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator*(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return lhs * sprout::rational(rhs); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator*(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return sprout::rational(lhs) * rhs; + } + + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::rational + rational_div_impl_1(IntType num, IntType den) { + return den < IntType(0) ? sprout::detail::make_rational( + -num, -den, + sprout::detail::rational_private_constructor_tag() + ) + : sprout::detail::make_rational( + num, den, + sprout::detail::rational_private_constructor_tag() + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::rational + rational_div_impl( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType gcd1, IntType gcd2 + ) + { + return sprout::detail::rational_div_impl_1( + (lhs.numerator() / gcd1) * (rhs.denominator() / gcd2), + (lhs.denominator() / gcd2) * (rhs.numerator() / gcd1) + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::rational + operator/(sprout::rational const& lhs, sprout::rational const& rhs) { + return rhs.numerator() == IntType(0) ? throw sprout::bad_rational() + : lhs.numerator() == IntType(0) ? lhs + : sprout::detail::rational_div_impl( + lhs, rhs, + sprout::math::gcd(lhs.numerator(), rhs.numerator()), + sprout::math::gcd(rhs.denominator(), lhs.denominator()) + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator/(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return lhs / sprout::rational(rhs); + } + template + inline SPROUT_CONSTEXPR sprout::rational + operator/(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return sprout::rational(lhs) / rhs; + } + + // + // operator== + // operator!= + // + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::rational const& lhs, sprout::rational const& rhs) { + return lhs.numerator() == rhs.numerator() && lhs.denominator() == rhs.denominator(); + } + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return lhs.denominator() == IntType(1) && lhs.numerator() == rhs; + } + template + inline SPROUT_CONSTEXPR bool + operator==(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return rhs == lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::rational const& lhs, sprout::rational const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return !(lhs == rhs); + } + + // + // operator< + // operator> + // operator<= + // operator>= + // + namespace detail { + template + inline SPROUT_CONSTEXPR bool + rational_less_impl_2( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType d1, IntType q1, IntType r1, + IntType d2, IntType q2, IntType r2, + unsigned reverse = 0 + ) + { + return q1 != q2 ? reverse ? q1 > q2 : q1 < q2 + : r1 == IntType(0) || r2 == IntType(0) + ? r1 == r2 ? false + : (r1 != IntType(0)) != static_cast(reverse ^ 1) + : sprout::detail::rational_less_impl_2( + lhs, rhs, + r1, d1 / r1, d1 % r1, + r2, d2 / r2, d2 % r2, + reverse ^ 1 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + rational_less_impl_1( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType d1, IntType q1, IntType r1, + IntType d2, IntType q2, IntType r2 + ) + { + return r2 < IntType(0) ? sprout::detail::rational_less_impl_1( + lhs, rhs, + d1, q1, r1, + d2, q2 - 1, r2 + d2 + ) + : sprout::detail::rational_less_impl_2( + lhs, rhs, + d1, q1, r1, + d2, q2, r2 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + rational_less_impl( + sprout::rational const& lhs, sprout::rational const& rhs, + IntType d1, IntType q1, IntType r1 + ) + { + return r1 < IntType(0) ? sprout::detail::rational_less_impl( + lhs, rhs, + d1, q1 - 1, r1 + d1 + ) + : sprout::detail::rational_less_impl_1( + lhs, rhs, + d1, q1, r1, + rhs.denominator(), rhs.numerator() / rhs.denominator(), rhs.numerator() % rhs.denominator() + ) + ; + } + + template + inline SPROUT_CONSTEXPR bool + rational_less_impl( + sprout::rational const& lhs, typename sprout::rational::param_type rhs, + IntType q, IntType r + ) + { + return r < IntType(0) ? sprout::detail::rational_less_impl( + lhs, rhs, + r + lhs.denominator(), q - 1 + ) + : q < rhs + ; + } + } // namespace detail + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::rational const& lhs, sprout::rational const& rhs) { + return sprout::detail::rational_less_impl( + lhs, rhs, + lhs.denominator(), lhs.numerator() / lhs.denominator(), lhs.numerator() % lhs.denominator() + ); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return sprout::detail::rational_less_impl( + lhs, rhs, + lhs.numerator() / lhs.denominator(), lhs.numerator() % lhs.denominator() + ); + } + template + inline SPROUT_CONSTEXPR bool + operator<(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return lhs != rhs && !(rhs < lhs); + } + + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::rational const& lhs, sprout::rational const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator>(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return rhs < lhs; + } + + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::rational const& lhs, sprout::rational const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<=(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return !(rhs < lhs); + } + + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::rational const& lhs, sprout::rational const& rhs) { + return !(lhs < rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::rational const& lhs, typename sprout::rational::param_type rhs) { + return !(lhs < rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(typename sprout::rational::param_type lhs, sprout::rational const& rhs) { + return !(lhs < rhs); + } + + // + // operator>> + // operator<< + // + template + inline std::basic_istream& + operator>>(std::basic_istream& lhs, sprout::rational& rhs) { + IntType n = IntType(0); + IntType d = IntType(1); + Elem c = 0; + sprout::detail::io::ios_flags_saver saver(lhs); + lhs >> n; + c = lhs.get(); + if (c != Elem('/')) { + lhs.clear(std::istream::badbit); + } + lhs >> std::noskipws; + lhs >> d; + if (lhs) { + rhs.assign(n, d); + } + return lhs; + } + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::rational const& rhs) { + return lhs << rhs.numerator() << Elem('/') << rhs.denominator(); + } + + // + // rational_cast + // + template + inline SPROUT_CONSTEXPR T + rational_cast(sprout::rational const& src) { + return static_cast(src.numerator()) / static_cast(src.denominator()); + } + + // + // abs + // + template + inline SPROUT_CONSTEXPR sprout::rational + abs(sprout::rational const& x) { + return x.numerator() >= IntType(0) ? x + : sprout::detail::make_rational( + -x.numerator(), x.denominator(), + sprout::detail::rational_private_constructor_tag() + ) + ; + } + +} // namespace sprout #endif // SPROUT_RATIONAL_HPP diff --git a/sprout/rational/arithmetic.hpp b/sprout/rational/arithmetic.hpp index 52dd830f..907dcc7e 100644 --- a/sprout/rational/arithmetic.hpp +++ b/sprout/rational/arithmetic.hpp @@ -255,4 +255,4 @@ namespace sprout { } } // namespace sprout -#endif // SPROUT_RATIONAL_ARITHMETIC_HPP +#endif // SPROUT_RATIONAL_ARITHMETIC_HPP diff --git a/sprout/rational/comparison.hpp b/sprout/rational/comparison.hpp index 83dd32c2..b465f194 100644 --- a/sprout/rational/comparison.hpp +++ b/sprout/rational/comparison.hpp @@ -193,4 +193,4 @@ namespace sprout { } } // namespace sprout -#endif // SPROUT_RATIONAL_COMPARISON_HPP +#endif // SPROUT_RATIONAL_COMPARISON_HPP diff --git a/sprout/rational/conversion.hpp b/sprout/rational/conversion.hpp index 30e2df60..764d8d19 100644 --- a/sprout/rational/conversion.hpp +++ b/sprout/rational/conversion.hpp @@ -15,4 +15,4 @@ namespace sprout { } } // namespace sprout -#endif // SPROUT_RATIONAL_CONVERSION_HPP +#endif // SPROUT_RATIONAL_CONVERSION_HPP diff --git a/sprout/rational/exceptions.hpp b/sprout/rational/exceptions.hpp index 642462b6..b86ad1b9 100644 --- a/sprout/rational/exceptions.hpp +++ b/sprout/rational/exceptions.hpp @@ -18,4 +18,4 @@ namespace sprout { }; } // namespace sprout -#endif // SPROUT_RATIONAL_EXCEPTIONS_HPP +#endif // SPROUT_RATIONAL_EXCEPTIONS_HPP diff --git a/sprout/rational/hash.hpp b/sprout/rational/hash.hpp index f9da6a61..d58ae4c4 100644 --- a/sprout/rational/hash.hpp +++ b/sprout/rational/hash.hpp @@ -16,4 +16,4 @@ namespace sprout { } } // namespace sprout -#endif // SPROUT_RATIONAL_HASH_HPP +#endif // SPROUT_RATIONAL_HASH_HPP diff --git a/sprout/rational/io.hpp b/sprout/rational/io.hpp index 008a7a9c..f20b6f69 100644 --- a/sprout/rational/io.hpp +++ b/sprout/rational/io.hpp @@ -38,4 +38,4 @@ namespace sprout { } } // namespace sprout -#endif // SPROUT_RATIONAL_IO_HPP +#endif // SPROUT_RATIONAL_IO_HPP diff --git a/sprout/rational/rational.hpp b/sprout/rational/rational.hpp index 69168a4a..46846695 100644 --- a/sprout/rational/rational.hpp +++ b/sprout/rational/rational.hpp @@ -219,4 +219,4 @@ namespace sprout { } // namespace detail } // namespace sprout -#endif // SPROUT_RATIONAL_RATIONAL_HPP +#endif // SPROUT_RATIONAL_RATIONAL_HPP diff --git a/sprout/rational/values.hpp b/sprout/rational/values.hpp index 0b7cdd4d..0f140056 100644 --- a/sprout/rational/values.hpp +++ b/sprout/rational/values.hpp @@ -21,4 +21,4 @@ namespace sprout { } } // namespace sprout -#endif // SPROUT_RATIONAL_VALUES_HPP +#endif // SPROUT_RATIONAL_VALUES_HPP diff --git a/sprout/tpp/algorithm.hpp b/sprout/tpp/algorithm.hpp new file mode 100644 index 00000000..12ab7326 --- /dev/null +++ b/sprout/tpp/algorithm.hpp @@ -0,0 +1,95 @@ +#ifndef SPROUT_TPP_ALGORITHM_HPP +#define SPROUT_TPP_ALGORITHM_HPP + +#include +#include + +namespace sprout { + namespace tpp { + namespace detail { + template + struct all_of_impl; + template<> + struct all_of_impl + : public std::true_type + {}; + template<> + struct all_of_impl + : public std::false_type + {}; + template + struct all_of_impl + : public std::integral_constant::value> + {}; + template + struct all_of_impl + : public std::false_type + {}; + } // namespace detail + // + // all_of + // + template + struct all_of + : public sprout::tpp::detail::all_of_impl + {}; + + namespace detail { + template + struct any_of_impl; + template<> + struct any_of_impl + : public std::true_type + {}; + template<> + struct any_of_impl + : public std::false_type + {}; + template + struct any_of_impl + : public std::true_type + {}; + template + struct any_of_impl + : public std::integral_constant::value> + {}; + } // namespace detail + // + // any_of + // + template + struct any_of + : public sprout::tpp::detail::any_of_impl + {}; + + namespace detail { + template + struct none_of_impl; + template<> + struct none_of_impl + : public std::false_type + {}; + template<> + struct none_of_impl + : public std::true_type + {}; + template + struct none_of_impl + : public std::false_type + {}; + template + struct none_of_impl + : public std::integral_constant::value> + {}; + } // namespace detail + // + // none_of + // + template + struct none_of + : public sprout::tpp::detail::none_of_impl + {}; + } // namespace tpp +} // namespace sprout + +#endif // #ifndef SPROUT_TPP_ALGORITHM_HPP diff --git a/sprout/utility/pair.hpp b/sprout/utility/pair.hpp index f909ae28..6c0eb7d3 100644 --- a/sprout/utility/pair.hpp +++ b/sprout/utility/pair.hpp @@ -1,7 +1,6 @@ #ifndef SPROUT_UTILITY_PAIR_HPP #define SPROUT_UTILITY_PAIR_HPP -#include #include #include #include @@ -10,7 +9,6 @@ #include #include #include -#include namespace sprout { // Copyright (C) 2011 RiSK (sscrisk) @@ -145,7 +143,7 @@ namespace sprout { // swap // template - inline void swap(sprout::pair& x, sprout::pair& y) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(x.swap(y))) { + inline void swap(pair& x, pair& y) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(x.swap(y))) { x.swap(y); } @@ -166,14 +164,6 @@ namespace sprout { sprout::forward(y) ); } - - // - // hash_value - // - template - inline SPROUT_CONSTEXPR std::size_t hash_value(sprout::pair const& v) { - return sprout::hash_values(v.first, v.second); - } } // namespace sprout namespace sprout { diff --git a/sprout/uuid/uuid.hpp b/sprout/uuid/uuid.hpp index aba93409..a2662f0e 100644 --- a/sprout/uuid/uuid.hpp +++ b/sprout/uuid/uuid.hpp @@ -7,7 +7,8 @@ #include #include #include -#include +#include +#include #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION # include diff --git a/sprout/weed/parser/directive/replace.hpp b/sprout/weed/parser/directive/replace.hpp new file mode 100644 index 00000000..137a02a5 --- /dev/null +++ b/sprout/weed/parser/directive/replace.hpp @@ -0,0 +1,108 @@ +#ifndef SPROUT_WEED_PARSER_DIRECTIVE_REPLACE_HPP +#define SPROUT_WEED_PARSER_DIRECTIVE_REPLACE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace weed { + // + // replace_p + // + template + struct replace_p + : public sprout::weed::parser_base + { + public: + typedef T value_type; + template + struct attribute { + public: + typedef value_type type; + }; + template + struct result { + public: + typedef sprout::weed::parser_result::type> type; + }; + private: + typedef typename sprout::weed::traits::terminal_or_expr_of::type expr_type; + private: + expr_type expr_; + value_type value_; + private: + template + SPROUT_CONSTEXPR typename result::type call( + Iterator first, + Result const& res + ) const + { + typedef typename result::type result_type; + typedef typename attribute::type attribute_type; + return res.success() + ? result_type(true, res.current(), value_) + : result_type(false, first, value_) + ; + } + public: + replace_p() = default; + SPROUT_CONSTEXPR replace_p( + Parser const& p, + value_type const& value + ) + : expr_(sprout::weed::make_terminal_or_expr(p)) + , value_(value) + {} + template + SPROUT_CONSTEXPR typename result::type operator()( + Iterator first, + Iterator last, + Context const& ctx + ) const + { + return call(first, sprout::weed::eval(expr_, ctx)); + } + }; + // + // replace_d + // + template + struct replace_d { + public: + typedef T value_type; + private: + value_type value_; + public: + explicit SPROUT_CONSTEXPR replace_d(value_type const& value) + : value_(value) + {} + template + SPROUT_CONSTEXPR sprout::weed::replace_p operator[](Parser const& p) const { + return sprout::weed::replace_p(p, value_); + } + }; + // + // replace_g + // + struct replace_g { + public: + template + SPROUT_CONSTEXPR sprout::weed::replace_d operator()(T const& value) const { + return sprout::weed::replace_d(value); + } + }; + // + // replace + // + SPROUT_CONSTEXPR sprout::weed::replace_g replace = sprout::weed::replace_g(); + } // namespace weed +} // namespace sprout + +#endif // #ifndef SPROUT_WEED_PARSER_DIRECTIVE_REPLACE_HPP diff --git a/testspr/tools.hpp b/testspr/tools.hpp index 8b798eaf..6e073351 100644 --- a/testspr/tools.hpp +++ b/testspr/tools.hpp @@ -142,6 +142,29 @@ namespace testspr { SPROUT_CONSTEXPR T operator()(T const& lhs, T const& rhs) const { return lhs + rhs; } }; + // + // gen_iota + // + template + struct gen_iota { + public: + struct result { + public: + T val; + gen_iota gen; + public: + SPROUT_CONSTEXPR T const& generated_value() const { return val; } + SPROUT_CONSTEXPR gen_iota const& next_generator() const { return gen; } + }; + private: + T val; + public: + explicit SPROUT_CONSTEXPR gen_iota(T const& val = T()) + : val(val) + {} + SPROUT_CONSTEXPR result operator()() const { return result{val, gen_iota(val + 1)}; } + }; + // // distance //