2011-10-10 01:20:21 +00:00
|
|
|
#ifndef SPROUT_ALGORITHM_STRING_JOIN_HPP
|
|
|
|
#define SPROUT_ALGORITHM_STRING_JOIN_HPP
|
|
|
|
|
2011-11-04 13:17:25 +00:00
|
|
|
#include <cstddef>
|
|
|
|
#include <iterator>
|
2011-10-10 01:20:21 +00:00
|
|
|
#include <type_traits>
|
|
|
|
#include <sprout/config.hpp>
|
|
|
|
#include <sprout/fixed_container/traits.hpp>
|
|
|
|
#include <sprout/fixed_container/functions.hpp>
|
|
|
|
#include <sprout/iterator/operation.hpp>
|
|
|
|
|
|
|
|
namespace sprout {
|
|
|
|
namespace algorithm {
|
|
|
|
namespace result_of {
|
|
|
|
//
|
|
|
|
// join
|
|
|
|
//
|
2011-11-04 13:17:25 +00:00
|
|
|
template<typename ContainerContainer>
|
2011-10-10 01:20:21 +00:00
|
|
|
struct join {
|
|
|
|
public:
|
|
|
|
typedef typename sprout::rebind_fixed_size<
|
|
|
|
typename sprout::fixed_container_traits<ContainerContainer>::value_type
|
|
|
|
>::template apply<
|
2011-11-04 13:17:25 +00:00
|
|
|
sprout::fixed_container_traits<
|
|
|
|
typename sprout::fixed_container_traits<ContainerContainer>::value_type
|
|
|
|
>::fixed_size
|
|
|
|
* sprout::fixed_container_traits<ContainerContainer>::fixed_size
|
2011-10-10 01:20:21 +00:00
|
|
|
>::type type;
|
|
|
|
};
|
|
|
|
} // namespace result_of
|
|
|
|
|
|
|
|
namespace detail {
|
2011-11-04 13:17:25 +00:00
|
|
|
template<typename Result, typename ContainerInputIterator, typename... Args>
|
2011-10-10 01:20:21 +00:00
|
|
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
2011-11-04 13:17:25 +00:00
|
|
|
sprout::fixed_container_traits<Result>::fixed_size == sizeof...(Args),
|
|
|
|
Result
|
|
|
|
>::type join_impl(
|
|
|
|
ContainerInputIterator first_cont,
|
|
|
|
ContainerInputIterator last_cont,
|
|
|
|
Args const&... args
|
|
|
|
);
|
|
|
|
template<typename Result, typename ContainerInputIterator, typename... Args>
|
|
|
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
|
|
|
sprout::fixed_container_traits<Result>::fixed_size != sizeof...(Args),
|
|
|
|
Result
|
|
|
|
>::type join_impl(
|
|
|
|
ContainerInputIterator first_cont,
|
|
|
|
ContainerInputIterator last_cont,
|
|
|
|
Args const&... args
|
|
|
|
);
|
|
|
|
template<typename Result, typename ContainerInputIterator, typename InputIterator, typename... Args>
|
|
|
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
|
|
|
sprout::fixed_container_traits<Result>::fixed_size == sizeof...(Args),
|
2011-10-10 01:20:21 +00:00
|
|
|
Result
|
|
|
|
>::type join_impl_1(
|
2011-11-04 13:17:25 +00:00
|
|
|
ContainerInputIterator first_cont,
|
|
|
|
ContainerInputIterator last_cont,
|
|
|
|
InputIterator first,
|
|
|
|
InputIterator last,
|
|
|
|
Args const&... args
|
2011-10-10 01:20:21 +00:00
|
|
|
)
|
|
|
|
{
|
2011-11-04 13:17:25 +00:00
|
|
|
return sprout::make_clone<Result>(args...);
|
2011-10-10 01:20:21 +00:00
|
|
|
}
|
2011-11-04 13:17:25 +00:00
|
|
|
template<typename Result, typename ContainerInputIterator, typename InputIterator, typename... Args>
|
2011-10-10 01:20:21 +00:00
|
|
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
2011-11-04 13:17:25 +00:00
|
|
|
sprout::fixed_container_traits<Result>::fixed_size != sizeof...(Args),
|
2011-10-10 01:20:21 +00:00
|
|
|
Result
|
|
|
|
>::type join_impl_1(
|
2011-11-04 13:17:25 +00:00
|
|
|
ContainerInputIterator first_cont,
|
|
|
|
ContainerInputIterator 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<Result>(sprout::next(first_cont), last_cont, args...)
|
|
|
|
;
|
|
|
|
}
|
|
|
|
template<typename Result, typename ContainerInputIterator, typename... Args>
|
|
|
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
|
|
|
sprout::fixed_container_traits<Result>::fixed_size == sizeof...(Args),
|
|
|
|
Result
|
|
|
|
>::type join_impl(
|
|
|
|
ContainerInputIterator first_cont,
|
|
|
|
ContainerInputIterator last_cont,
|
|
|
|
Args const&... args
|
2011-10-10 01:20:21 +00:00
|
|
|
)
|
|
|
|
{
|
2011-11-04 13:17:25 +00:00
|
|
|
return sprout::make_clone<Result>(args...);
|
2011-10-10 01:20:21 +00:00
|
|
|
}
|
2011-11-04 13:17:25 +00:00
|
|
|
template<typename Result, typename ContainerInputIterator, typename... Args>
|
|
|
|
SPROUT_CONSTEXPR inline typename std::enable_if<
|
|
|
|
sprout::fixed_container_traits<Result>::fixed_size != sizeof...(Args),
|
|
|
|
Result
|
|
|
|
>::type join_impl(
|
|
|
|
ContainerInputIterator first_cont,
|
|
|
|
ContainerInputIterator last_cont,
|
|
|
|
Args const&... args
|
2011-10-10 01:20:21 +00:00
|
|
|
)
|
|
|
|
{
|
2011-11-04 13:17:25 +00:00
|
|
|
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::make_clone<Result>(args...)
|
2011-10-10 01:20:21 +00:00
|
|
|
;
|
|
|
|
}
|
|
|
|
} // namespace detail
|
|
|
|
//
|
|
|
|
// join
|
|
|
|
//
|
2011-11-04 13:17:25 +00:00
|
|
|
template<typename ContainerContainer>
|
|
|
|
SPROUT_CONSTEXPR inline typename sprout::algorithm::result_of::join<ContainerContainer>::type join(
|
|
|
|
ContainerContainer const& cont_cont
|
2011-10-10 01:20:21 +00:00
|
|
|
)
|
|
|
|
{
|
2011-11-04 13:17:25 +00:00
|
|
|
return sprout::algorithm::detail::join_impl<typename sprout::algorithm::result_of::join<ContainerContainer>::type>(
|
2011-10-10 01:20:21 +00:00
|
|
|
sprout::begin(cont_cont),
|
2011-11-04 13:17:25 +00:00
|
|
|
sprout::end(cont_cont)
|
2011-10-10 01:20:21 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
} // namespace algorithm
|
|
|
|
} // namespace sprout
|
|
|
|
|
|
|
|
#endif // #ifndef SPROUT_ALGORITHM_STRING_JOIN_HPP
|