add tuples::apply

This commit is contained in:
bolero-MURAKAMI 2014-12-14 12:59:51 +09:00
parent a1f6d6ffc3
commit 5ccbc4e903
16 changed files with 280 additions and 52 deletions

View file

@ -0,0 +1,34 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_ABS_DIFF_HPP
#define SPROUT_ALGORITHM_ABS_DIFF_HPP
#include <sprout/config.hpp>
namespace sprout {
//
// abs_diff
//
template<typename T>
inline SPROUT_CONSTEXPR T
abs_diff(T const& a, T const& b) {
return (a < b) ? b - a : a - b;
}
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR T
abs_diff(T const& a, T const& b, Compare comp) {
return comp(a, b) ? b - a : a - b;
}
template<typename T, typename Compare, typename Difference>
inline SPROUT_CONSTEXPR T
abs_diff(T const& a, T const& b, Compare comp, Difference diff) {
return comp(a, b) ? diff(b, a) : diff(a, b);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_ABS_DIFF_HPP

View file

@ -17,42 +17,42 @@
namespace sprout { namespace sprout {
namespace detail { namespace detail {
template<typename PopIterator, typename SampleIterator, typename Size, typename URNG> template<typename PopulationIterator, typename SampleIterator, typename Distance, typename URNG>
inline SPROUT_CXX14_CONSTEXPR SampleIterator inline SPROUT_CXX14_CONSTEXPR SampleIterator
sample_impl( sample_impl(
PopIterator first, PopIterator last, std::input_iterator_tag*, PopulationIterator first, PopulationIterator last, std::input_iterator_tag*,
SampleIterator out, std::random_access_iterator_tag*, SampleIterator out, std::random_access_iterator_tag*,
Size n, URNG&& g Distance n, URNG&& g
) )
{ {
typedef SPROUT_WORKAROUND_DETAIL_UNIFORM_INT_DISTRIBUTION<Size> distribution_type; typedef SPROUT_WORKAROUND_DETAIL_UNIFORM_INT_DISTRIBUTION<Distance> distribution_type;
typedef typename distribution_type::param_type param_type; typedef typename distribution_type::param_type param_type;
distribution_type dist = {}; distribution_type dist = {};
Size sample_size = 0; Distance sample_size = 0;
while (first != last && sample_size != n) { while (first != last && sample_size != n) {
out[sample_size++] = *first++; out[sample_size++] = *first++;
} }
for (Size pop_size = sample_size; first != last; ++first, ++pop_size) { for (Distance pop_size = sample_size; first != last; ++first, ++pop_size) {
param_type const p(0, pop_size); param_type const p(0, pop_size);
Size const k = dist(g, p); Distance const k = dist(g, p);
if (k < n) { if (k < n) {
out[k] = *first; out[k] = *first;
} }
} }
return out + sample_size; return out + sample_size;
} }
template<typename PopIterator, typename SampleIterator, typename Size, typename URNG> template<typename PopulationIterator, typename SampleIterator, typename Distance, typename URNG>
inline SPROUT_CXX14_CONSTEXPR SampleIterator inline SPROUT_CXX14_CONSTEXPR SampleIterator
sample_impl( sample_impl(
PopIterator first, PopIterator last, std::forward_iterator_tag*, PopulationIterator first, PopulationIterator last, std::forward_iterator_tag*,
SampleIterator out, std::output_iterator_tag*, SampleIterator out, std::output_iterator_tag*,
Size n, URNG&& g Distance n, URNG&& g
) )
{ {
typedef SPROUT_WORKAROUND_DETAIL_UNIFORM_INT_DISTRIBUTION<Size> distribution_type; typedef SPROUT_WORKAROUND_DETAIL_UNIFORM_INT_DISTRIBUTION<Distance> distribution_type;
typedef typename distribution_type::param_type param_type; typedef typename distribution_type::param_type param_type;
distribution_type dist = {}; distribution_type dist = {};
Size unsampled_size = sprout::distance(first, last); Distance unsampled_size = sprout::distance(first, last);
for (n = NS_SSCRISK_CEL_OR_SPROUT::min(n, unsampled_size); n != 0; ++first ) { for (n = NS_SSCRISK_CEL_OR_SPROUT::min(n, unsampled_size); n != 0; ++first ) {
param_type const p(0, --unsampled_size); param_type const p(0, --unsampled_size);
if (dist(g, p) < n) { if (dist(g, p) < n) {
@ -66,10 +66,10 @@ namespace sprout {
// //
// sample // sample
// //
template<typename PopIterator, typename SampleIterator, typename Size, typename URNG> template<typename PopulationIterator, typename SampleIterator, typename Distance, typename URNG>
inline SPROUT_CXX14_CONSTEXPR SampleIterator inline SPROUT_CXX14_CONSTEXPR SampleIterator
sample(PopIterator first, PopIterator last, SampleIterator out, Size n, URNG&& g) { sample(PopulationIterator first, PopulationIterator last, SampleIterator out, Distance n, URNG&& g) {
typedef typename std::iterator_traits<PopIterator>::iterator_category* pop_category; typedef typename std::iterator_traits<PopulationIterator>::iterator_category* pop_category;
typedef typename std::iterator_traits<SampleIterator>::iterator_category* sample_category; typedef typename std::iterator_traits<SampleIterator>::iterator_category* sample_category;
return sprout::detail::sample_impl( return sprout::detail::sample_impl(
first, last, pop_category(), first, last, pop_category(),

View file

@ -61,5 +61,6 @@
#include <sprout/algorithm/next_difference.hpp> #include <sprout/algorithm/next_difference.hpp>
#include <sprout/algorithm/next_symmetric_difference.hpp> #include <sprout/algorithm/next_symmetric_difference.hpp>
#include <sprout/algorithm/clamp.hpp> #include <sprout/algorithm/clamp.hpp>
#include <sprout/algorithm/abs_diff.hpp>
#endif // #ifndef SPROUT_ALGORITHM_NON_MODIFYIING_HPP #endif // #ifndef SPROUT_ALGORITHM_NON_MODIFYIING_HPP

View file

@ -149,6 +149,13 @@ namespace sprout {
{ {
return sprout::search(first1, last1, first2, last2, sprout::equal_to<>()); return sprout::search(first1, last1, first2, last2, sprout::equal_to<>());
} }
//
template<typename ForwardIterator, typename Searcher>
inline SPROUT_CONSTEXPR ForwardIterator
search(ForwardIterator first, ForwardIterator last, Searcher const& searcher) {
return searcher(first, last);
}
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_SEARCH_HPP #endif // #ifndef SPROUT_ALGORITHM_SEARCH_HPP

View file

@ -0,0 +1,14 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_SEARCHING_HPP
#define SPROUT_ALGORITHM_SEARCHING_HPP
#include <sprout/config.hpp>
#include <sprout/algorithm/searching/default_searcher.hpp>
#endif // #ifndef SPROUT_ALGORITHM_SEARCHING_HPP

View file

@ -0,0 +1,40 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_SEARCHING_DEFAULT_SEARCHER_HPP
#define SPROUT_ALGORITHM_SEARCHING_DEFAULT_SEARCHER_HPP
#include <sprout/config.hpp>
#include <sprout/functional/equal_to.hpp>
#include <sprout/algorithm/search.hpp>
namespace sprout {
//
// default_searcher
//
template<typename ForwardIterator2, typename BinaryPredicate = sprout::equal_to<> >
class default_searcher {
private:
ForwardIterator2 first2_;
ForwardIterator2 last2_;
BinaryPredicate pred_;
public:
SPROUT_CONSTEXPR default_searcher(ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred)
: first2_(first2), last2_(last2), pred_(pred)
{}
SPROUT_CONSTEXPR default_searcher(ForwardIterator2 first2, ForwardIterator2 last2)
: first2_(first2), last2_(last2), pred_()
{}
template<typename ForwardIterator1>
SPROUT_CONSTEXPR ForwardIterator1
operator()(ForwardIterator1 first1, ForwardIterator1 last1) const {
return sprout::search(first1, last1, first2_, last2_, pred_);
}
};
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_SEARCHING_DEFAULT_SEARCHER_HPP

View file

@ -54,6 +54,11 @@ namespace sprout {
: public sprout::is_bind_expression<T> : public sprout::is_bind_expression<T>
{}; {};
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_bind_expression_v = sprout::is_bind_expression<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
namespace detail { namespace detail {
struct no_tuple_element; struct no_tuple_element;

View file

@ -190,6 +190,11 @@ namespace sprout {
: public sprout::integral_constant<int, N> : public sprout::integral_constant<int, N>
{}; {};
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_placeholder_v = sprout::is_placeholder<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
// //
// is_positional_placeholder // is_positional_placeholder
// //
@ -214,6 +219,11 @@ namespace sprout {
: public sprout::integral_constant<int, 1> : public sprout::integral_constant<int, 1>
{}; {};
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_positional_placeholder_v = sprout::is_positional_placeholder<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
// //
// is_variadic_placeholder // is_variadic_placeholder
// //
@ -237,6 +247,11 @@ namespace sprout {
struct is_variadic_placeholder<sprout::variadic_placeholder<N> > struct is_variadic_placeholder<sprout::variadic_placeholder<N> >
: public sprout::integral_constant<int, N + 1> : public sprout::integral_constant<int, N + 1>
{}; {};
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_variadic_placeholder_v = sprout::is_variadic_placeholder<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_BIND_PLACEHOLDER_HPP #endif // #ifndef SPROUT_FUNCTIONAL_BIND_PLACEHOLDER_HPP

View file

@ -76,6 +76,33 @@ namespace sprout {
SPROUT_FORWARD(ForwardRange1, range1) SPROUT_FORWARD(ForwardRange1, range1)
); );
} }
//
template<typename ForwardRange, typename Searcher>
inline SPROUT_CONSTEXPR typename sprout::range::range_return<ForwardRange>::type
search(ForwardRange&& range, Searcher const& searcher) {
return sprout::range::range_return<ForwardRange>::pack(
sprout::search(
sprout::begin(SPROUT_FORWARD(ForwardRange, range)),
sprout::end(SPROUT_FORWARD(ForwardRange, range)),
searcher
),
SPROUT_FORWARD(ForwardRange, range)
);
}
template<sprout::range::range_return_value RetV, typename ForwardRange, typename Searcher>
inline SPROUT_CONSTEXPR typename sprout::range::range_return<ForwardRange, RetV>::type
search(ForwardRange&& range, Searcher const& searcher) {
return sprout::range::range_return<ForwardRange, RetV>::pack(
sprout::search(
sprout::begin(SPROUT_FORWARD(ForwardRange, range)),
sprout::end(SPROUT_FORWARD(ForwardRange, range)),
searcher
),
SPROUT_FORWARD(ForwardRange, range)
);
}
} // namespace range } // namespace range
} // namespace sprout } // namespace sprout

View file

@ -13,6 +13,7 @@
#include <sprout/tuple/traits.hpp> #include <sprout/tuple/traits.hpp>
#include <sprout/tuple/metafunctions.hpp> #include <sprout/tuple/metafunctions.hpp>
#include <sprout/tuple/functions.hpp> #include <sprout/tuple/functions.hpp>
#include <sprout/tuple/apply.hpp>
#include <sprout/tuple/fused.hpp> #include <sprout/tuple/fused.hpp>
#include <sprout/tuple/flex.hpp> #include <sprout/tuple/flex.hpp>

70
sprout/tuple/apply.hpp Normal file
View file

@ -0,0 +1,70 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_TUPLE_APPLY_HPP
#define SPROUT_TUPLE_APPLY_HPP
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple/metafunction.hpp>
#include <sprout/tuple/tuple/tuple.hpp>
#include <sprout/tuple/tuple/get.hpp>
#include <sprout/tuple/indexes.hpp>
#include <sprout/utility/forward.hpp>
namespace sprout {
namespace tuples {
//
// apply_result
//
namespace detail {
template<typename F, typename Tuple, typename IndexTuple>
struct apply_result_impl;
template<typename F, typename Tuple, sprout::index_t... Indexes>
struct apply_result_impl<F, Tuple, sprout::index_tuple<Indexes...> > {
public:
typedef decltype(
std::declval<F>()(
sprout::tuples::get<Indexes>(std::declval<Tuple>())...
)
) type;
};
} // namespace detail
template<typename F, typename Tuple>
struct apply_result
: public sprout::tuples::detail::apply_result_impl<
F, Tuple,
typename sprout::tuple_indexes<typename std::remove_reference<Tuple>::type>::type
>
{};
//
// apply
//
namespace detail {
template<typename Result, typename F, typename Tuple, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR Result
apply_impl(F&& f, Tuple&& t, sprout::index_tuple<Indexes...>) {
return SPROUT_FORWARD(F, f)(sprout::tuples::get<Indexes>(SPROUT_FORWARD(Tuple, t))...);
}
} // namespace detail
template<typename F, typename Tuple>
inline SPROUT_CONSTEXPR typename sprout::tuples::apply_result<F, Tuple>::type
apply(F&& f, Tuple&& t) {
return sprout::tuples::detail::apply_impl<typename sprout::tuples::apply_result<F, Tuple>::type>(
SPROUT_FORWARD(F, f), SPROUT_FORWARD(Tuple, t),
sprout::tuple_indexes<typename std::remove_reference<Tuple>::type>::make()
);
}
} // namespace tuples
using sprout::tuples::apply_result;
using sprout::tuples::apply;
} // namespace sprout
#endif // #ifndef SPROUT_TUPLE_APPLY_HPP

View file

@ -8,13 +8,9 @@
#ifndef SPROUT_TUPLE_FUSED_HPP #ifndef SPROUT_TUPLE_FUSED_HPP
#define SPROUT_TUPLE_FUSED_HPP #define SPROUT_TUPLE_FUSED_HPP
#include <utility>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple/metafunction.hpp>
#include <sprout/tuple/tuple/tuple.hpp> #include <sprout/tuple/tuple/tuple.hpp>
#include <sprout/tuple/tuple/get.hpp> #include <sprout/tuple/apply.hpp>
#include <sprout/tuple/indexes.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/forward.hpp>
namespace sprout { namespace sprout {
@ -26,34 +22,13 @@ namespace sprout {
class fused { class fused {
public: public:
typedef F functor_type; typedef F functor_type;
private:
template<typename Tuple, typename IndexTuple>
struct result_impl;
template<typename Tuple, sprout::index_t... Indexes>
struct result_impl<Tuple, sprout::index_tuple<Indexes...> > {
public:
typedef decltype(
std::declval<functor_type const&>()(
sprout::tuples::get<Indexes>(std::declval<Tuple>())...
)
) type;
};
public: public:
template<typename Tuple> template<typename Tuple>
struct result struct result
: public result_impl< : public sprout::tuples::apply_result<functor_type const&, Tuple>
Tuple,
typename sprout::tuple_indexes<typename std::remove_reference<Tuple>::type>::type
>
{}; {};
private: private:
functor_type f_; functor_type f_;
private:
template<typename Result, typename Tuple, sprout::index_t... Indexes>
SPROUT_CONSTEXPR Result
call(Tuple&& t, sprout::index_tuple<Indexes...>) const {
return f_(sprout::tuples::get<Indexes>(SPROUT_FORWARD(Tuple, t))...);
}
public: public:
SPROUT_CONSTEXPR fused() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL SPROUT_CONSTEXPR fused() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
fused(fused const&) = default; fused(fused const&) = default;
@ -66,10 +41,7 @@ namespace sprout {
template<typename Tuple> template<typename Tuple>
SPROUT_CONSTEXPR typename result<Tuple>::type SPROUT_CONSTEXPR typename result<Tuple>::type
operator()(Tuple&& t) const { operator()(Tuple&& t) const {
return call<typename result<Tuple>::type>( return sprout::tuples::apply(f_, SPROUT_FORWARD(Tuple, t));
SPROUT_FORWARD(Tuple, t),
sprout::tuple_indexes<typename std::remove_reference<Tuple>::type>::make()
);
} }
}; };

View file

@ -0,0 +1,46 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_TYPE_TRAITS_IS_NULL_POINTER_HPP
#define SPROUT_TYPE_TRAITS_IS_NULL_POINTER_HPP
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/type_traits/integral_constant.hpp>
namespace sprout {
//
// is_null_pointer
//
template<typename T>
struct is_null_pointer
: public sprout::false_type
{};
template<typename T>
struct is_null_pointer<T const>
: public sprout::is_null_pointer<T>
{};
template<typename T>
struct is_null_pointer<T volatile>
: public sprout::is_null_pointer<T>
{};
template<typename T>
struct is_null_pointer<T const volatile>
: public sprout::is_null_pointer<T>
{};
template<>
struct is_null_pointer<std::nullptr_t>
: public sprout::true_type
{};
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_null_pointer_v = sprout::is_null_pointer<T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_TRAITS_IS_NULL_POINTER_HPP

View file

@ -14,6 +14,7 @@
#include <sprout/detail/predef.hpp> #include <sprout/detail/predef.hpp>
#include <sprout/type_traits/integral_constant.hpp> #include <sprout/type_traits/integral_constant.hpp>
#include <sprout/type_traits/common_type.hpp> #include <sprout/type_traits/common_type.hpp>
#include <sprout/type_traits/is_null_pointer.hpp>
#include <sprout/type_traits/detail/type_traits_wrapper.hpp> #include <sprout/type_traits/detail/type_traits_wrapper.hpp>
#if !defined(_LIBCPP_VERSION) || (_LIBCPP_VERSION < 1101) #if !defined(_LIBCPP_VERSION) || (_LIBCPP_VERSION < 1101)
# include <sprout/tpp/algorithm/max_element.hpp> # include <sprout/tpp/algorithm/max_element.hpp>
@ -28,10 +29,6 @@ namespace sprout {
: public sprout::detail::type_traits_wrapper<std::is_void<T> > : public sprout::detail::type_traits_wrapper<std::is_void<T> >
{}; {};
template<typename T> template<typename T>
struct is_null_pointer
: public sprout::detail::type_traits_wrapper<std::is_same<typename std::remove_cv<T>::type, std::nullptr_t> >
{};
template<typename T>
struct is_integral struct is_integral
: public sprout::detail::type_traits_wrapper<std::is_integral<T> > : public sprout::detail::type_traits_wrapper<std::is_integral<T> >
{}; {};

View file

@ -21,8 +21,6 @@ namespace sprout {
template<typename T> template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_void_v = sprout::is_void<T>::value; SPROUT_STATIC_CONSTEXPR bool is_void_v = sprout::is_void<T>::value;
template<typename T> template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_null_pointer_v = sprout::is_null_pointer<T>::value;
template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_integral_v = sprout::is_integral<T>::value; SPROUT_STATIC_CONSTEXPR bool is_integral_v = sprout::is_integral<T>::value;
template<typename T> template<typename T>
SPROUT_STATIC_CONSTEXPR bool is_floating_point_v = sprout::is_floating_point<T>::value; SPROUT_STATIC_CONSTEXPR bool is_floating_point_v = sprout::is_floating_point<T>::value;

View file

@ -12,6 +12,7 @@
#include <sprout/adapt/std/utility.hpp> #include <sprout/adapt/std/utility.hpp>
#include <sprout/adl/not_found.hpp> #include <sprout/adl/not_found.hpp>
#include <sprout/algorithm.hpp> #include <sprout/algorithm.hpp>
#include <sprout/algorithm/searching.hpp>
#include <sprout/algorithm/string.hpp> #include <sprout/algorithm/string.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
#include <sprout/assert.hpp> #include <sprout/assert.hpp>