mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-07-02 14:04:20 +00:00
rewrite sprout::algorithm::join performance
This commit is contained in:
parent
0ceabb5b9b
commit
1ea9d30e2a
145 changed files with 1359 additions and 364 deletions
|
@ -5,7 +5,7 @@
|
|||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/shuffle.hpp>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/shuffle.hpp>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/copy.hpp>
|
||||
#include <sprout/detail/container_complate.hpp>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <sprout/index_tuple.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
|
||||
namespace sprout {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/algorithm/fixed/swap_element.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/swap_element.hpp>
|
||||
#include <sprout/algorithm/fixed/pop_heap.hpp>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/swap_element.hpp>
|
||||
#include <sprout/algorithm/fixed/make_partial_heap.hpp>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/swap_element.hpp>
|
||||
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include <sprout/algorithm/fixed/swap_element.hpp>
|
||||
#include <sprout/algorithm/fixed/pop_heap.hpp>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue