rewrite sprout::algorithm::join performance

This commit is contained in:
bolero-MURAKAMI 2012-05-22 01:06:13 +09:00
parent 0ceabb5b9b
commit 1ea9d30e2a
145 changed files with 1359 additions and 364 deletions

View file

@ -26,9 +26,9 @@ struct fizzbuzz{
constexpr result_type
operator ()(int n) const{
return n % 15 == 0 ? sprout::to_string("FizzBuzz")
: n % 3 == 0 ? sprout::to_string("Fizz")
: n % 5 == 0 ? sprout::to_string("Buzz")
: sprout::to_string(n);
: n % 3 == 0 ? sprout::to_string("Fizz")
: n % 5 == 0 ? sprout::to_string("Buzz")
: sprout::to_string(n);
}
};

View file

@ -135,4 +135,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_BOGO_SORT_CPP

View file

@ -177,4 +177,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_BOGO_SORT_RESULT_CPP

View file

@ -104,4 +104,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COPY_CPP

View file

@ -104,4 +104,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COPY_BACKWARD_CPP

View file

@ -110,4 +110,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COPY_IF_CPP

View file

@ -104,4 +104,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COPY_N_CPP

View file

@ -74,4 +74,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_FILL_CPP

View file

@ -78,4 +78,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_FILL_N_CPP

View file

@ -78,4 +78,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_GENERATE_CPP

View file

@ -82,4 +82,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_GENERATE_N_CPP

View file

@ -133,4 +133,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_INPLACE_MERGE_CPP

View file

@ -125,4 +125,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_MAKE_HEAP_CPP

View file

@ -133,4 +133,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_MAKE_PARTIAL_HEAP_CPP

View file

@ -221,4 +221,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_MERGE_CPP

View file

@ -133,4 +133,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_NTH_ELEMENT_CPP

View file

@ -133,4 +133,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_PARTIAL_SORT_CPP

View file

@ -74,4 +74,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_PARTITION_CPP

View file

@ -110,4 +110,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_PARTITION_COPY_CPP

View file

@ -70,4 +70,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_POP_HEAP_CPP

View file

@ -125,4 +125,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_PUSH_HEAP_CPP

View file

@ -74,4 +74,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REMOVE_CPP

View file

@ -110,4 +110,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REMOVE_COPY_CPP

View file

@ -110,4 +110,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REMOVE_COPY_IF_CPP

View file

@ -74,4 +74,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REMOVE_IF_CPP

View file

@ -78,4 +78,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REPLACE_CPP

View file

@ -116,4 +116,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REPLACE_COPY_CPP

View file

@ -116,4 +116,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REPLACE_COPY_IF_CPP

View file

@ -78,4 +78,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REPLACE_IF_CPP

View file

@ -70,4 +70,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REBERSE_CPP

View file

@ -104,4 +104,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_REBERSE_COPY_CPP

View file

@ -74,4 +74,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_ROTATE_CPP

View file

@ -110,4 +110,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_ROTATE_COPY_CPP

View file

@ -221,4 +221,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SET_DIFFERENCE_CPP

View file

@ -221,4 +221,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SET_INTERSECTION_CPP

View file

@ -221,4 +221,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SET_SYMMETRIC_DIFFERENCE_CPP

View file

@ -221,4 +221,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SET_UNION_CPP

View file

@ -76,4 +76,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SHUFFLE_CPP

View file

@ -97,4 +97,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SHUFFLE_RESULT_CPP

View file

@ -125,4 +125,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SORT_CPP

View file

@ -125,4 +125,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SORT_HEAP_CPP

View file

@ -74,4 +74,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_STABLE_PARTITION_CPP

View file

@ -110,4 +110,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_STABLE_PARTITION_COPY_CPP

View file

@ -125,4 +125,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_STABLE_SORT_CPP

View file

@ -78,4 +78,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SWAP_ELEMENT_CPP

View file

@ -116,4 +116,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_SWAP_ELEMENT_COPY_CPP

View file

@ -208,4 +208,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_TRANSFORM_CPP

View file

@ -125,4 +125,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_UNIQUE_CPP

View file

