destructive change sprout::generate -> sprout::unfold

add range adapter reversed, replaced, filtered
This commit is contained in:
bolero-MURAKAMI 2012-09-21 15:43:30 +09:00
parent 6b3f7ad894
commit 73ead93fe5
60 changed files with 3840 additions and 318 deletions

View file

@ -11,29 +11,27 @@ namespace testspr {
static void algorithm_generate_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{0}};
// <20><EFBFBD>¬
{
SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate(
arr1,
testspr::x2<int>(),
2
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 10>{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}}
array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
));
}
{
SPROUT_STATIC_CONSTEXPR auto generated = sprout::fit::generate(
arr1,
testspr::x2<int>(),
2
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 10>{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}}
array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
));
}
// <20><EFBFBD>¬
@ -41,31 +39,29 @@ namespace testspr {
{
SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate(
sprout::sub(arr1, 2, 8),
testspr::x2<int>(),
2
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 6>{{2, 4, 8, 16, 32, 64}}
array<int, 6>{{1, 2, 3, 4, 5, 6}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(generated),
array<int, 10>{{1, 2, 2, 4, 8, 16, 32, 64, 9, 10}}
array<int, 10>{{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<int>(),
2
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 6>{{2, 4, 8, 16, 32, 64}}
array<int, 6>{{1, 2, 3, 4, 5, 6}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(generated),
array<int, 10>{{1, 2, 2, 4, 8, 16, 32, 64, 9, 10}}
array<int, 10>{{0, 0, 1, 2, 3, 4, 5, 6, 0, 0}}
));
}
}

View file

@ -11,31 +11,29 @@ namespace testspr {
static void algorithm_generate_n_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{0}};
// <20><EFBFBD>¬
{
SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate_n(
arr1,
4,
testspr::x2<int>(),
1
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 10>{{1, 2, 4, 8, 5, 6, 7, 8, 9, 10}}
array<int, 10>{{1, 2, 3, 4, 0, 0, 0, 0, 0, 0}}
));
}
{
SPROUT_STATIC_CONSTEXPR auto generated = sprout::fit::generate_n(
arr1,
4,
testspr::x2<int>(),
1
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 4>{{1, 2, 4, 8}}
array<int, 4>{{1, 2, 3, 4}}
));
}
// <20><EFBFBD>¬
@ -44,32 +42,30 @@ namespace testspr {
SPROUT_STATIC_CONSTEXPR auto generated = sprout::generate_n(
sprout::sub(arr1, 2, 8),
4,
testspr::x2<int>(),
1
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 6>{{1, 2, 4, 8, 7, 8}}
array<int, 6>{{1, 2, 3, 4, 0, 0}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(generated),
array<int, 10>{{1, 2, 1, 2, 4, 8, 7, 8, 9, 10}}
array<int, 10>{{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<int>(),
1
testspr::gen_iota<int>(1)
);
TESTSPR_BOTH_ASSERT(testspr::equal(
generated,
array<int, 4>{{1, 2, 4, 8}}
array<int, 4>{{1, 2, 3, 4}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(generated),
array<int, 10>{{1, 2, 1, 2, 4, 8, 7, 8, 9, 10}}
array<int, 10>{{0, 0, 1, 2, 3, 4, 0, 0, 0, 0}}
));
}
}

View file

@ -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();

View file

@ -0,0 +1,80 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_CPP
#include <sprout/algorithm/unfold.hpp>
#include <sprout/array.hpp>
#include <sprout/sub_array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_unfold_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
// 生成
{
SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold(
arr1,
testspr::x2<int>(),
2
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 10>{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}}
));
}
{
SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::fit::unfold(
arr1,
testspr::x2<int>(),
2
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 10>{{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}}
));
}
// 生成
// 範囲の切り出し
{
SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold(
sprout::sub(arr1, 2, 8),
testspr::x2<int>(),
2
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 6>{{2, 4, 8, 16, 32, 64}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(unfolded),
array<int, 10>{{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<int>(),
2
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 6>{{2, 4, 8, 16, 32, 64}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(unfolded),
array<int, 10>{{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 <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_CPP

View file

@ -0,0 +1,84 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_N_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_N_CPP
#include <sprout/algorithm/unfold_n.hpp>
#include <sprout/array.hpp>
#include <sprout/sub_array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_unfold_n_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
// 生成
{
SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold_n(
arr1,
4,
testspr::x2<int>(),
1
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 10>{{1, 2, 4, 8, 5, 6, 7, 8, 9, 10}}
));
}
{
SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::fit::unfold_n(
arr1,
4,
testspr::x2<int>(),
1
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 4>{{1, 2, 4, 8}}
));
}
// 生成
// 範囲の切り出し
{
SPROUT_STATIC_CONSTEXPR auto unfolded = sprout::unfold_n(
sprout::sub(arr1, 2, 8),
4,
testspr::x2<int>(),
1
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 6>{{1, 2, 4, 8, 7, 8}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(unfolded),
array<int, 10>{{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<int>(),
1
);
TESTSPR_BOTH_ASSERT(testspr::equal(
unfolded,
array<int, 4>{{1, 2, 4, 8}}
));
TESTSPR_BOTH_ASSERT(testspr::equal(
sprout::get_internal(unfolded),
array<int, 10>{{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 <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_UNFOLD_N_CPP

View file

@ -15,6 +15,8 @@
#include <sprout/algorithm/fit/fill_n.hpp>
#include <sprout/algorithm/fit/generate.hpp>
#include <sprout/algorithm/fit/generate_n.hpp>
#include <sprout/algorithm/fit/unfold.hpp>
#include <sprout/algorithm/fit/unfold_n.hpp>
#include <sprout/algorithm/fit/remove.hpp>
#include <sprout/algorithm/fit/remove_if.hpp>
#include <sprout/algorithm/fit/remove_copy.hpp>

View file

@ -11,16 +11,15 @@
namespace sprout {
namespace fit {
namespace detail {
template<typename Container, typename Generator, typename... Inits>
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type generate_impl(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::difference_type offset,
Inits const&... inits
typename sprout::container_traits<Container>::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<typename Container, typename Generator, typename... Inits>
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::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

View file

@ -12,17 +12,15 @@
namespace sprout {
namespace fit {
namespace detail {
template<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type generate_n_impl(
Container const& cont,
Size n,
Generator gen,
typename sprout::container_traits<Container>::difference_type offset,
Inits const&... inits
template<typename Container, typename Size, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type
generate_n_impl(
Container const& cont, Size n, Generator gen,
typename sprout::container_traits<Container>::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<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::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<typename Container, typename Size, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::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

View file

@ -0,0 +1,44 @@
#ifndef SPROUT_ALGORITHM_FIT_UNFOLD_HPP
#define SPROUT_ALGORITHM_FIT_UNFOLD_HPP
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/unfold.hpp>
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
namespace sprout {
namespace fit {
namespace detail {
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type unfold_impl(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::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<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::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

View file

@ -0,0 +1,47 @@
#ifndef SPROUT_ALGORITHM_FIT_UNFOLD_N_HPP
#define SPROUT_ALGORITHM_FIT_UNFOLD_N_HPP
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/unfold_n.hpp>
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace fit {
namespace detail {
template<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::type unfold_n_impl(
Container const& cont,
Size n,
Generator gen,
typename sprout::container_traits<Container>::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<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fit::result_of::algorithm<Container>::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

View file

@ -15,6 +15,8 @@
#include <sprout/algorithm/fixed/fill_n.hpp>
#include <sprout/algorithm/fixed/generate.hpp>
#include <sprout/algorithm/fixed/generate_n.hpp>
#include <sprout/algorithm/fixed/unfold.hpp>
#include <sprout/algorithm/fixed/unfold_n.hpp>
#include <sprout/algorithm/fixed/remove.hpp>
#include <sprout/algorithm/fixed/remove_if.hpp>
#include <sprout/algorithm/fixed/remove_copy.hpp>

View file

@ -1,163 +1,83 @@
#ifndef SPROUT_ALGORITHM_FIXED_GENERATE_HPP
#define SPROUT_ALGORITHM_FIXED_GENERATE_HPP
#include <cstddef>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/generator/functions.hpp>
#include <sprout/detail/container_complate.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace fixed {
namespace detail {
template<std::size_t InitSize, typename Container, typename Generator, typename... Args>
template<typename Container, typename Gen, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
InitSize == 0,
typename sprout::container_traits<Container>::value_type
>::type call_gen(
Generator gen,
sprout::container_traits<Container>::static_size == sizeof...(Args) + 1,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl_1(
Container const& cont, Gen const& gen,
typename sprout::container_traits<Container>::size_type size,
Args const&... args
)
{
return gen();
return sprout::remake<Container>(cont, size, args..., sprout::generators::generated_value(gen));
}
template<std::size_t InitSize, typename Container, typename Generator, typename Head, typename... Args>
template<typename Container, typename Gen, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
InitSize != 0 && InitSize == sizeof...(Args) + 1,
typename sprout::container_traits<Container>::value_type
>::type call_gen(
Generator gen,
Head const& head,
sprout::container_traits<Container>::static_size != sizeof...(Args) + 1,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type
generate_impl_1(
Container const& cont, Gen const& gen,
typename sprout::container_traits<Container>::size_type size,
Args const&... args
)
{
return gen(head, args...);
}
template<std::size_t InitSize, typename Container, typename Generator, typename Head, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
InitSize != 0 && InitSize != sizeof...(Args) + 1,
typename sprout::container_traits<Container>::value_type
>::type call_gen(
Generator gen,
Head const& head,
Args const&... 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)
)
{
return call_gen<InitSize, Container>(gen, args...);
: sprout::detail::container_complate(cont, args..., sprout::generators::generated_value(gen))
;
}
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type generate_impl_drop(
Container const& cont,
Generator gen,
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Container>::static_size == 0,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl(
Container const& cont, Generator gen,
typename sprout::container_traits<Container>::size_type size
)
{
return sprout::detail::container_complate(cont);
return sprout::remake<Container>(cont, size);
}
template<typename Container, typename Generator, typename Head, typename... Inits>
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size >= sizeof...(Inits) + 1),
sprout::container_traits<Container>::static_size != 0,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl_drop(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Head const& head,
Inits const&... inits
>::type
generate_impl(
Container const& cont, Generator gen,
typename sprout::container_traits<Container>::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<typename Container, typename Generator, typename Head, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size < sizeof...(Inits) + 1),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl_drop(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Head const& head,
Inits const&... inits
)
{
return sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...);
}
template<std::size_t InitSize, typename Container, typename Generator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Container>::static_size == sizeof...(Args),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl_1(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Args const&... args
)
{
return sprout::remake<Container>(cont, sprout::size(cont), args...);
}
template<std::size_t InitSize, typename Container, typename Generator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Container>::static_size != sizeof...(Args),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl_1(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Args const&... args
)
{
return sizeof...(Args) < size
? sprout::fixed::detail::generate_impl_1<InitSize>(cont, gen, size, args..., sprout::fixed::detail::call_gen<InitSize, Container>(gen, args...))
: sprout::detail::container_complate(cont, args...)
;
}
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size > sizeof...(Inits)),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Inits const&... inits
)
{
return sizeof...(Inits) < size
? sprout::fixed::detail::generate_impl_1<sizeof...(Inits)>(cont, gen, size, inits...)
: sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...)
;
}
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size <= sizeof...(Inits)),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type generate_impl(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Inits const&... inits
)
{
return sprout::fixed::detail::generate_impl_drop(cont, gen, size, inits...);
}
} // namespace detail
//
// generate
//
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type generate(
Container const& cont,
Generator gen,
Inits const&... inits
)
{
return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont), inits...);
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
generate(Container const& cont, Generator gen) {
return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont));
}
} // namespace fixed

View file

@ -11,15 +11,10 @@ namespace sprout {
//
// generate_n
//
template<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type generate_n(
Container const& cont,
Size n,
Generator gen,
Inits const&... inits
)
{
return sprout::fixed::detail::generate_impl(cont, gen, n, inits...);
template<typename Container, typename Size, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
generate_n(Container const& cont, Size n, Generator gen) {
return sprout::fixed::detail::generate_impl(cont, gen, n);
}
} // namespace fixed

View file

@ -0,0 +1,167 @@
#ifndef SPROUT_ALGORITHM_FIXED_UNFOLD_HPP
#define SPROUT_ALGORITHM_FIXED_UNFOLD_HPP
#include <cstddef>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/detail/container_complate.hpp>
namespace sprout {
namespace fixed {
namespace detail {
template<std::size_t InitSize, typename Container, typename Generator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
InitSize == 0,
typename sprout::container_traits<Container>::value_type
>::type call_gen(
Generator gen,
Args const&... args
)
{
return gen();
}
template<std::size_t InitSize, typename Container, typename Generator, typename Head, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
InitSize != 0 && InitSize == sizeof...(Args) + 1,
typename sprout::container_traits<Container>::value_type
>::type call_gen(
Generator gen,
Head const& head,
Args const&... args
)
{
return gen(head, args...);
}
template<std::size_t InitSize, typename Container, typename Generator, typename Head, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
InitSize != 0 && InitSize != sizeof...(Args) + 1,
typename sprout::container_traits<Container>::value_type
>::type call_gen(
Generator gen,
Head const& head,
Args const&... args
)
{
return call_gen<InitSize, Container>(gen, args...);
}
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type unfold_impl_drop(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size
)
{
return sprout::detail::container_complate(cont);
}
template<typename Container, typename Generator, typename Head, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size >= sizeof...(Inits) + 1),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type unfold_impl_drop(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::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<typename Container, typename Generator, typename Head, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size < sizeof...(Inits) + 1),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type unfold_impl_drop(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Head const& head,
Inits const&... inits
)
{
return sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...);
}
template<std::size_t InitSize, typename Container, typename Generator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Container>::static_size == sizeof...(Args),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type unfold_impl_1(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Args const&... args
)
{
return sprout::remake<Container>(cont, sprout::size(cont), args...);
}
template<std::size_t InitSize, typename Container, typename Generator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Container>::static_size != sizeof...(Args),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type unfold_impl_1(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Args const&... args
)
{
return sizeof...(Args) < size
? sprout::fixed::detail::unfold_impl_1<InitSize>(cont, gen, size, args..., sprout::fixed::detail::call_gen<InitSize, Container>(gen, args...))
: sprout::detail::container_complate(cont, args...)
;
}
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size > sizeof...(Inits)),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type unfold_impl(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Inits const&... inits
)
{
return sizeof...(Inits) < size
? sprout::fixed::detail::unfold_impl_1<sizeof...(Inits)>(cont, gen, size, inits...)
: sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...)
;
}
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size <= sizeof...(Inits)),
typename sprout::fixed::result_of::algorithm<Container>::type
>::type unfold_impl(
Container const& cont,
Generator gen,
typename sprout::container_traits<Container>::size_type size,
Inits const&... inits
)
{
return sprout::fixed::detail::unfold_impl_drop(cont, gen, size, inits...);
}
} // namespace detail
//
// unfold
//
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::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

View file

@ -0,0 +1,29 @@
#ifndef SPROUT_ALGORITHM_FIXED_UNFOLD_N_HPP
#define SPROUT_ALGORITHM_FIXED_UNFOLD_N_HPP
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/unfold.hpp>
namespace sprout {
namespace fixed {
//
// unfold_n
//
template<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::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

View file

@ -0,0 +1,8 @@
#ifndef SPROUT_ALGORITHM_UNFOLD_HPP
#define SPROUT_ALGORITHM_UNFOLD_HPP
#include <sprout/config.hpp>
#include <sprout/algorithm/fixed/unfold.hpp>
#include <sprout/algorithm/fit/unfold.hpp>
#endif // #ifndef SPROUT_ALGORITHM_UNFOLD_HPP

View file

@ -0,0 +1,8 @@
#ifndef SPROUT_ALGORITHM_UNFOLD_N_HPP
#define SPROUT_ALGORITHM_UNFOLD_N_HPP
#include <sprout/config.hpp>
#include <sprout/algorithm/fixed/unfold_n.hpp>
#include <sprout/algorithm/fit/unfold_n.hpp>
#endif // #ifndef SPROUT_ALGORITHM_UNFOLD_N_HPP

View file

@ -9,7 +9,8 @@
#include <sprout/index_tuple.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/reverse_iterator.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
# include <sprout/iterator/index_iterator.hpp>

9
sprout/brainfuck.hpp Normal file
View file

@ -0,0 +1,9 @@
#ifndef SPROUT_BRAINFUCK_HPP
#define SPROUT_BRAINFUCK_HPP
#include <sprout/config.hpp>
#include <sprout/brainfuck/brainfuck.hpp>
#include <sprout/brainfuck/ook.hpp>
#include <sprout/brainfuck/misa.hpp>
#endif // #ifndef SPROUT_BRAINFUCK_HPP

View file

@ -0,0 +1,211 @@
#ifndef SPROUT_BRAINFUCK_BRAINFUCK_HPP
#define SPROUT_BRAINFUCK_BRAINFUCK_HPP
#include <cstddef>
#include <iterator>
#include <stdexcept>
#include <sprout/config.hpp>
#include <sprout/array.hpp>
#include <sprout/pit.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/value_iterator.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/copy.hpp>
#include <sprout/operation/fixed/set.hpp>
namespace sprout {
namespace brainfuck {
namespace detail {
template<typename InputIterator>
inline SPROUT_CONSTEXPR InputIterator
find_scope_end(InputIterator first, std::size_t count = 0) {
typedef typename std::iterator_traits<InputIterator>::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<typename BidirectionalIterator>
inline SPROUT_CONSTEXPR BidirectionalIterator
find_scope_start(BidirectionalIterator first, std::size_t count = 0) {
typedef typename std::iterator_traits<BidirectionalIterator>::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<typename InputIterator>
inline SPROUT_CONSTEXPR bool
is_well_formed(InputIterator first, InputIterator last, std::size_t count = 0) {
typedef typename std::iterator_traits<InputIterator>::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<Output>::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<SourceBidirectionalIterator>::value_type value_type;
typedef typename sprout::container_traits<OutputBuffer>::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<std::size_t BufferSize = 32, typename SourceBidirectionalIterator, typename Output, typename InputInputIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec(
SourceBidirectionalIterator first, SourceBidirectionalIterator last,
Output const& output, InputInputIterator in_first, InputInputIterator in_last
)
{
typedef typename std::iterator_traits<SourceBidirectionalIterator>::value_type value_type;
typedef sprout::container_traits<Output> out_traits;
return sprout::brainfuck::detail::exec_impl(
first, last, output, in_first, in_last,
sprout::array<value_type, BufferSize>{{}}, sprout::array<typename out_traits::value_type, out_traits::static_size>{{}}
);
}
template<std::size_t BufferSize = 32, typename SourceBidirectionalIterator, typename Output>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec(
SourceBidirectionalIterator first, SourceBidirectionalIterator last,
Output const& output
)
{
typedef typename std::iterator_traits<SourceBidirectionalIterator>::value_type value_type;
return sprout::brainfuck::exec<BufferSize>(
first, last, output, sprout::value_iterator<value_type>(value_type()), sprout::value_iterator<value_type>()
);
}
template<std::size_t BufferSize = 32, typename SourceBidirectionalIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<
sprout::array<typename std::iterator_traits<SourceBidirectionalIterator>::value_type, BufferSize>
>::type
exec(
SourceBidirectionalIterator first, SourceBidirectionalIterator last
)
{
typedef typename std::iterator_traits<SourceBidirectionalIterator>::value_type value_type;
return sprout::brainfuck::exec<BufferSize>(
first, last, sprout::pit<sprout::array<value_type, BufferSize> >()
);
}
//
// exec_range
//
template<std::size_t BufferSize = 32, typename Source, typename Output, typename Input>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec_range(Source const& source, Output const& output, Input const& input) {
return sprout::brainfuck::exec<BufferSize>(
sprout::begin(source), sprout::end(source), output, sprout::begin(input), sprout::end(input)
);
}
template<std::size_t BufferSize = 32, typename Source, typename Output>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec_range(Source const& source, Output const& output) {
return sprout::brainfuck::exec<BufferSize>(
sprout::begin(source), sprout::end(source), output
);
}
template<std::size_t BufferSize = 32, typename Source>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<
sprout::array<typename sprout::container_traits<Source>::value_type, BufferSize>
>::type
exec_range(Source const& source) {
return sprout::brainfuck::exec<BufferSize>(
sprout::begin(source), sprout::end(source)
);
}
//
// is_well_formed
//
template<typename InputIterator>
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

View file

@ -0,0 +1,30 @@
#ifndef SPROUT_BRAINFUCK_DETAIL_CONVERT_HPP
#define SPROUT_BRAINFUCK_DETAIL_CONVERT_HPP
#include <sprout/config.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/copy.hpp>
namespace sprout {
namespace brainfuck {
namespace detail {
template<typename Result, typename Parsed>
inline SPROUT_CONSTEXPR sprout::pair<typename sprout::fixed::result_of::algorithm<Result>::type, bool>
parsed_to_brainfuck(Parsed const& parsed, Result const& result) {
return parsed.success()
? sprout::pair<typename sprout::fixed::result_of::algorithm<Result>::type, bool>(
sprout::fixed::copy(sprout::begin(parsed.attr()), sprout::end(parsed.attr()), result),
true
)
: sprout::pair<typename sprout::fixed::result_of::algorithm<Result>::type, bool>(
sprout::deep_copy(result),
false
)
;
}
} // namespace detail
} // namespace brainfuck
} // namespace sprout
#endif // #ifndef SPROUT_BRAINFUCK_DETAIL_CONVERT_HPP

92
sprout/brainfuck/misa.hpp Normal file
View file

@ -0,0 +1,92 @@
#ifndef SPROUT_BRAINFUCK_MISA_HPP
#define SPROUT_BRAINFUCK_MISA_HPP
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/utility/pair.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/weed/parse.hpp>
#include <sprout/weed/parser/lim.hpp>
#include <sprout/weed/parser/lit.hpp>
#include <sprout/weed/parser/char/char.hpp>
#include <sprout/weed/parser/char/char_class.hpp>
#include <sprout/weed/parser/string/string.hpp>
#include <sprout/weed/parser/directive/replace.hpp>
#include <sprout/weed/operator.hpp>
#include <sprout/brainfuck/detail/convert.hpp>
namespace sprout {
namespace brainfuck {
namespace misa {
//
// to_brainfuck
//
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR sprout::pair<typename sprout::fixed::result_of::algorithm<Result>::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<sprout::container_traits<Result>::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<std::size_t BufferSize = 32, typename Source, typename Output, typename Input>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec_range(Source const& source, Output const& output, Input const& input) {
typedef typename sprout::container_construct_traits<Source>::copied_type copied_type;
return sprout::brainfuck::exec_range<BufferSize>(
sprout::brainfuck::misa::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit<copied_type>()).first,
output, input
);
}
template<std::size_t BufferSize = 32, typename Source, typename Output>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec_range(Source const& source, Output const& output) {
typedef typename sprout::container_construct_traits<Source>::copied_type copied_type;
return sprout::brainfuck::exec_range<BufferSize>(
sprout::brainfuck::misa::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit<copied_type>()).first,
output
);
}
template<std::size_t BufferSize = 32, typename Source>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<
sprout::array<typename sprout::container_traits<Source>::value_type, BufferSize>
>::type
exec_range(Source const& source) {
typedef typename sprout::container_construct_traits<Source>::copied_type copied_type;
return sprout::brainfuck::exec_range<BufferSize>(
sprout::brainfuck::misa::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit<copied_type>()).first
);
}
} // namespace misa
} // namespace brainfuck
} // namespace sprout
#endif // #ifndef SPROUT_BRAINFUCK_MISA_HPP

92
sprout/brainfuck/ook.hpp Normal file
View file

@ -0,0 +1,92 @@
#ifndef SPROUT_BRAINFUCK_OOK_HPP
#define SPROUT_BRAINFUCK_OOK_HPP
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/utility/pair.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/weed/parse.hpp>
#include <sprout/weed/parser/lim.hpp>
#include <sprout/weed/parser/lit.hpp>
#include <sprout/weed/parser/char/char.hpp>
#include <sprout/weed/parser/char/char_class.hpp>
#include <sprout/weed/parser/string/string.hpp>
#include <sprout/weed/parser/directive/replace.hpp>
#include <sprout/weed/operator.hpp>
#include <sprout/brainfuck/detail/convert.hpp>
namespace sprout {
namespace brainfuck {
namespace ook {
//
// to_brainfuck
//
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR sprout::pair<typename sprout::fixed::result_of::algorithm<Result>::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<sprout::container_traits<Result>::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<std::size_t BufferSize = 32, typename Source, typename Output, typename Input>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec_range(Source const& source, Output const& output, Input const& input) {
typedef typename sprout::container_construct_traits<Source>::copied_type copied_type;
return sprout::brainfuck::exec_range<BufferSize>(
sprout::brainfuck::ook::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit<copied_type>()).first,
output, input
);
}
template<std::size_t BufferSize = 32, typename Source, typename Output>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Output>::type
exec_range(Source const& source, Output const& output) {
typedef typename sprout::container_construct_traits<Source>::copied_type copied_type;
return sprout::brainfuck::exec_range<BufferSize>(
sprout::brainfuck::ook::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit<copied_type>()).first,
output
);
}
template<std::size_t BufferSize = 32, typename Source>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<
sprout::array<typename sprout::container_traits<Source>::value_type, BufferSize>
>::type
exec_range(Source const& source) {
typedef typename sprout::container_construct_traits<Source>::copied_type copied_type;
return sprout::brainfuck::exec_range<BufferSize>(
sprout::brainfuck::ook::to_brainfuck(sprout::begin(source), sprout::end(source), sprout::pit<copied_type>()).first
);
}
} // namespace ook
} // namespace brainfuck
} // namespace sprout
#endif // #ifndef SPROUT_BRAINFUCK_OOK_HPP

View file

@ -1,12 +1,588 @@
#ifndef SPROUT_COMPLEX_HPP
#define SPROUT_COMPLEX_HPP
#include <iosfwd>
#include <ios>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/values.hpp>
#include <sprout/complex/transcendentals.hpp>
#include <sprout/complex/nearest.hpp>
#include <sprout/complex/hash.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/abs.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/math/atan2.hpp>
#include <sprout/math/sinh.hpp>
#include <sprout/math/cosh.hpp>
#include <sprout/math/exp.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/pow.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/math/ceil.hpp>
#include <sprout/math/floor.hpp>
#include <sprout/math/trunc.hpp>
#include <sprout/math/round.hpp>
namespace sprout {
template<typename T>
class complex;
template<typename T>
SPROUT_CONSTEXPR T norm(sprout::complex<T> const& x);
//
// complex
//
template<typename T>
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<typename X>
SPROUT_CONSTEXPR complex(complex<X> 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<T>& operator=(T const& rhs) {
re_ = rhs;
im_ = T();
return *this;
}
complex<T>& operator+=(T const& rhs) {
re_ += rhs;
return *this;
}
complex<T>& operator-=(T const& rhs) {
re_ -= rhs;
return *this;
}
complex<T>& operator*=(T const& rhs) {
re_ *= rhs;
im_ *= rhs;
return *this;
}
complex<T>& operator/=(T const& rhs) {
re_ /= rhs;
im_ /= rhs;
return *this;
}
complex& operator=(complex const&) = default;
template<typename X>
complex<T>& operator=(complex<X> const& rhs) {
re_ = rhs.real();
im_ = rhs.imag();
return *this;
}
template<typename X>
complex<T>& operator+=(complex<X> const& rhs) {
re_ += rhs.real();
im_ += rhs.imag();
return *this;
}
template<typename X>
complex<T>& operator-=(complex<X> const& rhs) {
re_ -= rhs.real();
im_ -= rhs.imag();
return *this;
}
template<typename X>
complex<T>& operator*=(complex<X> const& rhs) {
return *this = complex<T>(
re_ * rhs.real() - im_ * rhs.imag(),
re_ * rhs.imag() + im_ * rhs.real()
);
}
template<typename X>
complex<T>& operator/=(complex<X> const& rhs) {
T n = sprout::norm(rhs);
return *this = complex<T>(
(re_ * rhs.real() + im_ * rhs.imag()) / n,
(im_ * rhs.real() - re_ * rhs.imag()) / n
);
}
};
// 26.4.6, operators:
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator+(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
return sprout::complex<T>(
lhs.real() + rhs.real(),
lhs.imag() + rhs.imag()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator+(sprout::complex<T> const& lhs, T const& rhs) {
return sprout::complex<T>(
lhs.real() + rhs,
lhs.imag()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator+(T const& lhs, sprout::complex<T> const& rhs) {
return sprout::complex<T>(
lhs + rhs.real(),
rhs.imag()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator-(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
return sprout::complex<T>(
lhs.real() - rhs.real(),
lhs.imag() - rhs.imag()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator-(sprout::complex<T> const& lhs, T const& rhs) {
return sprout::complex<T>(
lhs.real() - rhs,
lhs.imag()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator-(T const& lhs, sprout::complex<T> const& rhs) {
return sprout::complex<T>(
lhs - rhs.real(),
-rhs.imag()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator*(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
return sprout::complex<T>(
lhs.real() * rhs.real() - lhs.imag() * rhs.imag(),
lhs.real() * rhs.imag() + lhs.imag() * rhs.real()
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator*(sprout::complex<T> const& lhs, T const& rhs) {
return sprout::complex<T>(
lhs.real() * rhs,
lhs.imag() * rhs
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator*(T const& lhs, sprout::complex<T> const& rhs) {
return sprout::complex<T>(
lhs * rhs.real(),
lhs * rhs.imag()
);
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> divides_impl(
sprout::complex<T> const& lhs,
sprout::complex<T> const& rhs,
T const& n
)
{
return sprout::complex<T>(
(lhs.real() * rhs.real() + lhs.imag() * rhs.imag()) / n,
(lhs.imag() * rhs.real() - lhs.real() * rhs.imag()) / n
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> divides_impl(
T const& lhs,
sprout::complex<T> const& rhs,
T const& n
)
{
return sprout::complex<T>(
lhs * rhs.real() / n,
-lhs * rhs.imag() / n
);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator/(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
return sprout::detail::divides_impl(lhs, rhs, sprout::norm(rhs));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator/(sprout::complex<T> const& lhs, T const& rhs) {
return sprout::complex<T>(
lhs.real() / rhs,
lhs.imag() / rhs
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator/(T const& lhs, sprout::complex<T> const& rhs) {
return sprout::detail::divides_impl(lhs, rhs, sprout::norm(rhs));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator+(sprout::complex<T> const& x) {
return x;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> operator-(sprout::complex<T> const& x) {
return sprout::complex<T>(-x.real(), -x.imag());
}
template<typename T>
inline SPROUT_CONSTEXPR bool operator==(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
}
template<typename T>
inline SPROUT_CONSTEXPR bool operator==(sprout::complex<T> const& lhs, T const& rhs) {
return lhs.real() == rhs && lhs.imag() == T();
}
template<typename T>
inline SPROUT_CONSTEXPR bool operator==(T const& lhs, sprout::complex<T> const& rhs) {
return lhs == rhs.real() && T() == rhs.imag();
}
template<typename T>
inline SPROUT_CONSTEXPR bool operator!=(sprout::complex<T> const& lhs, sprout::complex<T> const& rhs) {
return !(lhs == rhs);
}
template<typename T>
inline SPROUT_CONSTEXPR bool operator!=(sprout::complex<T> const& lhs, T const& rhs) {
return !(lhs == rhs);
}
template<typename T>
inline SPROUT_CONSTEXPR bool operator!=(T const& lhs, sprout::complex<T> const& rhs) {
return !(lhs == rhs);
}
template<typename T, typename Char, typename Traits>
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& lhs, sprout::complex<T>& rhs) {
T re, im;
Char ch;
lhs >> ch;
if (ch == '(') {
lhs >> re >> ch;
if (ch == ',') {
lhs >> im >> ch;
if (ch == ')') {
rhs = sprout::complex<T>(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<typename T, typename Char, typename Traits>
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& lhs, sprout::complex<T> const& rhs) {
return lhs << '(' << rhs.real() << ',' << rhs.imag() << ')';
}
// 26.4.7, values:
template<typename T>
inline SPROUT_CONSTEXPR T real(sprout::complex<T> const& x) {
return x.real();
}
template<typename T>
inline SPROUT_CONSTEXPR T imag(sprout::complex<T> const& x) {
return x.imag();
}
template<typename T>
inline SPROUT_CONSTEXPR T abs(sprout::complex<T> const& x) {
return sprout::sqrt(sprout::norm(x));
}
template<typename T>
inline SPROUT_CONSTEXPR T arg(sprout::complex<T> const& x) {
return sprout::atan2(x.imag(), x.real());
}
template<typename T>
inline SPROUT_CONSTEXPR T norm(sprout::complex<T> const& x) {
return x.real() * x.real() + x.imag() * x.imag();
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> conj(sprout::complex<T> const& x) {
return sprout::complex<T>(x.real(), -x.imag());
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> proj_impl(sprout::complex<T> const& x, T const& den) {
return sprout::complex<T>(
T(2) * x.real() / den,
T(2) * x.imag() / den
);
}
} // detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> proj(sprout::complex<T> const& x) {
return sprout::detail::proj_impl(
x,
sprout::norm(x) + T(1)
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> polar(T const& rho, T const& theta = 0) {
return sprout::complex<T>(rho * sprout::cos(theta), rho * sprout::sin(theta));
}
// 26.4.8, transcendentals:
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> acos(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> asin(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> atan(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> acosh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> asinh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> atanh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> cos(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> cosh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> exp(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> log(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> log10(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, T const& y);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, sprout::complex<T> const& y);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> pow(T const& x, sprout::complex<T> const& y);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> sin(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> sinh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> sqrt(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> tan(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T> tanh(sprout::complex<T> const& x);
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> acos_impl(sprout::complex<T> const& t) {
return sprout::complex<T>(sprout::math::half_pi<T>() - t.real(), -t.imag());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> acos(sprout::complex<T> const& x) {
return sprout::detail::acos_impl(sprout::asin(x));
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> asin_impl(sprout::complex<T> const& t) {
return sprout::complex<T>(t.imag(), -t.real());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> asin(sprout::complex<T> const& x) {
return sprout::detail::asin_impl(sprout::asinh(sprout::complex<T>(-x.imag(), x.real())));
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> atan_impl_1(
sprout::complex<T> const& x,
T const& r2,
T const& z,
T const& num,
T const& den
)
{
return sprout::complex<T>(
T(0.5) * sprout::atan2(T(2) * x.real(), z),
T(0.25) * sprout::log((r2 + num * num) / (r2 + den * den))
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> atan_impl(
sprout::complex<T> 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<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> atan(sprout::complex<T> const& x) {
return sprout::detail::atan_impl(x, x.real() * x.real());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> acosh(sprout::complex<T> const& x) {
return T(2) * sprout::log(sprout::sqrt(T(0.5) * (x + T(1))) + sprout::sqrt(T(0.5) * (x - T(1))));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> asinh(sprout::complex<T> const& x) {
return sprout::log(
sprout::sqrt(
sprout::complex<T>(
(x.real() - x.imag()) * (x.real() + x.imag()) + T(1),
T(2) * x.real() * x.imag()
)
)
+ x
);
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> atanh_impl_1(
sprout::complex<T> const& x,
T const& i2,
T const& z,
T const& num,
T const& den
)
{
return sprout::complex<T>(
T(0.25) * (sprout::log(i2 + num * num) - sprout::log(i2 + den * den)),
T(0.5) * sprout::atan2(T(2) * x.imag(), z)
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> atanh_impl(
sprout::complex<T> 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<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> atanh(sprout::complex<T> const& x) {
return sprout::detail::atanh_impl(x, x.imag() * x.imag());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> cos(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::cos(x.real()) * sprout::cosh(x.imag()),
-(sprout::sin(x.real()) * sprout::sinh(x.imag()))
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> cosh(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::cosh(x.real()) * sprout::cos(x.imag()),
sprout::sinh(x.real()) * sprout::sin(x.imag())
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> exp(sprout::complex<T> const& x) {
return sprout::polar(sprout::exp(x.real()), x.imag());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> log(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::log(sprout::abs(x)), sprout::arg(x));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> log10(sprout::complex<T> const& x) {
return sprout::log(x) / sprout::log(T(10));
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> pow_impl(sprout::complex<T> const& t, T const& y) {
return sprout::polar(sprout::exp(y * t.real()), y * t.imag());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> 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<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> pow(sprout::complex<T> const& x, sprout::complex<T> const& y) {
return x == T() ? T()
: sprout::exp(y * sprout::log(x))
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> pow(T const& x, sprout::complex<T> const& y) {
return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * sprout::log(x))
: sprout::pow(sprout::complex<T>(x), y)
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> sin(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::sin(x.real()) * sprout::cosh(x.imag()),
sprout::cos(x.real()) * sprout::sinh(x.imag())
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> sinh(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::sinh(x.real()) * sprout::cos(x.imag()),
sprout::cosh(x.real()) * sprout::sin(x.imag())
);
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> sqrt_impl_1(sprout::complex<T> const& x, T const& t) {
return sprout::complex<T>(t, x.imag() < T() ? -t : t);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> sqrt_impl_2_1(sprout::complex<T> const& x, T const& t, T const& u) {
return x.real() > T() ? sprout::complex<T>(u, x.imag() / t)
: sprout::complex<T>(sprout::abs(x.imag()) / t, x.imag() < T() ? -u : u)
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> sqrt_impl_2(sprout::complex<T> const& x, T const& t) {
return sprout::detail::sqrt_impl_2_1(x, t, t / 2);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> sqrt(sprout::complex<T> 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<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> tan(sprout::complex<T> const& x) {
return sprout::sin(x) / sprout::cos(x);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> tanh(sprout::complex<T> const& x) {
return sprout::sinh(x) / sprout::cosh(x);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> ceil(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::ceil(x.real()), sprout::ceil(x.imag()));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> floor(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::floor(x.real()), sprout::floor(x.imag()));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> trunc(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::trunc(x.real()), sprout::trunc(x.imag()));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> round(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::round(x.real()), sprout::round(x.imag()));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_HPP

View file

@ -5,6 +5,5 @@
#include <sprout/darkroom/objects/intersect.hpp>
#include <sprout/darkroom/objects/sphere.hpp>
#include <sprout/darkroom/objects/aa_plane.hpp>
#include <sprout/darkroom/objects/polygon.hpp>
#endif // #ifndef SPROUT_DARKROOM_OBJECTS_HPP

View file

@ -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<typename Ray>
@ -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
);

View file

@ -10,76 +10,27 @@
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
namespace hash_detail {
struct enable_hash_value {
public:
typedef std::size_t type;
};
template<typename T, typename Enable = void>
struct basic_numbers {};
template<typename T>
struct basic_numbers<
T,
typename std::enable_if<
(std::is_integral<T>::value && sizeof(T) <= sizeof(std::size_t))
>::type
>
: public sprout::hash_detail::enable_hash_value
{};
template<typename T, typename Enable = void>
struct long_numbers {};
template<typename T>
struct long_numbers<
T,
typename std::enable_if<
(std::is_integral<T>::value && std::is_signed<T>::value && sizeof(T) > sizeof(std::size_t))
>::type
>
: public sprout::hash_detail::enable_hash_value
{};
template<typename T, typename Enable = void>
struct ulong_numbers {};
template<typename T>
struct ulong_numbers<
T,
typename std::enable_if<
(std::is_integral<T>::value && std::is_unsigned<T>::value && sizeof(T) > sizeof(std::size_t))
>::type
>
: public sprout::hash_detail::enable_hash_value
{};
template<typename T, typename Enable = void>
struct float_numbers {};
template<typename T>
struct float_numbers<
T,
typename std::enable_if<
(std::is_floating_point<T>::value)
>::type
>
: public sprout::hash_detail::enable_hash_value
{};
} // namespace hash_detail
//
// hash_value
//
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::hash_detail::basic_numbers<T>::type
hash_value(T);
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::hash_detail::long_numbers<T>::type
hash_value(T);
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::hash_detail::ulong_numbers<T>::type
hash_value(T);
// template<typename T>
// inline SPROUT_CONSTEXPR typename sprout::hash_detail::float_numbers<T>::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<std::is_pointer<typename std::remove_reference<T>::type>::value>::type
@ -153,26 +104,51 @@ namespace sprout {
//
// hash_value
//
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::hash_detail::basic_numbers<T>::type
hash_value(T v) {
inline SPROUT_CONSTEXPR std::size_t hash_value(bool v) {
return static_cast<std::size_t>(v);
}
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::hash_detail::long_numbers<T>::type
hash_value(T v) {
inline SPROUT_CONSTEXPR std::size_t hash_value(char v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned char v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(signed char v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(char16_t v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(char32_t v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(wchar_t v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(short v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned short v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(int v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned int v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(long v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(unsigned long v) {
return static_cast<std::size_t>(v);
}
inline SPROUT_CONSTEXPR std::size_t hash_value(long long v) {
return sprout::hash_detail::hash_value_signed(v);
}
template<typename T>
inline SPROUT_CONSTEXPR typename sprout::hash_detail::ulong_numbers<T>::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<typename T>
// inline SPROUT_CONSTEXPR typename sprout::hash_detail::float_numbers<T>::type
// hash_value(T v) {
// return sprout::hash_detail::hash_value_float(v);
// }
template<
typename T,
typename sprout::enabler_if<std::is_pointer<typename std::remove_reference<T>::type>::value>::type = sprout::enabler

6
sprout/generator.hpp Normal file
View file

@ -0,0 +1,6 @@
#ifndef SPROUT_GENERATOR_HPP
#define SPROUT_GENERATOR_HPP
#include <sprout/generator/functions.hpp>
#endif // #ifndef SPROUT_GENERATOR_HPP

View file

@ -0,0 +1,7 @@
#ifndef SPROUT_GENERATOR_FUNCTIONS_HPP
#define SPROUT_GENERATOR_FUNCTIONS_HPP
#include <sprout/generator/generated_value.hpp>
#include <sprout/generator/next_generator.hpp>
#endif // #ifndef SPROUT_GENERATOR_FUNCTIONS_HPP

View file

@ -0,0 +1,209 @@
#ifndef SPROUT_GENERATOR_GENERATED_VALUE_HPP
#define SPROUT_GENERATOR_GENERATED_VALUE_HPP
#include <utility>
#include <type_traits>
#include <sprout/utility/forward.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/tuple/tuple/get.hpp>
namespace sprout_generator_detail {
struct not_found_adl_generated_value {};
sprout_generator_detail::not_found_adl_generated_value generated_value(...);
template<typename T>
struct has_mem_generated_value_test {
public:
template<
typename U = T,
typename = decltype(std::declval<U>().generated_value())
>
static std::true_type test(int);
static std::false_type test(...);
};
template<typename T>
struct has_mem_generated_value
: public decltype(sprout_generator_detail::has_mem_generated_value_test<T>::test(0))
{};
template<typename T>
struct has_adl_generated_value_test {
public:
template<
typename U = T,
typename sprout::enabler_if<
!std::is_same<decltype(generated_value(std::declval<U>())), sprout_generator_detail::not_found_adl_generated_value>::value
>::type = sprout::enabler
>
static std::true_type test(int);
static std::false_type test(...);
};
template<typename T>
struct has_adl_generated_value
: public decltype(sprout_generator_detail::has_adl_generated_value_test<T>::test(0))
{};
template<typename T>
struct has_tuple_get_generated_value_test {
public:
template<
typename U = T,
typename = decltype(sprout::tuples::get<0>(std::declval<U>()))
>
static std::true_type test(int);
static std::false_type test(...);
};
template<typename T>
struct has_tuple_get_generated_value
: public decltype(sprout_generator_detail::has_tuple_get_generated_value_test<T>::test(0))
{};
template<typename T, typename Enable = void>
struct select_mem_generated_value;
template<typename T>
struct select_mem_generated_value<
T,
typename std::enable_if<sprout_generator_detail::has_mem_generated_value<T>::value>::type
>
: public std::true_type
{};
template<typename T>
struct select_mem_generated_value<
T,
typename std::enable_if<!sprout_generator_detail::has_mem_generated_value<T>::value>::type
>
: public std::false_type
{};
template<typename T, typename Enable = void>
struct select_adl_generated_value;
template<typename T>
struct select_adl_generated_value<
T,
typename std::enable_if<
sprout_generator_detail::has_adl_generated_value<T>::value
&& !sprout_generator_detail::has_mem_generated_value<T>::value
>::type
>
: public std::true_type
{};
template<typename T>
struct select_adl_generated_value<
T,
typename std::enable_if<!(
sprout_generator_detail::has_adl_generated_value<T>::value
&& !sprout_generator_detail::has_mem_generated_value<T>::value
)>::type
>
: public std::false_type
{};
template<typename T, typename Enable = void>
struct select_tuple_get_generated_value;
template<typename T>
struct select_tuple_get_generated_value<
T,
typename std::enable_if<
sprout_generator_detail::has_tuple_get_generated_value<T>::value
&& !sprout_generator_detail::has_mem_generated_value<T>::value
&& !sprout_generator_detail::has_adl_generated_value<T>::value
>::type
>
: public std::true_type
{};
template<typename T>
struct select_tuple_get_generated_value<
T,
typename std::enable_if<!(
sprout_generator_detail::has_tuple_get_generated_value<T>::value
&& !sprout_generator_detail::has_mem_generated_value<T>::value
&& !sprout_generator_detail::has_adl_generated_value<T>::value
)>::type
>
: public std::false_type
{};
template<typename T, typename = void>
struct noexcept_generated_value;
template<typename T>
struct noexcept_generated_value<T, typename std::enable_if<sprout_generator_detail::select_mem_generated_value<T>::value>::type>
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(std::declval<T>().generated_value(), false)>
{};
template<typename T>
struct noexcept_generated_value<T, typename std::enable_if<sprout_generator_detail::select_adl_generated_value<T>::value>::type>
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(generated_value(std::declval<T>()), false)>
{};
template<typename T>
struct noexcept_generated_value<T, typename std::enable_if<sprout_generator_detail::select_tuple_get_generated_value<T>::value>::type>
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(sprout::tuples::get<0>(std::declval<T>()), false)>
{};
template<typename T, typename = void>
struct generated_value_result;
template<typename T>
struct generated_value_result<T, typename std::enable_if<sprout_generator_detail::select_mem_generated_value<T>::value>::type> {
public:
typedef decltype(std::declval<T>().generated_value()) type;
};
template<typename T>
struct generated_value_result<T, typename std::enable_if<sprout_generator_detail::select_adl_generated_value<T>::value>::type> {
public:
typedef decltype(generated_value(std::declval<T>())) type;
};
template<typename T>
struct generated_value_result<T, typename std::enable_if<sprout_generator_detail::select_tuple_get_generated_value<T>::value>::type> {
public:
typedef decltype(sprout::tuples::get<0>(std::declval<T>())) type;
};
template<
typename T,
typename sprout::enabler_if<sprout_generator_detail::select_mem_generated_value<T>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result<T>::type
generated_value_impl(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value<T>::value))
{
return sprout::forward<T>(t).generated_value();
}
template<
typename T,
typename sprout::enabler_if<sprout_generator_detail::select_adl_generated_value<T>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result<T>::type
generated_value_impl(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value<T>::value))
{
return generated_value(sprout::forward<T>(t));
}
template<
typename T,
typename sprout::enabler_if<sprout_generator_detail::select_tuple_get_generated_value<T>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result<T>::type
generated_value_impl(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value<T>::value))
{
return sprout::tuples::get<0>(sprout::forward<T>(t));
}
} // namespace sprout_generator_detail
namespace sprout {
namespace generators {
//
// generated_value
//
template<typename T>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::generated_value_result<T>::type
generated_value(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_generated_value<T>::value))
{
return sprout_generator_detail::generated_value_impl(sprout::forward<T>(t));
}
} // namespace generators
using sprout::generators::generated_value;
} // namespace sprout
#endif // #ifndef SPROUT_GENERATOR_GENERATED_VALUE_HPP

View file

@ -0,0 +1,209 @@
#ifndef SPROUT_GENERATOR_NEXT_GENERATOR_HPP
#define SPROUT_GENERATOR_NEXT_GENERATOR_HPP
#include <utility>
#include <type_traits>
#include <sprout/utility/forward.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/tuple/tuple/get.hpp>
namespace sprout_generator_detail {
struct not_found_adl_next_generator {};
sprout_generator_detail::not_found_adl_next_generator next_generator(...);
template<typename T>
struct has_mem_next_generator_test {
public:
template<
typename U = T,
typename = decltype(std::declval<U>().next_generator())
>
static std::true_type test(int);
static std::false_type test(...);
};
template<typename T>
struct has_mem_next_generator
: public decltype(sprout_generator_detail::has_mem_next_generator_test<T>::test(0))
{};
template<typename T>
struct has_adl_next_generator_test {
public:
template<
typename U = T,
typename sprout::enabler_if<
!std::is_same<decltype(next_generator(std::declval<U>())), sprout_generator_detail::not_found_adl_next_generator>::value
>::type = sprout::enabler
>
static std::true_type test(int);
static std::false_type test(...);
};
template<typename T>
struct has_adl_next_generator
: public decltype(sprout_generator_detail::has_adl_next_generator_test<T>::test(0))
{};
template<typename T>
struct has_tuple_get_next_generator_test {
public:
template<
typename U = T,
typename = decltype(sprout::tuples::get<1>(std::declval<U>()))
>
static std::true_type test(int);
static std::false_type test(...);
};
template<typename T>
struct has_tuple_get_next_generator
: public decltype(sprout_generator_detail::has_tuple_get_next_generator_test<T>::test(0))
{};
template<typename T, typename Enable = void>
struct select_mem_next_generator;
template<typename T>
struct select_mem_next_generator<
T,
typename std::enable_if<sprout_generator_detail::has_mem_next_generator<T>::value>::type
>
: public std::true_type
{};
template<typename T>
struct select_mem_next_generator<
T,
typename std::enable_if<!sprout_generator_detail::has_mem_next_generator<T>::value>::type
>
: public std::false_type
{};
template<typename T, typename Enable = void>
struct select_adl_next_generator;
template<typename T>
struct select_adl_next_generator<
T,
typename std::enable_if<
sprout_generator_detail::has_adl_next_generator<T>::value
&& !sprout_generator_detail::has_mem_next_generator<T>::value
>::type
>
: public std::true_type
{};
template<typename T>
struct select_adl_next_generator<
T,
typename std::enable_if<!(
sprout_generator_detail::has_adl_next_generator<T>::value
&& !sprout_generator_detail::has_mem_next_generator<T>::value
)>::type
>
: public std::false_type
{};
template<typename T, typename Enable = void>
struct select_tuple_get_next_generator;
template<typename T>
struct select_tuple_get_next_generator<
T,
typename std::enable_if<
sprout_generator_detail::has_tuple_get_next_generator<T>::value
&& !sprout_generator_detail::has_mem_next_generator<T>::value
&& !sprout_generator_detail::has_adl_next_generator<T>::value
>::type
>
: public std::true_type
{};
template<typename T>
struct select_tuple_get_next_generator<
T,
typename std::enable_if<!(
sprout_generator_detail::has_tuple_get_next_generator<T>::value
&& !sprout_generator_detail::has_mem_next_generator<T>::value
&& !sprout_generator_detail::has_adl_next_generator<T>::value
)>::type
>
: public std::false_type
{};
template<typename T, typename = void>
struct noexcept_next_generator;
template<typename T>
struct noexcept_next_generator<T, typename std::enable_if<sprout_generator_detail::select_mem_next_generator<T>::value>::type>
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(std::declval<T>().next_generator(), false)>
{};
template<typename T>
struct noexcept_next_generator<T, typename std::enable_if<sprout_generator_detail::select_adl_next_generator<T>::value>::type>
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(next_generator(std::declval<T>()), false)>
{};
template<typename T>
struct noexcept_next_generator<T, typename std::enable_if<sprout_generator_detail::select_tuple_get_next_generator<T>::value>::type>
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(sprout::tuples::get<1>(std::declval<T>()), false)>
{};
template<typename T, typename = void>
struct next_generator_result;
template<typename T>
struct next_generator_result<T, typename std::enable_if<sprout_generator_detail::select_mem_next_generator<T>::value>::type> {
public:
typedef decltype(std::declval<T>().next_generator()) type;
};
template<typename T>
struct next_generator_result<T, typename std::enable_if<sprout_generator_detail::select_adl_next_generator<T>::value>::type> {
public:
typedef decltype(next_generator(std::declval<T>())) type;
};
template<typename T>
struct next_generator_result<T, typename std::enable_if<sprout_generator_detail::select_tuple_get_next_generator<T>::value>::type> {
public:
typedef decltype(sprout::tuples::get<1>(std::declval<T>())) type;
};
template<
typename T,
typename sprout::enabler_if<sprout_generator_detail::select_mem_next_generator<T>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result<T>::type
next_generator_impl(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator<T>::value))
{
return sprout::forward<T>(t).next_generator();
}
template<
typename T,
typename sprout::enabler_if<sprout_generator_detail::select_adl_next_generator<T>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result<T>::type
next_generator_impl(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator<T>::value))
{
return next_generator(sprout::forward<T>(t));
}
template<
typename T,
typename sprout::enabler_if<sprout_generator_detail::select_tuple_get_next_generator<T>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result<T>::type
next_generator_impl(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator<T>::value))
{
return sprout::tuples::get<1>(sprout::forward<T>(t));
}
} // namespace sprout_generator_detail
namespace sprout {
namespace generators {
//
// next_generator
//
template<typename T>
inline SPROUT_CONSTEXPR typename sprout_generator_detail::next_generator_result<T>::type
next_generator(T&& t)
SPROUT_NOEXCEPT_EXPR((sprout_generator_detail::noexcept_next_generator<T>::value))
{
return sprout_generator_detail::next_generator_impl(sprout::forward<T>(t));
}
} // namespace generators
using sprout::generators::next_generator;
} // namespace sprout
#endif // #ifndef SPROUT_GENERATOR_NEXT_GENERATOR_HPP

View file

@ -4,5 +4,7 @@
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/predefined.hpp>
#include <sprout/iterator/adaptor.hpp>
#include <sprout/iterator/wave.hpp>
#endif // #ifndef SPROUT_ITERATOR_HPP

View file

@ -0,0 +1,11 @@
#ifndef SPROUT_ITERATOR_ADAPTOR_HPP
#define SPROUT_ITERATOR_ADAPTOR_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/reverse_iterator.hpp>
#include <sprout/iterator/transform_iterator.hpp>
#include <sprout/iterator/filter_iterator.hpp>
#include <sprout/iterator/counting_iterator.hpp>
#include <sprout/iterator/size_enum_iterator.hpp>
#endif // #ifndef SPROUT_ITERATOR_ADAPTOR_HPP

View file

@ -0,0 +1,202 @@
#ifndef SPROUT_ITERATOR_FILTER_ITERATOR_HPP
#define SPROUT_ITERATOR_FILTER_ITERATOR_HPP
#include <iterator>
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/iterator/next.hpp>
#include <sprout/iterator/prev.hpp>
#include <sprout/algorithm/find_if.hpp>
namespace sprout {
//
// filter_iterator
//
template<typename Predicate, typename Iterator>
class filter_iterator
: public std::iterator<
typename std::conditional<
std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value,
std::bidirectional_iterator_tag,
typename std::iterator_traits<Iterator>::iterator_category
>::type,
typename std::iterator_traits<Iterator>::value_type,
typename std::iterator_traits<Iterator>::difference_type,
typename std::iterator_traits<Iterator>::pointer,
typename std::iterator_traits<Iterator>::reference
>
{
public:
typedef Predicate predicate_type;
typedef Iterator iterator_type;
typedef typename std::conditional<
std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value,
std::bidirectional_iterator_tag,
typename std::iterator_traits<Iterator>::iterator_category
>::type iterator_category;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef typename std::iterator_traits<Iterator>::pointer pointer;
typedef typename std::iterator_traits<Iterator>::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<typename U>
SPROUT_CONSTEXPR filter_iterator(filter_iterator<Predicate, U> const& it)
: current(it.current)
, last(it.last)
, pred(it.pred)
{}
template<typename U>
filter_iterator& operator=(filter_iterator<Predicate, U> 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<typename Predicate, typename Iterator1, typename Iterator2>
inline SPROUT_CONSTEXPR bool operator==(
sprout::filter_iterator<Predicate, Iterator1> const& lhs,
sprout::filter_iterator<Predicate, Iterator2> const& rhs
)
{
return lhs.base() == rhs.base();
}
template<typename Predicate, typename Iterator1, typename Iterator2>
inline SPROUT_CONSTEXPR bool operator!=(
sprout::filter_iterator<Predicate, Iterator1> const& lhs,
sprout::filter_iterator<Predicate, Iterator2> const& rhs
)
{
return !(lhs == rhs);
}
//
// make_filter_iterator
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::filter_iterator<Predicate, Iterator>
make_filter_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) {
return sprout::filter_iterator<Predicate, Iterator>(pred, it, last);
}
//
// swap
//
template<typename Predicate, typename Iterator>
inline void swap(sprout::filter_iterator<Predicate, Iterator>& lhs, sprout::filter_iterator<Predicate, Iterator>& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) {
lhs.swap(rhs);
}
//
// next
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::filter_iterator<Predicate, Iterator> next(
sprout::filter_iterator<Predicate, Iterator> const& it
)
{
return it.next();
}
//
// prev
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::filter_iterator<Predicate, Iterator> prev(
sprout::filter_iterator<Predicate, Iterator> const& it
)
{
return it.prev();
}
} // namespace sprout
#endif // SPROUT_ITERATOR_FILTER_ITERATOR_HPP

View file

@ -25,8 +25,7 @@ namespace sprout {
void*
)
{
using std::next;
return next(sprout::forward<ForwardIterator>(it));
return std::next(sprout::forward<ForwardIterator>(it));
}
template<typename RandomAccessIterator>
@ -48,8 +47,7 @@ namespace sprout {
void*
)
{
using std::next;
return next(sprout::forward<ForwardIterator>(it), n);
return std::next(sprout::forward<ForwardIterator>(it), n);
}
} // namespace detail
//

View file

@ -25,8 +25,7 @@ namespace sprout {
void*
)
{
using std::prev;
return prev(sprout::forward<BidirectionalIterator>(it));
return std::prev(sprout::forward<BidirectionalIterator>(it));
}
template<typename RandomAccessIterator>
@ -48,8 +47,7 @@ namespace sprout {
void*
)
{
using std::prev;
return prev(sprout::forward<BidirectionalIterator>(it), n);
return std::prev(sprout::forward<BidirectionalIterator>(it), n);
}
} // namespace detail
//

View file

@ -182,6 +182,15 @@ namespace sprout {
return it + n;
}
//
// make_reverse_iterator
//
template<typename Iterator>
inline SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator>
make_reverse_iterator(Iterator it) {
return sprout::reverse_iterator<Iterator>(it);
}
//
// swap
//

10
sprout/iterator/wave.hpp Normal file
View file

@ -0,0 +1,10 @@
#ifndef SPROUT_ITERATOR_WAVE_HPP
#define SPROUT_ITERATOR_WAVE_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/sinusoid_iterator.hpp>
#include <sprout/iterator/sawtooth_iterator.hpp>
#include <sprout/iterator/triangle_iterator.hpp>
#include <sprout/iterator/square_iterator.hpp>
#endif // #ifndef SPROUT_ITERATOR_WAVE_HPP

View file

@ -9,7 +9,7 @@
namespace sprout {
template<typename Container>
inline SPROUT_CONSTEXPR std::size_t hash_value(sprout::pit<Container> const& v) {
return sprout::hash_range(v.begin(), v.end());
return sprout::to_hash(v.elem);
}
} // namespace sprout

View file

@ -6,7 +6,8 @@
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/reverse_iterator.hpp>
#include <sprout/iterator/value_iterator.hpp>
namespace sprout {

View file

@ -3,7 +3,11 @@
#include <sprout/config.hpp>
#include <sprout/range/adaptor/copied.hpp>
#include <sprout/range/adaptor/reversed.hpp>
#include <sprout/range/adaptor/transformed.hpp>
#include <sprout/range/adaptor/replaced.hpp>
#include <sprout/range/adaptor/replaced_if.hpp>
#include <sprout/range/adaptor/filtered.hpp>
#include <sprout/range/adaptor/counting.hpp>
#include <sprout/range/adaptor/deep_copied.hpp>
#include <sprout/range/adaptor/sized.hpp>

View file

@ -0,0 +1,139 @@
#ifndef SPROUT_RANGE_ADAPTOR_FILTERED_HPP
#define SPROUT_RANGE_ADAPTOR_FILTERED_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/pit.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/filter_iterator.hpp>
#include <sprout/range/range_container.hpp>
#include <sprout/range/algorithm/copy.hpp>
#include <sprout/type_traits/lvalue_reference.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/lvalue_forward.hpp>
namespace sprout {
namespace adaptors {
//
// filtered_range
//
template<typename Predicate, typename Range>
class filtered_range
: public sprout::range::range_container<
sprout::filter_iterator<
Predicate,
typename sprout::container_traits<Range>::iterator
>
>
, public sprout::detail::container_nosy_static_size<Range>
, public sprout::detail::container_nosy_fixed_size<Range>
{
public:
typedef Predicate predicate_type;
typedef Range range_type;
typedef sprout::range::range_container<
sprout::filter_iterator<
Predicate,
typename sprout::container_traits<Range>::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<typename Predicate>
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<typename Predicate>
SPROUT_CONSTEXPR sprout::adaptors::filter_holder<Predicate>
operator()(Predicate pred) {
return sprout::adaptors::filter_holder<Predicate>(pred);
}
};
//
// filtered
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::adaptors::filtered_forwarder filtered{};
} // anonymous-namespace
//
// operator|
//
template<typename Range, typename Predicate>
inline SPROUT_CONSTEXPR sprout::adaptors::filtered_range<
Predicate,
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>
operator|(Range&& lhs, sprout::adaptors::filter_holder<Predicate> const& rhs) {
return sprout::adaptors::filtered_range<
Predicate,
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>(
rhs.predicate(),
sprout::lvalue_forward<Range>(lhs)
);
}
} // namespace adaptors
//
// container_construct_traits
//
template<typename Predicate, typename Range>
struct container_construct_traits<sprout::adaptors::filtered_range<Predicate, Range> > {
public:
typedef typename sprout::container_construct_traits<Range>::copied_type copied_type;
public:
template<typename Cont>
static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) {
return sprout::range::fixed::copy(sprout::forward<Cont>(cont), sprout::pit<copied_type>());
}
template<typename... Args>
static SPROUT_CONSTEXPR copied_type make(Args&&... args) {
return sprout::make<copied_type>(sprout::forward<Args>(args)...);
}
template<typename Cont, typename... Args>
static SPROUT_CONSTEXPR copied_type remake(
Cont&& cont,
typename sprout::container_traits<sprout::adaptors::filtered_range<Predicate, Range> >::difference_type size,
Args&&... args
)
{
return sprout::remake<copied_type>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
}
};
} // namespace sprout
#endif // #ifndef SPROUT_RANGE_ADAPTOR_FILTERED_HPP

View file

@ -0,0 +1,160 @@
#ifndef SPROUT_RANGE_ADAPTOR_REPLACED_HPP
#define SPROUT_RANGE_ADAPTOR_REPLACED_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/pit.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/transform_iterator.hpp>
#include <sprout/range/range_container.hpp>
#include <sprout/range/algorithm/copy.hpp>
#include <sprout/type_traits/lvalue_reference.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/lvalue_forward.hpp>
namespace sprout {
namespace adaptors {
namespace detail {
template<typename T>
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<typename Range>
class replaced_range
: public sprout::range::range_container<
sprout::transform_iterator<
sprout::adaptors::detail::replace_value<typename sprout::container_traits<Range>::value_type>,
typename sprout::container_traits<Range>::iterator
>
>
, public sprout::detail::container_nosy_static_size<Range>
, public sprout::detail::container_nosy_fixed_size<Range>
{
public:
typedef Range range_type;
typedef sprout::range::range_container<
sprout::transform_iterator<
sprout::adaptors::detail::replace_value<typename sprout::container_traits<Range>::value_type>,
typename sprout::container_traits<Range>::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<typename T>
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<typename T>
SPROUT_CONSTEXPR sprout::adaptors::replace_holder<T>
operator()(T const& old_value, T const& new_value) {
return sprout::adaptors::replace_holder<T>(old_value, new_value);
}
};
//
// replaced
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::adaptors::replaced_forwarder replaced{};
} // anonymous-namespace
//
// operator|
//
template<typename Range, typename T>
inline SPROUT_CONSTEXPR sprout::adaptors::replaced_range<
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>
operator|(Range&& lhs, sprout::adaptors::replace_holder<T> const& rhs) {
return sprout::adaptors::replaced_range<
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>(
sprout::lvalue_forward<Range>(lhs),
rhs.old_value(),
rhs.new_value()
);
}
} // namespace adaptors
//
// container_construct_traits
//
template<typename Range>
struct container_construct_traits<sprout::adaptors::replaced_range<Range> > {
public:
typedef typename sprout::container_construct_traits<Range>::copied_type copied_type;
public:
template<typename Cont>
static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) {
return sprout::range::fixed::copy(sprout::forward<Cont>(cont), sprout::pit<copied_type>());
}
template<typename... Args>
static SPROUT_CONSTEXPR copied_type make(Args&&... args) {
return sprout::make<copied_type>(sprout::forward<Args>(args)...);
}
template<typename Cont, typename... Args>
static SPROUT_CONSTEXPR copied_type remake(
Cont&& cont,
typename sprout::container_traits<sprout::adaptors::replaced_range<Range> >::difference_type size,
Args&&... args
)
{
return sprout::remake<copied_type>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
}
};
} // namespace sprout
#endif // #ifndef SPROUT_RANGE_ADAPTOR_REPLACED_HPP

View file

@ -0,0 +1,164 @@
#ifndef SPROUT_RANGE_ADAPTOR_REPLACED_IF_HPP
#define SPROUT_RANGE_ADAPTOR_REPLACED_IF_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/pit.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/transform_iterator.hpp>
#include <sprout/range/range_container.hpp>
#include <sprout/range/algorithm/copy.hpp>
#include <sprout/type_traits/lvalue_reference.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/lvalue_forward.hpp>
namespace sprout {
namespace adaptors {
namespace detail {
template<typename Predicate, typename T>
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<typename Predicate, typename Range>
class replaced_if_range
: public sprout::range::range_container<
sprout::transform_iterator<
sprout::adaptors::detail::replace_value_if<Predicate, typename sprout::container_traits<Range>::value_type>,
typename sprout::container_traits<Range>::iterator
>
>
, public sprout::detail::container_nosy_static_size<Range>
, public sprout::detail::container_nosy_fixed_size<Range>
{
public:
typedef Range range_type;
typedef sprout::range::range_container<
sprout::transform_iterator<
sprout::adaptors::detail::replace_value_if<Predicate, typename sprout::container_traits<Range>::value_type>,
typename sprout::container_traits<Range>::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<typename Predicate, typename T>
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<typename Predicate, typename T>
SPROUT_CONSTEXPR sprout::adaptors::replace_if_holder<Predicate, T>
operator()(Predicate pred, T const& new_value) {
return sprout::adaptors::replace_if_holder<Predicate, T>(pred, new_value);
}
};
//
// replaced_if
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::adaptors::replaced_if_forwarder replaced_if{};
} // anonymous-namespace
//
// operator|
//
template<typename Range, typename Predicate, typename T>
inline SPROUT_CONSTEXPR sprout::adaptors::replaced_if_range<
Predicate,
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>
operator|(Range&& lhs, sprout::adaptors::replace_if_holder<Predicate, T> const& rhs) {
return sprout::adaptors::replaced_if_range<
Predicate,
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>(
sprout::lvalue_forward<Range>(lhs),
rhs.predicate(),
rhs.new_value()
);
}
} // namespace adaptors
//
// container_construct_traits
//
template<typename Predicate, typename Range>
struct container_construct_traits<sprout::adaptors::replaced_if_range<Predicate, Range> > {
public:
typedef typename sprout::container_construct_traits<Range>::copied_type copied_type;
public:
template<typename Cont>
static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) {
return sprout::range::fixed::copy(sprout::forward<Cont>(cont), sprout::pit<copied_type>());
}
template<typename... Args>
static SPROUT_CONSTEXPR copied_type make(Args&&... args) {
return sprout::make<copied_type>(sprout::forward<Args>(args)...);
}
template<typename Cont, typename... Args>
static SPROUT_CONSTEXPR copied_type remake(
Cont&& cont,
typename sprout::container_traits<sprout::adaptors::replaced_if_range<Predicate, Range> >::difference_type size,
Args&&... args
)
{
return sprout::remake<copied_type>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
}
};
} // namespace sprout
#endif // #ifndef SPROUT_RANGE_ADAPTOR_REPLACED_IF_HPP

View file

@ -0,0 +1,106 @@
#ifndef SPROUT_RANGE_ADAPTOR_REVERSED_HPP
#define SPROUT_RANGE_ADAPTOR_REVERSED_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/pit.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/reverse_iterator.hpp>
#include <sprout/range/range_container.hpp>
#include <sprout/range/algorithm/copy.hpp>
#include <sprout/type_traits/lvalue_reference.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/lvalue_forward.hpp>
namespace sprout {
namespace adaptors {
//
// reversed_range
//
template<typename Range>
class reversed_range
: public sprout::range::range_container<
sprout::reverse_iterator<
typename sprout::container_traits<Range>::iterator
>
>
, public sprout::detail::container_nosy_static_size<Range>
, public sprout::detail::container_nosy_fixed_size<Range>
{
public:
typedef Range range_type;
typedef sprout::range::range_container<
sprout::reverse_iterator<
typename sprout::container_traits<Range>::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<typename Range>
inline SPROUT_CONSTEXPR sprout::adaptors::reversed_range<
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>
operator|(Range&& lhs, sprout::adaptors::reversed_forwarder) {
return sprout::adaptors::reversed_range<
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
>(
sprout::lvalue_forward<Range>(lhs)
);
}
} // namespace adaptors
//
// container_construct_traits
//
template<typename Range>
struct container_construct_traits<sprout::adaptors::reversed_range<Range> > {
public:
typedef typename sprout::container_construct_traits<Range>::copied_type copied_type;
public:
template<typename Cont>
static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) {
return sprout::range::fixed::copy(sprout::forward<Cont>(cont), sprout::pit<copied_type>());
}
template<typename... Args>
static SPROUT_CONSTEXPR copied_type make(Args&&... args) {
return sprout::make<copied_type>(sprout::forward<Args>(args)...);
}
template<typename Cont, typename... Args>
static SPROUT_CONSTEXPR copied_type remake(
Cont&& cont,
typename sprout::container_traits<sprout::adaptors::reversed_range<Range> >::difference_type size,
Args&&... args
)
{
return sprout::remake<copied_type>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
}
};
} // namespace sprout
#endif // #ifndef SPROUT_RANGE_ADAPTOR_REVERSED_HPP

View file

@ -1,14 +1,725 @@
#ifndef SPROUT_RATIONAL_HPP
#define SPROUT_RATIONAL_HPP
#include <limits>
#include <utility>
#include <stdexcept>
#include <ios>
#include <iostream>
#include <sprout/config.hpp>
#include <sprout/rational/rational.hpp>
#include <sprout/rational/arithmetic.hpp>
#include <sprout/rational/comparison.hpp>
#include <sprout/rational/io.hpp>
#include <sprout/rational/conversion.hpp>
#include <sprout/rational/exceptions.hpp>
#include <sprout/rational/hash.hpp>
#include <sprout/rational/values.hpp>
#include <sprout/cstdlib/abs.hpp>
#include <sprout/math/gcd.hpp>
#include <sprout/detail/call_traits.hpp>
#include <sprout/detail/io/ios_state.hpp>
namespace sprout {
//
// bad_rational
//
class bad_rational
: public std::domain_error
{
public:
explicit bad_rational()
: std::domain_error("bad rational: zero denominator")
{}
};
template<typename IntType>
class rational;
namespace detail {
struct rational_private_constructor_tag {};
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType> make_rational(
typename sprout::detail::call_traits<IntType>::param_type n,
typename sprout::detail::call_traits<IntType>::param_type d,
sprout::detail::rational_private_constructor_tag
);
} // namespace detail
namespace detail {
template<typename IntType>
class rational_impl {
protected:
typedef IntType int_type;
typedef typename sprout::detail::call_traits<IntType>::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<typename IntType>
class rational
: private sprout::detail::rational_impl<IntType>
{
static_assert(std::numeric_limits<IntType>::is_specialized, "std::numeric_limits<IntType>::is_specialized");
public:
typedef IntType int_type;
typedef typename sprout::detail::call_traits<IntType>::param_type param_type;
private:
struct private_constructor_tag {};
typedef sprout::detail::rational_impl<IntType> 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<IntType> sprout::detail::make_rational<IntType>(
typename sprout::detail::call_traits<IntType>::param_type n,
typename sprout::detail::call_traits<IntType>::param_type d,
sprout::detail::rational_private_constructor_tag
);
};
namespace detail {
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType> make_rational(
typename sprout::detail::call_traits<IntType>::param_type n,
typename sprout::detail::call_traits<IntType>::param_type d,
sprout::detail::rational_private_constructor_tag
)
{
return sprout::rational<IntType>(
n, d,
typename sprout::rational<IntType>::private_constructor_tag()
);
}
} // namespace detail
//
// operator+
// operator-
//
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator+(rational<IntType> const& r) {
return r;
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator-(rational<IntType> const& r) {
return sprout::detail::make_rational<IntType>(
-r.numerator(), r.denominator(),
sprout::detail::rational_private_constructor_tag()
);
}
//
// operator+
// operator-
// operator*
// operator/
//
namespace detail {
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_add_impl_3(
sprout::rational<IntType> const& rhs,
IntType g, IntType den, IntType num
)
{
return sprout::detail::make_rational<IntType>(
num / g, den * (rhs.denominator() / g),
sprout::detail::rational_private_constructor_tag()
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_add_impl_2(
sprout::rational<IntType> const& rhs,
IntType g, IntType den, IntType num
)
{
return rational_add_impl_3(
rhs,
sprout::math::gcd(num, g), den, num
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_add_impl_1(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs,
IntType g, IntType den
)
{
return rational_add_impl_2(
rhs,
g, den, lhs.numerator() * (rhs.denominator() / g) + rhs.numerator() * den
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_add_impl(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs,
IntType g
)
{
return rational_add_impl_1(
lhs, rhs,
g, lhs.denominator() / g
);
}
} // namespace detail
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator+(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return sprout::detail::rational_add_impl(
lhs, rhs,
sprout::math::gcd(lhs.denominator(), rhs.denominator())
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator+(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return lhs + sprout::rational<IntType>(rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator+(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return sprout::rational<IntType>(lhs) + rhs;
}
namespace detail {
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_sub_impl_3(
sprout::rational<IntType> const& rhs,
IntType g, IntType den, IntType num
)
{
return sprout::detail::make_rational<IntType>(
num / g, den * (rhs.denominator() / g),
sprout::detail::rational_private_constructor_tag()
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_sub_impl_2(
sprout::rational<IntType> const& rhs,
IntType g, IntType den, IntType num
)
{
return rational_sub_impl_3(
rhs,
sprout::math::gcd(num, g), den, num
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_sub_impl_1(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs,
IntType g, IntType den
)
{
return rational_sub_impl_2(
rhs,
g, den, lhs.numerator() * (rhs.denominator() / g) - rhs.numerator() * den
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_sub_impl(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs,
IntType g
)
{
return rational_sub_impl_1(
lhs, rhs,
g, lhs.denominator() / g
);
}
} // namespace detail
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator-(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return sprout::detail::rational_sub_impl(
lhs, rhs,
sprout::math::gcd(lhs.denominator(), rhs.denominator())
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator-(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return lhs - sprout::rational<IntType>(rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator-(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return sprout::rational<IntType>(lhs) - rhs;
}
namespace detail {
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_mul_impl(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs,
IntType gcd1, IntType gcd2
)
{
return sprout::detail::make_rational<IntType>(
(lhs.numerator() / gcd1) * (rhs.numerator() / gcd2),
(lhs.denominator() / gcd2) * (rhs.denominator() / gcd1),
sprout::detail::rational_private_constructor_tag()
);
}
} // namespace detail
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator*(sprout::rational<IntType> const& lhs, sprout::rational<IntType> 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<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator*(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return lhs * sprout::rational<IntType>(rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator*(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return sprout::rational<IntType>(lhs) * rhs;
}
namespace detail {
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_div_impl_1(IntType num, IntType den) {
return den < IntType(0) ? sprout::detail::make_rational<IntType>(
-num, -den,
sprout::detail::rational_private_constructor_tag()
)
: sprout::detail::make_rational<IntType>(
num, den,
sprout::detail::rational_private_constructor_tag()
)
;
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
rational_div_impl(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> 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<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator/(sprout::rational<IntType> const& lhs, sprout::rational<IntType> 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<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator/(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return lhs / sprout::rational<IntType>(rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
operator/(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return sprout::rational<IntType>(lhs) / rhs;
}
//
// operator==
// operator!=
//
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator==(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return lhs.numerator() == rhs.numerator() && lhs.denominator() == rhs.denominator();
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator==(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return lhs.denominator() == IntType(1) && lhs.numerator() == rhs;
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator==(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return rhs == lhs;
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator!=(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return !(lhs == rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator!=(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return !(lhs == rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator!=(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return !(lhs == rhs);
}
//
// operator<
// operator>
// operator<=
// operator>=
//
namespace detail {
template<typename IntType>
inline SPROUT_CONSTEXPR bool
rational_less_impl_2(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> 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<bool>(reverse ^ 1)
: sprout::detail::rational_less_impl_2(
lhs, rhs,
r1, d1 / r1, d1 % r1,
r2, d2 / r2, d2 % r2,
reverse ^ 1
)
;
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
rational_less_impl_1(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> 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<typename IntType>
inline SPROUT_CONSTEXPR bool
rational_less_impl(
sprout::rational<IntType> const& lhs, sprout::rational<IntType> 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<typename IntType>
inline SPROUT_CONSTEXPR bool
rational_less_impl(
sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::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<typename IntType>
inline SPROUT_CONSTEXPR bool
operator<(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return sprout::detail::rational_less_impl(
lhs, rhs,
lhs.denominator(), lhs.numerator() / lhs.denominator(), lhs.numerator() % lhs.denominator()
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator<(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return sprout::detail::rational_less_impl(
lhs, rhs,
lhs.numerator() / lhs.denominator(), lhs.numerator() % lhs.denominator()
);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator<(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return lhs != rhs && !(rhs < lhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator>(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return rhs < lhs;
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator>(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return rhs < lhs;
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator>(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return rhs < lhs;
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator<=(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return !(rhs < lhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator<=(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return !(rhs < lhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator<=(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return !(rhs < lhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator>=(sprout::rational<IntType> const& lhs, sprout::rational<IntType> const& rhs) {
return !(lhs < rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator>=(sprout::rational<IntType> const& lhs, typename sprout::rational<IntType>::param_type rhs) {
return !(lhs < rhs);
}
template<typename IntType>
inline SPROUT_CONSTEXPR bool
operator>=(typename sprout::rational<IntType>::param_type lhs, sprout::rational<IntType> const& rhs) {
return !(lhs < rhs);
}
//
// operator>>
// operator<<
//
template<typename Elem, typename Traits, typename IntType>
inline std::basic_istream<Elem, Traits>&
operator>>(std::basic_istream<Elem, Traits>& lhs, sprout::rational<IntType>& 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<typename Elem, typename Traits, typename IntType>
inline std::basic_ostream<Elem, Traits>&
operator<<(std::basic_ostream<Elem, Traits>& lhs, sprout::rational<IntType> const& rhs) {
return lhs << rhs.numerator() << Elem('/') << rhs.denominator();
}
//
// rational_cast
//
template<typename T, typename IntType>
inline SPROUT_CONSTEXPR T
rational_cast(sprout::rational<IntType> const& src) {
return static_cast<T>(src.numerator()) / static_cast<T>(src.denominator());
}
//
// abs
//
template<typename IntType>
inline SPROUT_CONSTEXPR sprout::rational<IntType>
abs(sprout::rational<IntType> const& x) {
return x.numerator() >= IntType(0) ? x
: sprout::detail::make_rational<IntType>(
-x.numerator(), x.denominator(),
sprout::detail::rational_private_constructor_tag()
)
;
}
} // namespace sprout
#endif // SPROUT_RATIONAL_HPP

95
sprout/tpp/algorithm.hpp Normal file
View file

@ -0,0 +1,95 @@
#ifndef SPROUT_TPP_ALGORITHM_HPP
#define SPROUT_TPP_ALGORITHM_HPP
#include <type_traits>
#include <sprout/config.hpp>
namespace sprout {
namespace tpp {
namespace detail {
template<bool Head, bool... Tail>
struct all_of_impl;
template<>
struct all_of_impl<true>
: public std::true_type
{};
template<>
struct all_of_impl<false>
: public std::false_type
{};
template<bool... Tail>
struct all_of_impl<true, Tail...>
: public std::integral_constant<bool, sprout::tpp::detail::all_of_impl<Tail...>::value>
{};
template<bool... Tail>
struct all_of_impl<false, Tail...>
: public std::false_type
{};
} // namespace detail
//
// all_of
//
template<bool... Values>
struct all_of
: public sprout::tpp::detail::all_of_impl<Values...>
{};
namespace detail {
template<bool Head, bool... Tail>
struct any_of_impl;
template<>
struct any_of_impl<true>
: public std::true_type
{};
template<>
struct any_of_impl<false>
: public std::false_type
{};
template<bool... Tail>
struct any_of_impl<true, Tail...>
: public std::true_type
{};
template<bool... Tail>
struct any_of_impl<false, Tail...>
: public std::integral_constant<bool, sprout::tpp::detail::any_of_impl<Tail...>::value>
{};
} // namespace detail
//
// any_of
//
template<bool... Values>
struct any_of
: public sprout::tpp::detail::any_of_impl<Values...>
{};
namespace detail {
template<bool Head, bool... Tail>
struct none_of_impl;
template<>
struct none_of_impl<true>
: public std::false_type
{};
template<>
struct none_of_impl<false>
: public std::true_type
{};
template<bool... Tail>
struct none_of_impl<true, Tail...>
: public std::false_type
{};
template<bool... Tail>
struct none_of_impl<false, Tail...>
: public std::integral_constant<bool, sprout::tpp::detail::none_of_impl<Tail...>::value>
{};
} // namespace detail
//
// none_of
//
template<bool... Values>
struct none_of
: public sprout::tpp::detail::none_of_impl<Values...>
{};
} // namespace tpp
} // namespace sprout
#endif // #ifndef SPROUT_TPP_ALGORITHM_HPP

View file

@ -1,7 +1,6 @@
#ifndef SPROUT_UTILITY_PAIR_HPP
#define SPROUT_UTILITY_PAIR_HPP
#include <cstddef>
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
@ -10,7 +9,6 @@
#include <sprout/utility/move.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/functional/ref.hpp>
#include <sprout/functional/hash/hash.hpp>
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
@ -145,7 +143,7 @@ namespace sprout {
// swap
//
template<class T1, class T2>
inline void swap(sprout::pair<T1, T2>& x, sprout::pair<T1, T2>& y) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(x.swap(y))) {
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(x.swap(y))) {
x.swap(y);
}
@ -166,14 +164,6 @@ namespace sprout {
sprout::forward<T2>(y)
);
}
//
// hash_value
//
template<typename T1, typename T2>
inline SPROUT_CONSTEXPR std::size_t hash_value(sprout::pair<T1, T2> const& v) {
return sprout::hash_values(v.first, v.second);
}
} // namespace sprout
namespace sprout {

View file

@ -7,7 +7,8 @@
#include <stdexcept>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/iterator.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/reverse_iterator.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
# include <sprout/iterator/index_iterator.hpp>

View file

@ -0,0 +1,108 @@
#ifndef SPROUT_WEED_PARSER_DIRECTIVE_REPLACE_HPP
#define SPROUT_WEED_PARSER_DIRECTIVE_REPLACE_HPP
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/weed/unused.hpp>
#include <sprout/weed/parser_result.hpp>
#include <sprout/weed/expr/make_terminal_or_expr.hpp>
#include <sprout/weed/expr/eval.hpp>
#include <sprout/weed/parser/parser_base.hpp>
#include <sprout/weed/traits/expr/terminal_or_expr_of.hpp>
#include <sprout/weed/traits/parser/attribute_of.hpp>
namespace sprout {
namespace weed {
//
// replace_p
//
template<typename Parser, typename T>
struct replace_p
: public sprout::weed::parser_base
{
public:
typedef T value_type;
template<typename Context, typename Iterator>
struct attribute {
public:
typedef value_type type;
};
template<typename Context, typename Iterator>
struct result {
public:
typedef sprout::weed::parser_result<Iterator, typename attribute<Context, Iterator>::type> type;
};
private:
typedef typename sprout::weed::traits::terminal_or_expr_of<Parser>::type expr_type;
private:
expr_type expr_;
value_type value_;
private:
template<typename Context, typename Iterator, typename Result>
SPROUT_CONSTEXPR typename result<Context, Iterator>::type call(
Iterator first,
Result const& res
) const
{
typedef typename result<Context, Iterator>::type result_type;
typedef typename attribute<Context, Iterator>::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<typename Context, typename Iterator>
SPROUT_CONSTEXPR typename result<Context, Iterator>::type operator()(
Iterator first,
Iterator last,
Context const& ctx
) const
{
return call<Context>(first, sprout::weed::eval(expr_, ctx));
}
};
//
// replace_d
//
template<typename T>
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<typename Parser>
SPROUT_CONSTEXPR sprout::weed::replace_p<Parser, value_type> operator[](Parser const& p) const {
return sprout::weed::replace_p<Parser, value_type>(p, value_);
}
};
//
// replace_g
//
struct replace_g {
public:
template<typename T>
SPROUT_CONSTEXPR sprout::weed::replace_d<T> operator()(T const& value) const {
return sprout::weed::replace_d<T>(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

View file

@ -142,6 +142,29 @@ namespace testspr {
SPROUT_CONSTEXPR T operator()(T const& lhs, T const& rhs) const { return lhs + rhs; }
};
//
// gen_iota
//
template<typename T>
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
//