@ -195,4 +195,3 @@ namespace testspr {
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_UNIQUE_COPY_CPP

View file

@ -3,6 +3,5 @@
#include <sprout/config.hpp>
#include <sprout/algorithm/string/join.hpp>
#include <sprout/algorithm/string/join2.hpp>
#endif // #ifndef SPROUT_ALGORITHM_STRING_HPP

View file

@ -1,22 +1,88 @@
#ifndef SPROUT_ALGORITHM_STRING_JOIN_HPP
#define SPROUT_ALGORITHM_STRING_JOIN_HPP
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/pit.hpp>
#include <sprout/iterator/traits.hpp>
#include <sprout/utility/enabler_if.hpp>
#include <sprout/range/adaptor/size_enumed.hpp>
#include <sprout/range/algorithm/lower_bound.hpp>
#include <sprout/range/numeric/partial_sum.hpp>
#include <sprout/weed/traits/type/is_c_str.hpp>
namespace sprout {
namespace algorithm {
namespace detail {
template<typename String, typename = void>
struct string_size;
template<typename String>
struct string_size<
String,
typename std::enable_if<sprout::weed::traits::is_c_str<String>::value>::type
>
: public std::integral_constant<
typename sprout::container_traits<String>::size_type,
sprout::container_traits<String>::static_size - 1
>
{};
template<typename String>
struct string_size<
String,
typename std::enable_if<!sprout::weed::traits::is_c_str<String>::value>::type
>
: public std::integral_constant<
typename sprout::container_traits<String>::size_type,
sprout::container_traits<String>::static_size
>
{};
template<
typename String,
typename sprout::enabler_if<sprout::weed::traits::is_c_str<String>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::container_traits<String>::difference_type
str_size(String const& str) {
return sprout::size(str) - 1;
}
template<
typename String,
typename sprout::enabler_if<!sprout::weed::traits::is_c_str<String>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::container_traits<String>::difference_type
str_size(String const& str) {
return sprout::size(str);
}
} // namespace detail
namespace result_of {
//
// join
//
template<typename ContainerContainer>
template<typename ContainerContainer, typename Separator = void>
struct join {
public:
typedef typename sprout::container_transform_traits<
typename sprout::container_traits<ContainerContainer>::value_type
>::template rebind_size<
sprout::container_traits<
typename sprout::container_traits<ContainerContainer>::value_type
>::static_size
? (sprout::container_traits<
typename sprout::container_traits<ContainerContainer>::value_type
>::static_size
+ sprout::algorithm::detail::string_size<Separator>::value
)
* sprout::container_traits<ContainerContainer>::static_size
- sprout::algorithm::detail::string_size<Separator>::value
: 0
>::type type;
};
template<typename ContainerContainer>
struct join<ContainerContainer, void> {
public:
typedef typename sprout::container_transform_traits<
typename sprout::container_traits<ContainerContainer>::value_type
@ -30,31 +96,80 @@ namespace sprout {
} // namespace result_of
namespace detail {
template<typename Result, typename ContainerInputIterator, typename... Args>
template<typename Result, typename ContIterator, typename SizeIterator, typename Sizes>
inline SPROUT_CONSTEXPR typename sprout::container_traits<Result>::value_type
join_impl_ra_2(
ContIterator first_cont,
SizeIterator found,
Sizes const& sizes,
sprout::index_t idx
)
{
typedef typename sprout::container_traits<Result>::value_type value_type;
return found == sizes.end() ? value_type()
: sprout::begin(first_cont[found - sizes.begin()])[idx - (found != sizes.begin() ? found[-1] : 0)]
;
}
template<typename Result, typename ContIterator, sprout::index_t... Indexes, typename Sizes>
inline SPROUT_CONSTEXPR Result
join_impl_ra_1(
ContIterator first_cont,
sprout::index_tuple<Indexes...>,
Sizes const& sizes
)
{
return sprout::make<Result>(
sprout::algorithm::detail::join_impl_ra_2<Result>(
first_cont,
sprout::range::lower_bound(sizes, Indexes + 1),
sizes,
Indexes
)...
);
}
template<typename Result, typename ContainerContainer>
inline SPROUT_CONSTEXPR Result
join_impl_ra(ContainerContainer const& cont_cont) {
typedef typename sprout::container_traits<Result>::difference_type size_type;
typedef sprout::array<
size_type,
sprout::container_traits<ContainerContainer>::static_size
> sizes_type;
return sprout::algorithm::detail::join_impl_ra_1<Result>(
sprout::begin(cont_cont),
sprout::index_range<0, sprout::container_traits<Result>::static_size>::make(),
sprout::range::partial_sum(
cont_cont | sprout::adaptors::size_enumed,
sprout::pit<sizes_type>()
)
);
}
template<typename Result, typename ContIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args),
Result
>::type join_impl(
ContainerInputIterator first_cont,
ContainerInputIterator last_cont,
ContIterator first_cont,
ContIterator last_cont,
Args const&... args
);
template<typename Result, typename ContainerInputIterator, typename... Args>
template<typename Result, typename ContIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size != sizeof...(Args),
Result
>::type join_impl(
ContainerInputIterator first_cont,
ContainerInputIterator last_cont,
ContIterator first_cont,
ContIterator last_cont,
Args const&... args
);
template<typename Result, typename ContainerInputIterator, typename InputIterator, typename... Args>
template<typename Result, typename ContIterator, typename InputIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args),
Result
>::type join_impl_1(
ContainerInputIterator first_cont,
ContainerInputIterator last_cont,
ContIterator first_cont,
ContIterator last_cont,
InputIterator first,
InputIterator last,
Args const&... args
@ -62,63 +177,344 @@ namespace sprout {
{
return sprout::make<Result>(args...);
}
template<typename Result, typename ContainerInputIterator, typename InputIterator, typename... Args>
template<typename Result, typename ContIterator, typename InputIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size != sizeof...(Args),
Result
>::type join_impl_1(
ContainerInputIterator first_cont,
ContainerInputIterator last_cont,
ContIterator first_cont,
ContIterator last_cont,
InputIterator first,
InputIterator last,
Args const&... args
)
{
return first != last
? sprout::algorithm::detail::join_impl_1<Result>(first_cont, last_cont, sprout::next(first), last, args..., *first)
? sprout::algorithm::detail::join_impl_1<Result>(
first_cont, last_cont,
sprout::next(first), last,
args..., *first
)
: sprout::algorithm::detail::join_impl<Result>(sprout::next(first_cont), last_cont, args...)
;
}
template<typename Result, typename ContainerInputIterator, typename... Args>
template<typename Result, typename ContIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args),
Result
>::type join_impl(
ContainerInputIterator first_cont,
ContainerInputIterator last_cont,
ContIterator first_cont,
ContIterator last_cont,
Args const&... args
)
{
return sprout::make<Result>(args...);
}
template<typename Result, typename ContainerInputIterator, typename... Args>
template<typename Result, typename ContIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size != sizeof...(Args),
Result
>::type join_impl(
ContainerInputIterator first_cont,
ContainerInputIterator last_cont,
ContIterator first_cont,
ContIterator last_cont,
Args const&... args
)
{
return first_cont != last_cont
? sprout::algorithm::detail::join_impl_1<Result>(first_cont, last_cont, sprout::begin(*first_cont), sprout::end(*first_cont), args...)
? sprout::algorithm::detail::join_impl_1<Result>(
first_cont, last_cont,
sprout::begin(*first_cont), sprout::end(*first_cont),
args...
)
: sprout::make<Result>(args...)
;
}
template<
typename ContainerContainer,
typename sprout::enabler_if<
sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator
>::value
&& sprout::is_random_access_iterator<
typename sprout::container_traits<
typename sprout::container_traits<ContainerContainer const>::value_type
>::iterator
>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type
join(ContainerContainer const& cont_cont) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type;
return sprout::algorithm::detail::join_impl_ra<result_type>(cont_cont);
}
template<
typename ContainerContainer,
typename sprout::enabler_if<!(
sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator
>::value
&& sprout::is_random_access_iterator<
typename sprout::container_traits<
typename sprout::container_traits<ContainerContainer const>::value_type
>::iterator
>::value
)>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type
join(ContainerContainer const& cont_cont) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type;
return sprout::algorithm::detail::join_impl<result_type>(
sprout::begin(cont_cont),
sprout::end(cont_cont)
);
}
} // namespace detail
//
// join
//
template<typename ContainerContainer>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type join(
ContainerContainer const& cont_cont
)
{
return sprout::algorithm::detail::join_impl<typename sprout::algorithm::result_of::join<ContainerContainer>::type>(
sprout::begin(cont_cont),
sprout::end(cont_cont)
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type
join(ContainerContainer const& cont_cont) {
return sprout::algorithm::detail::join(cont_cont);
}
namespace detail {
template<typename Result, typename ContIterator, typename SepIterator, typename SizeIterator, typename Sizes>
inline SPROUT_CONSTEXPR typename sprout::container_traits<Result>::value_type
join_impl_ra_2(
ContIterator first_cont,
SepIterator first,
SizeIterator found,
Sizes const& sizes,
sprout::index_t idx
)
{
typedef typename sprout::container_traits<Result>::value_type value_type;
return found == sizes.end() ? value_type()
: (found - sizes.begin()) % 2 ? first[idx - found[-1]]
: sprout::begin(first_cont[(found - sizes.begin()) / 2])[idx - (found != sizes.begin() ? found[-1] : 0)]
;
}
template<typename Result, typename ContIterator, typename SepIterator, sprout::index_t... Indexes, typename Sizes>
inline SPROUT_CONSTEXPR Result
join_impl_ra_1(
ContIterator first_cont,
SepIterator first,
sprout::index_tuple<Indexes...>,
Sizes const& sizes
)
{
return sprout::make<Result>(
sprout::algorithm::detail::join_impl_ra_2<Result>(
first_cont,
first,
sprout::range::lower_bound(sizes, Indexes + 1),
sizes,
Indexes
)...
);
}
template<typename Result, typename ContainerContainer, typename Separator>
inline SPROUT_CONSTEXPR Result
join_impl_ra(ContainerContainer const& cont_cont, Separator const& separator) {
typedef typename sprout::container_traits<Result>::difference_type size_type;
typedef sprout::array<
size_type,
sprout::container_traits<ContainerContainer>::static_size
? sprout::container_traits<ContainerContainer>::static_size * 2 - 1
: 0
> sizes_type;
return sprout::algorithm::detail::join_impl_ra_1<Result>(
sprout::begin(cont_cont),
sprout::begin(separator),
sprout::index_range<0, sprout::container_traits<Result>::static_size>::make(),
sprout::range::partial_sum(
cont_cont | sprout::adaptors::size_enumed(sprout::algorithm::detail::str_size(separator), true),
sprout::pit<sizes_type>()
)
);
}
template<typename Result, typename ContIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args),
Result
>::type join_impl(
ContIterator first_cont,
ContIterator last_cont,
Args const&... args
);
template<typename Result, typename ContIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size != sizeof...(Args),
Result
>::type join_impl(
ContIterator first_cont,
ContIterator last_cont,
Args const&... args
);
template<typename Result, typename ContIterator, typename SepIterator, typename InputIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args),
Result
>::type join_impl_1(
ContIterator first_cont,
ContIterator last_cont,
SepIterator sep_first,
SepIterator sep_last,
bool sep,
InputIterator first,
InputIterator last,
Args const&... args
)
{
return sprout::make<Result>(args...);
}
template<typename Result, typename ContIterator, typename SepIterator, typename InputIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size != sizeof...(Args),
Result
>::type join_impl_1(
ContIterator first_cont,
ContIterator last_cont,
SepIterator sep_first,
SepIterator sep_last,
bool sep,
InputIterator first,
InputIterator last,
Args const&... args
)
{
return first != last
? sprout::algorithm::detail::join_impl_1<Result>(
first_cont, last_cont,
sep_first, sep_last,
sep,
sprout::next(first), last,
args..., *first
)
: sep
? sprout::algorithm::detail::join_impl<Result>(
sprout::next(first_cont), last_cont,
sep_first, sep_last,
false,
args...
)
: sprout::algorithm::detail::join_impl<Result>(
first_cont, last_cont,
sep_first, sep_last,
true,
args...
)
;
}
template<typename Result, typename ContIterator, typename SepIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args),
Result
>::type join_impl(
ContIterator first_cont,
ContIterator last_cont,
SepIterator sep_first,
SepIterator sep_last,
bool sep,
Args const&... args
)
{
return sprout::make<Result>(args...);
}
template<typename Result, typename ContIterator, typename SepIterator, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size != sizeof...(Args),
Result
>::type join_impl(
ContIterator first_cont,
ContIterator last_cont,
SepIterator sep_first,
SepIterator sep_last,
bool sep,
Args const&... args
)
{
return first_cont != last_cont
? sep
? sprout::algorithm::detail::join_impl_1<Result>(
first_cont, last_cont,
sep_first, sep_last,
sep,
sep_first, sep_last,
args...
)
: sprout::algorithm::detail::join_impl_1<Result>(
first_cont, last_cont,
sep_first, sep_last,
sep,
sprout::begin(*first_cont), sprout::end(*first_cont),
args...
)
: sprout::make<Result>(args...)
;
}
template<
typename ContainerContainer,
typename Separator,
typename sprout::enabler_if<
sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator
>::value
&& sprout::is_random_access_iterator<
typename sprout::container_traits<
typename sprout::container_traits<ContainerContainer const>::value_type
>::iterator
>::value
&& sprout::is_random_access_iterator<
typename sprout::container_traits<Separator const>::iterator
>::value
>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type
join(ContainerContainer const& cont_cont, Separator const& separator) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type;
return sprout::algorithm::detail::join_impl_ra<result_type>(cont_cont, separator);
}
template<
typename ContainerContainer,
typename Separator,
typename sprout::enabler_if<!(
sprout::is_random_access_iterator<
typename sprout::container_traits<ContainerContainer const>::iterator
>::value
&& sprout::is_random_access_iterator<
typename sprout::container_traits<
typename sprout::container_traits<ContainerContainer const>::value_type
>::iterator
>::value
&& sprout::is_random_access_iterator<
typename sprout::container_traits<Separator const>::iterator
>::value
)>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer>::type
join(ContainerContainer const& cont_cont, Separator const& separator) {
typedef typename sprout::algorithm::result_of::join<ContainerContainer>::type result_type;
return sprout::algorithm::detail::join_impl<result_type>(
sprout::begin(cont_cont),
sprout::end(cont_cont),
sprout::begin(separator),
sprout::end(separator),
false
);
}
} // namespace detail
//
// join
//
template<typename ContainerContainer, typename Separator>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join<ContainerContainer, Separator>::type
join(ContainerContainer const& cont_cont, Separator const& separator) {
return sprout::algorithm::detail::join(cont_cont, separator);
}
} // namespace algorithm
} // namespace sprout

View file

@ -1,108 +0,0 @@
#ifndef SPROUT_ALGORITHM_STRING_JOIN2_HPP
#define SPROUT_ALGORITHM_STRING_JOIN2_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/operation/fixed/append_back.hpp>
namespace sprout {
namespace algorithm {
namespace result_of {
//
// join2
//
template<typename ContainerContainer, typename Separator>
struct join2 {
public:
typedef typename sprout::container_transform_traits<
typename sprout::container_traits<ContainerContainer>::value_type
>::template rebind_size<
sprout::container_traits<ContainerContainer>::static_size != 0
? (
sprout::container_traits<
typename sprout::container_traits<ContainerContainer>::value_type
>::static_size
+ (sprout::container_traits<ContainerContainer>::static_size - 1) * (
sprout::container_traits<Separator>::static_size
+ sprout::container_traits<
typename sprout::container_traits<ContainerContainer>::value_type
>::static_size
)
)
: 0
>::type type;
};
} // namespace result_of
namespace detail {
template<typename Result, typename ContainerIterator, typename Separator, typename Container>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size == sprout::container_traits<Result>::static_size),
Result
>::type join2_impl_1(
ContainerIterator first,
ContainerIterator last,
Separator const& separator,
Container const& current
)
{
return current;
}
template<typename Result, typename ContainerIterator, typename Separator, typename Container>
inline SPROUT_CONSTEXPR typename std::enable_if<
(sprout::container_traits<Container>::static_size < sprout::container_traits<Result>::static_size),
Result
>::type join2_impl_1(
ContainerIterator first,
ContainerIterator last,
Separator const& separator,
Container const& current
)
{
return sprout::algorithm::detail::join2_impl_1<Result>(
sprout::next(first),
last,
separator,
sprout::fixed::append_back(sprout::fixed::append_back(current, separator), *first)
);
}
template<typename Result, typename ContainerIterator, typename Separator>
inline SPROUT_CONSTEXPR Result join2_impl(
ContainerIterator first,
ContainerIterator last,
Separator const& separator
)
{
return first != last
? sprout::algorithm::detail::join2_impl_1<Result>(
sprout::next(first),
last,
separator,
*first
)
: sprout::make<Result>()
;
}
} // namespace detail
//
// join2
//
template<typename ContainerContainer, typename Separator>
inline SPROUT_CONSTEXPR typename sprout::algorithm::result_of::join2<ContainerContainer, Separator>::type join2(
ContainerContainer const& cont_cont,
Separator const& separator
)
{
return sprout::algorithm::detail::join2_impl<typename sprout::algorithm::result_of::join2<ContainerContainer, Separator>::type>(
sprout::begin(cont_cont),
sprout::end(cont_cont),
separator
);
}
} // namespace algorithm
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_STRING_JOIN2_HPP

View file

@ -317,12 +317,12 @@ namespace sprout {
template<typename... As>
SPROUT_CONSTEXPR typename sprout::breed::result_of::funop<
expr(As const&...),
expr,
expr,
sprout::breed::default_domain
>::type operator()(As const&... args) const {
return sprout::breed::result_of::funop<
expr(As const&...),
expr,
expr,
sprout::breed::default_domain
>::call(*this, args...);
}
@ -444,12 +444,12 @@ namespace sprout {
template<typename... As>
SPROUT_CONSTEXPR typename sprout::breed::result_of::funop<
expr(As const&...),
expr,
expr,
sprout::breed::default_domain
>::type operator()(As const&... args) const {
return sprout::breed::result_of::funop<
expr(As const&...),
expr,
expr,
sprout::breed::default_domain
>::call(*this, args...);
}

View file

@ -146,7 +146,7 @@ namespace sprout {
template<typename This, typename Expr>
struct result<This(Expr const&)>
{
public:
public:
typedef Extends<Expr> type;
};
public:

View file

@ -8,52 +8,52 @@ namespace sprout {
namespace breed {
namespace tagns_ {
namespace tag {
struct terminal {};
struct unary_plus {};
struct negate {};
struct dereference {};
struct complement {};
struct address_of {};
struct logical_not {};
struct pre_inc {};
struct pre_dec {};
struct post_inc {};
struct post_dec {};
struct shift_left {};
struct shift_right {};
struct multiplies {};
struct divides {};
struct modulus {};
struct plus {};
struct minus {};
struct less {};
struct greater {};
struct less_equal {};
struct greater_equal {};
struct equal_to {};
struct not_equal_to {};
struct logical_or {};
struct logical_and {};
struct bitwise_and {};
struct bitwise_or {};
struct bitwise_xor {};
struct comma {};
struct mem_ptr {};
struct assign {};
struct shift_left_assign {};
struct shift_right_assign {};
struct multiplies_assign {};
struct divides_assign {};
struct modulus_assign {};
struct plus_assign {};
struct minus_assign {};
struct bitwise_and_assign {};
struct bitwise_or_assign {};
struct bitwise_xor_assign {};
struct subscript {};
struct member {};
struct if_else_ {};
struct function {};
struct terminal {};
struct unary_plus {};
struct negate {};
struct dereference {};
struct complement {};
struct address_of {};
struct logical_not {};
struct pre_inc {};
struct pre_dec {};
struct post_inc {};
struct post_dec {};
struct shift_left {};
struct shift_right {};
struct multiplies {};
struct divides {};
struct modulus {};
struct plus {};
struct minus {};
struct less {};
struct greater {};
struct less_equal {};
struct greater_equal {};
struct equal_to {};
struct not_equal_to {};
struct logical_or {};
struct logical_and {};
struct bitwise_and {};
struct bitwise_or {};
struct bitwise_xor {};
struct comma {};
struct mem_ptr {};
struct assign {};
struct shift_left_assign {};
struct shift_right_assign {};
struct multiplies_assign {};
struct divides_assign {};
struct modulus_assign {};
struct plus_assign {};
struct minus_assign {};
struct bitwise_and_assign {};
struct bitwise_or_assign {};
struct bitwise_xor_assign {};
struct subscript {};
struct member {};
struct if_else_ {};
struct function {};
} // namespace tag
} // namespace tagns_
} // namespace breed

View file

@ -11,7 +11,7 @@
namespace sprout {
namespace breed {
namespace detail {
namespace detail {
template<
typename Grammar,
typename Expr,
@ -32,10 +32,10 @@ namespace sprout {
public:
typedef sprout::breed::list<
typename Grammar::template breed_child<Indexes>::type::template impl<
typename sprout::breed::result_of::child_c<Expr, Indexes>::type,
State,
Data
>::result_type...
typename sprout::breed::result_of::child_c<Expr, Indexes>::type,
State,
Data
>::result_type...
> type;
};
public:

View file

@ -93,7 +93,7 @@ namespace sprout {
struct otherwise
: public sprout::breed::when<sprout::breed::_, Fun>
{};
//
//
// external_transforms
//
template<typename... Args>

View file

@ -10,7 +10,8 @@ namespace sprout {
// empty
//
template<typename Container>
inline SPROUT_CONSTEXPR bool empty(Container const& cont) {
inline SPROUT_CONSTEXPR bool
empty(Container const& cont) {
return sprout::begin(cont) == sprout::end(cont);
}
} // namespace sprout

View file

@ -12,7 +12,8 @@ namespace sprout {
// size
//
template<typename Container>
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::difference_type size(Container const& cont) {
inline SPROUT_CONSTEXPR typename sprout::container_traits<Container>::difference_type
size(Container const& cont) {
return NS_SSCRISK_CEL_OR_SPROUT::distance(sprout::begin(cont), sprout::end(cont));
}
} // namespace sprout

View file

@ -179,4 +179,3 @@ namespace sprout {
} // namespace sprout
#endif // #ifndef SPROUT_DETAIL_INTEGER_HPP

View file

@ -63,4 +63,3 @@ namespace sprout {
} // namespace sprout
#endif // #ifndef SPROUT_DETAIL_INTEGER_INTEGER_MASK_HPP

View file

@ -297,7 +297,7 @@ namespace sprout {
SPROUT_CONSTEXPR Result call_cv(sprout::tuples::tuple<Args...>&& args, sprout::index_tuple<Indexes...>) const volatile {
return f_(sprout::detail::mu<BoundArgs>()(sprout::detail::volget<Indexes>(bound_args_), args)...);
}
public:
public:
template<typename... Args>
explicit SPROUT_CONSTEXPR binder(Functor const& f, Args&&... args)
: f_(f)

View file

@ -13,7 +13,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x & y;
return x & y;
}
};
} // namespace sprout

View file

@ -12,7 +12,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x) const {
return !x;
return !x;
}
};
} // namespace sprout

View file

@ -13,7 +13,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x | y;
return x | y;
}
};
} // namespace sprout

View file

@ -13,7 +13,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x ^ y;
return x ^ y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x / y;
return x / y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x == y;
return x == y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x > y;
return x > y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x >= y;
return x >= y;
}
};
} // namespace sprout

View file

@ -5,4 +5,3 @@
#include <sprout/functional/hash/hash.hpp>
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP

View file

@ -14,4 +14,3 @@ namespace sprout {
} // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP

View file

@ -270,4 +270,3 @@ namespace sprout {
} //namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_HPP

View file

@ -33,4 +33,3 @@ namespace sprout {
} // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP

View file

@ -14,4 +14,3 @@ namespace sprout {
} // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP

View file

@ -6,4 +6,3 @@
#include <sprout/string/hash.hpp>
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP

View file

@ -14,4 +14,3 @@ namespace sprout {
} // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP

View file

@ -5,4 +5,3 @@
#include <sprout/functional/hash/hash_fwd.hpp>
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x < y;
return x < y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x <= y;
return x <= y;
}
};
} // namespace sprout

View file

@ -13,7 +13,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x && y;
return x && y;
}
};
} // namespace sprout

View file

@ -12,7 +12,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x) const {
return !x;
return !x;
}
};
} // namespace sprout

View file

@ -13,7 +13,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x || y;
return x || y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x - y;
return x - y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x % y;
return x % y;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x, T const& y) const {
return x * y;
return x * y;
}
};
} // namespace sprout

View file

@ -14,7 +14,7 @@ namespace sprout {
typedef T result_type;
public:
SPROUT_CONSTEXPR T operator()(T const& x) const {
return -x;
return -x;
}
};
} // namespace sprout

View file

@ -15,7 +15,7 @@ namespace sprout {
typedef bool result_type;
public:
SPROUT_CONSTEXPR bool operator()(T const& x, T const& y) const {
return x != y;
return x != y;
}
};
} // namespace sprout

View file

@ -34,7 +34,7 @@ namespace sprout {
typedef typename T::first_argument_type first_argument_type;
typedef typename T::second_argument_type second_argument_type;
};
template<typename T>
template<typename T>
struct reference_wrapper_base_impl<true, true, T>
: public sprout::weak_result_type<T>
{
@ -152,9 +152,9 @@ namespace sprout {
SPROUT_CONSTEXPR T& get() const SPROUT_NOEXCEPT {
return *t_;
}
SPROUT_CONSTEXPR T* get_pointer() const SPROUT_NOEXCEPT {
return t_;
}
SPROUT_CONSTEXPR T* get_pointer() const SPROUT_NOEXCEPT {
return t_;
}
// invocation
template<typename... Args>
SPROUT_CONSTEXPR typename std::result_of<T& (Args&&...)>::type

View file

@ -0,0 +1,447 @@
#ifndef SPROUT_ITERATOR_SIZE_ENUM_ITERATOR_HPP
#define SPROUT_ITERATOR_SIZE_ENUM_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/iterator/distance.hpp>
#include <sprout/container/size.hpp>
namespace sprout {
//
// size_enum_iterator
//
template<typename Iterator, bool Separated = false>
class size_enum_iterator
: public std::iterator<
typename std::iterator_traits<Iterator>::iterator_category,
typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type,
typename std::iterator_traits<Iterator>::difference_type,
typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type*,
typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type
>
{
public:
typedef Iterator iterator_type;
typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
typedef typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type value_type;
typedef value_type reference;
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
typedef value_type* pointer;
protected:
iterator_type current;
public:
size_enum_iterator() = default;
size_enum_iterator(size_enum_iterator const&) = default;
explicit SPROUT_CONSTEXPR size_enum_iterator(iterator_type it)
: current(it)
{}
template<typename U>
SPROUT_CONSTEXPR size_enum_iterator(size_enum_iterator<U> const& it)
: current(it.current)
{}
template<typename U>
size_enum_iterator& operator=(size_enum_iterator<U> const& it) {
size_enum_iterator temp(it);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR iterator_type base() const {
return current;
}
SPROUT_CONSTEXPR bool is_separator() const {
return false;
}
SPROUT_CONSTEXPR reference operator*() const {
return sprout::size(*current);
}
SPROUT_CONSTEXPR pointer operator->() const {
return &sprout::size(*current);
}
size_enum_iterator& operator++() {
++current;
return *this;
}
size_enum_iterator operator++(int) {
size_enum_iterator result(*this);
++current;
return result;
}
size_enum_iterator& operator--() {
--current;
return *this;
}
size_enum_iterator operator--(int) {
size_enum_iterator temp(*this);
--current;
return temp;
}
SPROUT_CONSTEXPR size_enum_iterator operator+(difference_type n) const {
return size_enum_iterator(current + n);
}
SPROUT_CONSTEXPR size_enum_iterator operator-(difference_type n) const {
return size_enum_iterator(current - n);
}
size_enum_iterator& operator+=(difference_type n) {
size_enum_iterator temp(current + n);
temp.swap(*this);
return *this;
}
size_enum_iterator& operator-=(difference_type n) {
size_enum_iterator temp(current - n);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return sprout::size(current[n]);
}
SPROUT_CONSTEXPR size_enum_iterator next() const {
return size_enum_iterator(sprout::next(current));
}
SPROUT_CONSTEXPR size_enum_iterator prev() const {
return size_enum_iterator(sprout::prev(current));
}
void swap(size_enum_iterator& other) {
using std::swap;
swap(current, other.current);
}
};
//
// size_enum_iterator
//
template<typename Iterator>
class size_enum_iterator<Iterator, true>
: public std::iterator<
typename std::iterator_traits<Iterator>::iterator_category,
typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type,
typename std::iterator_traits<Iterator>::difference_type,
typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type*,
typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type
>
{
public:
typedef Iterator iterator_type;
typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
typedef typename sprout::container_traits<
typename std::iterator_traits<Iterator>::value_type
>::difference_type value_type;
typedef value_type reference;
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
typedef value_type* pointer;
protected:
iterator_type current;
value_type sep_size;
bool is_sep;
public:
size_enum_iterator() = default;
size_enum_iterator(size_enum_iterator const&) = default;
explicit SPROUT_CONSTEXPR size_enum_iterator(iterator_type it, value_type size = 0, bool sep = false)
: current(it)
, sep_size(size)
, is_sep(sep)
{}
template<typename U, bool V>
SPROUT_CONSTEXPR size_enum_iterator(size_enum_iterator<U, V> const& it)
: current(it.current)
, sep_size(it.sep_size)
, is_sep(it.is_sep)
{}
template<typename U, bool V>
size_enum_iterator& operator=(size_enum_iterator<U, V> const& it) {
size_enum_iterator temp(it);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR iterator_type base() const {
return current;
}
SPROUT_CONSTEXPR value_type separator_size() const {
return sep_size;
}
SPROUT_CONSTEXPR bool is_separator() const {
return is_sep;
}
SPROUT_CONSTEXPR reference operator*() const {
return is_sep ? sep_size : sprout::size(*current);
}
SPROUT_CONSTEXPR pointer operator->() const {
return &(is_sep ? sep_size : sprout::size(*current));
}
size_enum_iterator& operator++() {
if (is_sep) {
++current;
is_sep = false;
} else {
is_sep = true;
}
return *this;
}
size_enum_iterator operator++(int) {
size_enum_iterator result(*this);
if (is_sep) {
++current;
is_sep = false;
} else {
is_sep = true;
}
return result;
}
size_enum_iterator& operator--() {
if (is_sep) {
is_sep = false;
} else {
--current;
is_sep = true;
}
return *this;
}
size_enum_iterator operator--(int) {
size_enum_iterator temp(*this);
if (is_sep) {
is_sep = false;
} else {
--current;
is_sep = true;
}
return temp;
}
SPROUT_CONSTEXPR size_enum_iterator operator+(difference_type n) const {
return size_enum_iterator(current + (n + is_sep) / 2, sep_size, (n + is_sep) % 2);
}
SPROUT_CONSTEXPR size_enum_iterator operator-(difference_type n) const {
return size_enum_iterator(current - (n - is_sep) / 2, sep_size, (n - is_sep) % 2);
}
size_enum_iterator& operator+=(difference_type n) {
size_enum_iterator temp(current + (n + is_sep) / 2, sep_size, (n + is_sep) % 2);
temp.swap(*this);
return *this;
}
size_enum_iterator& operator-=(difference_type n) {
size_enum_iterator temp(current - (n - is_sep) / 2, sep_size, (n - is_sep) % 2);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return sprout::size(current[(n + is_sep) / 2]);
}
SPROUT_CONSTEXPR size_enum_iterator next() const {
return is_sep
? size_enum_iterator(sprout::next(current), sep_size, false)
: size_enum_iterator(current, sep_size, true)
;
}
SPROUT_CONSTEXPR size_enum_iterator prev() const {
return is_sep
? size_enum_iterator(current, sep_size, false)
: size_enum_iterator(sprout::prev(current), sep_size, true)
;
}
void swap(size_enum_iterator& other) {
using std::swap;
swap(current, other.current);
swap(sep_size, other.sep_size);
swap(is_sep, other.is_sep);
}
};
template<
typename Iterator1, bool Separated1,
typename Iterator2, bool Separated2
>
SPROUT_CONSTEXPR bool operator==(
sprout::size_enum_iterator<Iterator1, Separated1> const& lhs,
sprout::size_enum_iterator<Iterator2, Separated2> const& rhs
)
{
return lhs.base() == rhs.base() && lhs.is_separator() == rhs.is_separator();
}
template<
typename Iterator1, bool Separated1,
typename Iterator2, bool Separated2
>
SPROUT_CONSTEXPR bool operator!=(
sprout::size_enum_iterator<Iterator1, Separated1> const& lhs,
sprout::size_enum_iterator<Iterator2, Separated2> const& rhs
)
{
return !(lhs == rhs);
}
template<
typename Iterator1, bool Separated1,
typename Iterator2, bool Separated2
>
SPROUT_CONSTEXPR bool operator<(
sprout::size_enum_iterator<Iterator1, Separated1> const& lhs,
sprout::size_enum_iterator<Iterator2, Separated2> const& rhs
)
{
return lhs.base() < rhs.base()
|| (lhs.base() == rhs.base() && !lhs.is_separator() && rhs.is_separator())
;
}
template<
typename Iterator1, bool Separated1,
typename Iterator2, bool Separated2
>
SPROUT_CONSTEXPR bool operator>(
sprout::size_enum_iterator<Iterator1, Separated1> const& lhs,
sprout::size_enum_iterator<Iterator2, Separated2> const& rhs
)
{
return rhs < lhs;
}
template<
typename Iterator1, bool Separated1,
typename Iterator2, bool Separated2
>
SPROUT_CONSTEXPR bool operator<=(
sprout::size_enum_iterator<Iterator1, Separated1> const& lhs,
sprout::size_enum_iterator<Iterator2, Separated2> const& rhs
)
{
return !(rhs < lhs);
}
template<
typename Iterator1, bool Separated1,
typename Iterator2, bool Separated2
>
SPROUT_CONSTEXPR bool operator>=(
sprout::size_enum_iterator<Iterator1, Separated1> const& lhs,
sprout::size_enum_iterator<Iterator2, Separated2> const& rhs
)
{
return !(lhs < rhs);
}
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR decltype(std::declval<Iterator1>() - std::declval<Iterator2>()) operator-(
sprout::size_enum_iterator<Iterator1> const& lhs,
sprout::size_enum_iterator<Iterator2> const& rhs
)
{
return lhs.base() - rhs.base();
}
template<typename Iterator1, typename Iterator2>
SPROUT_CONSTEXPR decltype(std::declval<Iterator1>() - std::declval<Iterator2>()) operator-(
sprout::size_enum_iterator<Iterator1, true> const& lhs,
sprout::size_enum_iterator<Iterator2, true> const& rhs
)
{
return lhs.base() - rhs.base() + (
lhs.is_separator()
? rhs.is_separator() ? 0 : -1
: rhs.is_separator() ? 1 : 0
)
;
}
template<typename Iterator, bool Separated>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator, Separated> operator+(
typename sprout::size_enum_iterator<Iterator, Separated>::difference_type n,
sprout::size_enum_iterator<Iterator, Separated> const& it
)
{
return it + n;
}
//
// make_size_enum_iterator
//
template<typename Iterator>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator>
make_size_enum_iterator(Iterator it) {
return sprout::size_enum_iterator<Iterator>(it);
}
template<typename Iterator>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator, true>
make_size_enum_iterator(
Iterator it,
typename sprout::size_enum_iterator<Iterator, true>::value_type sep_size,
bool sep = false
)
{
return sprout::size_enum_iterator<Iterator, true>(it, sep_size, sep);
}
//
// swap
//
template<typename Iterator, bool Separated>
void swap(
sprout::size_enum_iterator<Iterator, Separated>& lhs,
sprout::size_enum_iterator<Iterator, Separated>& rhs
)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
//
// next
//
template<typename Iterator, bool Separated>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator, Separated> next(
sprout::size_enum_iterator<Iterator, Separated> const& it
)
{
return it.next();
}
template<typename Iterator, bool Separated>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator, Separated> next(
sprout::size_enum_iterator<Iterator, Separated> const& it,
typename sprout::size_enum_iterator<Iterator, Separated>::difference_type n
)
{
return it + n;
}
//
// prev
//
template<typename Iterator, bool Separated>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator, Separated> prev(
sprout::size_enum_iterator<Iterator, Separated> const& it
)
{
return it.prev();
}
template<typename Iterator, bool Separated>
SPROUT_CONSTEXPR sprout::size_enum_iterator<Iterator, Separated> prev(
sprout::size_enum_iterator<Iterator, Separated> const& it,
typename sprout::size_enum_iterator<Iterator, Separated>::difference_type n
)
{
return it - n;
}
//
// distance
//
template<typename Iterator, bool Separated>
SPROUT_CONSTEXPR typename std::iterator_traits<sprout::size_enum_iterator<Iterator, Separated> >::difference_type
distance(
sprout::size_enum_iterator<Iterator, Separated> first,
sprout::size_enum_iterator<Iterator, Separated> last
)
{
return last - first;
}
} // namespace sprout
#endif // #ifndef SPROUT_ITERATOR_SIZE_ENUM_ITERATOR_HPP

143
sprout/iterator/traits.hpp Normal file
View file

@ -0,0 +1,143 @@
#ifndef SPROUT_ITERATOR_TRAITS_HPP
#define SPROUT_ITERATOR_TRAITS_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/type_traits/has_xxx.hpp>
namespace sprout {
namespace detail {
// has_iterator_category
SPROUT_HAS_XXX_TYPE_DEF_LAZY(iterator_category);
} // namespace detail
//
// is_iterator
//
template<typename Iterator>
struct is_iterator
: sprout::detail::has_iterator_category<std::iterator_traits<Iterator> >
{};
namespace detail {
template<typename Iterator, typename = void>
struct is_input_iterator_impl
: std::false_type
{};
template<typename Iterator>
struct is_input_iterator_impl<
Iterator,
typename std::enable_if<sprout::is_iterator<Iterator>::value>::type
>
: std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::input_iterator_tag
>
{};
} // namespace detail
//
// is_input_iterator
//
template<typename Iterator>
struct is_input_iterator
: sprout::detail::is_input_iterator_impl<Iterator>
{};
namespace detail {
template<typename Iterator, typename = void>
struct is_output_iterator_impl
: std::false_type
{};
template<typename Iterator>
struct is_output_iterator_impl<
Iterator,
typename std::enable_if<sprout::is_iterator<Iterator>::value>::type
>
: std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::output_iterator_tag
>
{};
} // namespace detail
//
// is_output_iterator
//
template<typename Iterator>
struct is_output_iterator
: sprout::detail::is_output_iterator_impl<Iterator>
{};
namespace detail {
template<typename Iterator, typename = void>
struct is_forward_iterator_impl
: std::false_type
{};
template<typename Iterator>
struct is_forward_iterator_impl<
Iterator,
typename std::enable_if<sprout::is_iterator<Iterator>::value>::type
>
: std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::forward_iterator_tag
>
{};
} // namespace detail
//
// is_forward_iterator
//
template<typename Iterator>
struct is_forward_iterator
: sprout::detail::is_forward_iterator_impl<Iterator>
{};
namespace detail {
template<typename Iterator, typename = void>
struct is_bidirectional_iterator_impl
: std::false_type
{};
template<typename Iterator>
struct is_bidirectional_iterator_impl<
Iterator,
typename std::enable_if<sprout::is_iterator<Iterator>::value>::type
>
: std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::bidirectional_iterator_tag
>
{};
} // namespace detail
//
// is_bidirectional_iterator
//
template<typename Iterator>
struct is_bidirectional_iterator
: sprout::detail::is_bidirectional_iterator_impl<Iterator>
{};
namespace detail {
template<typename Iterator, typename = void>
struct is_random_access_iterator_impl
: std::false_type
{};
template<typename Iterator>
struct is_random_access_iterator_impl<
Iterator,
typename std::enable_if<sprout::is_iterator<Iterator>::value>::type
>
: std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::random_access_iterator_tag
>
{};
} // namespace detail
//
// is_random_access_iterator
//
template<typename Iterator>
struct is_random_access_iterator
: sprout::detail::is_random_access_iterator_impl<Iterator>
{};
} // namespace sprout
#endif // #ifndef SPROUT_ITERATOR_TRAITS_HPP

View file

@ -5,4 +5,3 @@
#include <sprout/numeric/fft/bitrev_table.hpp>
#endif // #ifndef SPROUT_NUMERIC_FFT_HPP

View file

@ -13,8 +13,8 @@
#include <sprout/integer/bit_length.hpp>
namespace sprout {
namespace fixed {
namespace detail {
namespace fixed {
namespace detail {
template<typename Container, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type bitrev_table_impl(
Container const& cont,

View file

@ -10,4 +10,3 @@
#define SPROUT_PP_CAT_I(a, b) a ## b
#endif // #ifndef SPROUT_PREPROCESSOR_CAT_HPP

View file

@ -9,4 +9,3 @@
#define SPROUT_PP_EMPTY()
#endif // #ifndef SPROUT_PREPROCESSOR_EMPTY_HPP

View file

@ -7,4 +7,3 @@
#include <sprout/preprocessor/u32str.hpp>
#endif // #ifndef SPROUT_PREPROCESSOR_STR_ALL_HPP

View file

@ -10,4 +10,3 @@
#define SPROUT_PP_STRINGIZE_I(text) #text
#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP

View file

@ -8,4 +8,3 @@
#include <sprout/preprocessor/u32stringize.hpp>
#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_ALL_HPP

View file

@ -10,4 +10,3 @@
#define SPROUT_PP_U16STR_I(str) u ## str
#endif // #ifndef SPROUT_PREPROCESSOR_U16STR_HPP

View file

@ -11,4 +11,3 @@
#define SPROUT_PP_U16STRINGIZE_II(str) u ## str
#endif // #ifndef SPROUT_PREPROCESSOR_U16STRINGIZE_HPP

Some files were not shown because too many files have changed in this diff Show more