mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-10-19 13:49:23 +00:00
fix recursion depth O(logN): some algorithms
This commit is contained in:
parent
28697ee7a8
commit
5019f6aa96
162 changed files with 3600 additions and 1659 deletions
109
testspr/algorithm.hpp
Normal file
109
testspr/algorithm.hpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
#ifndef TESTSPR_ALGORITHM_HPP
|
||||
#define TESTSPR_ALGORITHM_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/container.hpp>
|
||||
|
||||
namespace testspr {
|
||||
//
|
||||
// distance
|
||||
//
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
distance(InputIterator first, InputIterator last) {
|
||||
return first == last ? 0
|
||||
: 1 + testspr::distance(first + 1, last)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// equal
|
||||
//
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) {
|
||||
return first1 == last1 ? first2 == last2
|
||||
: first2 == last2 ? false
|
||||
: !(*first1 == *first2) ? false
|
||||
: testspr::equal(first1 + 1, last1, first2 + 1, last2)
|
||||
;
|
||||
}
|
||||
template<typename Range1, typename Range2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
equal(Range1 const& range1, Range2 const& range2) {
|
||||
return testspr::equal(sprout::begin(range1), sprout::end(range1), sprout::begin(range2), sprout::end(range2));
|
||||
}
|
||||
|
||||
//
|
||||
// is_found
|
||||
//
|
||||
template<class InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_found(InputIterator first, InputIterator last, T const& value) {
|
||||
return first == last ? false
|
||||
: *first == value ? true
|
||||
: testspr::is_found(first + 1, last, value)
|
||||
;
|
||||
}
|
||||
template<typename Range, typename T>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_found(Range const& range, T const& value) {
|
||||
return testspr::is_found(sprout::begin(range), sprout::end(range), value);
|
||||
}
|
||||
|
||||
//
|
||||
// count
|
||||
//
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count(InputIterator first, InputIterator last, T const& value) {
|
||||
return first == last ? 0
|
||||
: (*first == value ? 1 : 0) + testspr::count(first + 1, last, value)
|
||||
;
|
||||
}
|
||||
template<typename Range, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<typename Range::const_iterator>::difference_type
|
||||
count(Range const& range, T const& value) {
|
||||
return testspr::count(sprout::begin(range), sprout::end(range), value);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_permutation_impl(
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
ForwardIterator1 first1_, ForwardIterator2 first2_
|
||||
)
|
||||
{
|
||||
return first1_ == last1 && first2_ == last2 ? true
|
||||
: testspr::count(first1, last1, *first1_) != testspr::count(first2, first2 + testspr::distance(first1, last1), *first1_)
|
||||
? false
|
||||
: testspr::detail::is_permutation_impl(first1, last1, first2, last2, first1_ + 1, first2_ + 1)
|
||||
;
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// is_permutation
|
||||
//
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_permutation(
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2
|
||||
)
|
||||
{
|
||||
return testspr::detail::is_permutation_impl(first1, last1, first2, last2, first1, first2);
|
||||
}
|
||||
template<typename Range1, typename Range2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_permutation(Range1 const& range1, Range2 const& range2) {
|
||||
return testspr::is_permutation(
|
||||
sprout::begin(range1), sprout::end(range1),
|
||||
sprout::begin(range2), sprout::end(range2)
|
||||
);
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
#endif // #ifndef TESTSPR_ALGORITHM_HPP
|
44
testspr/assert.hpp
Normal file
44
testspr/assert.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef TESTSPR_ASSERT_HPP
|
||||
#define TESTSPR_ASSERT_HPP
|
||||
|
||||
#include <cassert>
|
||||
#ifdef TESTSPR_CONFIG_ENABLE_STATIC_WARNING
|
||||
# include <boost/serialization/static_warning.hpp>
|
||||
#endif
|
||||
|
||||
//
|
||||
// TESTSPR_STATIC_ASSERT
|
||||
// TESTSPR_ASSERT
|
||||
// TESTSPR_BOTH_ASSERT
|
||||
//
|
||||
#define TESTSPR_STATIC_ASSERT(expr) static_assert(expr, #expr)
|
||||
#define TESTSPR_ASSERT(expr) assert(expr)
|
||||
#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_ASSERT(expr) TESTSPR_STATIC_ASSERT(expr); TESTSPR_ASSERT(expr)
|
||||
#else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_ASSERT(expr) TESTSPR_ASSERT(expr)
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
|
||||
//
|
||||
// TESTSPR_STATIC_WARNING
|
||||
//
|
||||
#ifdef TESTSPR_CONFIG_ENABLE_STATIC_WARNING
|
||||
# define TESTSPR_STATIC_WARNING(expr) BOOST_STATIC_WARNING(expr)
|
||||
#else
|
||||
# define TESTSPR_STATIC_WARNING(expr)
|
||||
#endif
|
||||
|
||||
//
|
||||
// TESTSPR_STATIC_UNCHECKED
|
||||
// TESTSPR_UNCHECKED
|
||||
// TESTSPR_BOTH_UNCHECKED
|
||||
//
|
||||
#define TESTSPR_STATIC_UNCHECKED(expr) TESTSPR_STATIC_WARNING(expr)
|
||||
#define TESTSPR_UNCHECKED(expr) (expr)
|
||||
#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_UNCHECKED(expr) TESTSPR_STATIC_UNCHECKED(expr); TESTSPR_UNCHECKED(expr)
|
||||
#else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_UNCHECKED(expr) TESTSPR_UNCHECKED(expr)
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
|
||||
#endif // #ifndef TESTSPR_ASSERT_HPP
|
217
testspr/functional.hpp
Normal file
217
testspr/functional.hpp
Normal file
|
@ -0,0 +1,217 @@
|
|||
#ifndef TESTSPR_FUNCTIONAL_HPP
|
||||
#define TESTSPR_FUNCTIONAL_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace testspr {
|
||||
//
|
||||
// do_nothing
|
||||
//
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
do_nothing(T const&) SPROUT_NOEXCEPT {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// is_even
|
||||
//
|
||||
template<typename T>
|
||||
struct is_even {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& t) const { return t % 2 == 0; }
|
||||
};
|
||||
//
|
||||
// is_odd
|
||||
//
|
||||
template<typename T>
|
||||
struct is_odd {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& t) const { return t % 2 != 0; }
|
||||
};
|
||||
//
|
||||
// is_multiple_of
|
||||
//
|
||||
template<typename T, typename U = T>
|
||||
struct is_multiple_of {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef U second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& t, U const& u) const { return t % u == 0; }
|
||||
};
|
||||
|
||||
//
|
||||
// less
|
||||
//
|
||||
template<typename T>
|
||||
struct less {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs < rhs; }
|
||||
};
|
||||
//
|
||||
// greater
|
||||
//
|
||||
template<typename T>
|
||||
struct greater {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs > rhs; }
|
||||
};
|
||||
//
|
||||
// equal_to
|
||||
//
|
||||
template<typename T>
|
||||
struct equal_to {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs == rhs; }
|
||||
};
|
||||
//
|
||||
// mod_less
|
||||
//
|
||||
template<typename T, T mod>
|
||||
struct mod_less {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs % mod < rhs % mod; }
|
||||
};
|
||||
|
||||
//
|
||||
// less_than
|
||||
//
|
||||
template<typename T>
|
||||
struct less_than {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
T value;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR less_than(T const& value) : value(value) {}
|
||||
SPROUT_CONSTEXPR bool operator()(T const& x) const { return x < value; }
|
||||
};
|
||||
//
|
||||
// greater_than
|
||||
//
|
||||
template<typename T>
|
||||
struct greater_than {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
T value;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR greater_than(T const& value) : value(value) {}
|
||||
SPROUT_CONSTEXPR bool operator()(T const& x) const { return x > value; }
|
||||
};
|
||||
|
||||
//
|
||||
// x2
|
||||
//
|
||||
template<typename T>
|
||||
struct x2 {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef T result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T operator()(T const& t) const { return t + t; }
|
||||
};
|
||||
|
||||
//
|
||||
// plus
|
||||
//
|
||||
template<typename T>
|
||||
struct plus {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef T result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T operator()(T const& lhs, T const& rhs) const { return lhs + rhs; }
|
||||
};
|
||||
|
||||
//
|
||||
// gen_iota
|
||||
//
|
||||
template<typename T>
|
||||
struct gen_iota {
|
||||
public:
|
||||
struct result {
|
||||
public:
|
||||
T val;
|
||||
gen_iota gen;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T const& generated_value() const { return val; }
|
||||
SPROUT_CONSTEXPR gen_iota const& next_generator() const { return gen; }
|
||||
};
|
||||
private:
|
||||
T val;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR gen_iota(T const& val = T())
|
||||
: val(val)
|
||||
{}
|
||||
SPROUT_CONSTEXPR result operator()() const { return result{val, gen_iota(val + 1)}; }
|
||||
};
|
||||
//
|
||||
// unf_iota
|
||||
//
|
||||
template<typename T>
|
||||
struct unf_iota {
|
||||
public:
|
||||
struct result {
|
||||
public:
|
||||
T val;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T const& generated_value() const { return val; }
|
||||
SPROUT_CONSTEXPR T next_generator() const { return val + 1; }
|
||||
};
|
||||
public:
|
||||
SPROUT_CONSTEXPR result operator()(T const& val) const { return result{val}; }
|
||||
};
|
||||
|
||||
//
|
||||
// x2_visitor
|
||||
//
|
||||
template<typename R = void>
|
||||
class x2_visitor {
|
||||
public:
|
||||
typedef R result_type;
|
||||
public:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR result_type operator()(T const& t) const { return static_cast<result_type>(t + t); }
|
||||
};
|
||||
//
|
||||
// x2_assign_visitor
|
||||
//
|
||||
template<typename R = void>
|
||||
class x2_assign_visitor {
|
||||
public:
|
||||
typedef R result_type;
|
||||
public:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR result_type operator()(T& t) const { return static_cast<result_type>(t += t); }
|
||||
};
|
||||
} // namespace testspr
|
||||
|
||||
#endif // #ifndef TESTSPR_FUNCTIONAL_HPP
|
257
testspr/iterator.hpp
Normal file
257
testspr/iterator.hpp
Normal file
|
@ -0,0 +1,257 @@
|
|||
#ifndef TESTSPR_ITERATOR_HPP
|
||||
#define TESTSPR_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/next.hpp>
|
||||
#include <sprout/iterator/prev.hpp>
|
||||
#include <sprout/iterator/distance.hpp>
|
||||
#include <sprout/utility/swap.hpp>
|
||||
|
||||
namespace testspr {
|
||||
//
|
||||
// reduct_iterator
|
||||
//
|
||||
template<typename Iterator, typename Category = typename std::iterator_traits<Iterator>::iterator_category>
|
||||
class reduct_iterator
|
||||
: public std::iterator<
|
||||
Category,
|
||||
typename std::iterator_traits<Iterator>::value_type,
|
||||
typename std::iterator_traits<Iterator>::difference_type,
|
||||
typename std::iterator_traits<Iterator>::pointer,
|
||||
typename std::iterator_traits<Iterator>::reference
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef Iterator iterator_type;
|
||||
typedef Category iterator_category;
|
||||
typedef typename std::iterator_traits<iterator_type>::value_type value_type;
|
||||
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<iterator_type>::pointer pointer;
|
||||
typedef typename std::iterator_traits<iterator_type>::reference reference;
|
||||
protected:
|
||||
iterator_type current;
|
||||
public:
|
||||
reduct_iterator() = default;
|
||||
SPROUT_CONSTEXPR reduct_iterator(reduct_iterator const& other)
|
||||
: current(other.current)
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR reduct_iterator(iterator_type it)
|
||||
: current(it)
|
||||
{}
|
||||
template<typename U, typename V>
|
||||
SPROUT_CONSTEXPR reduct_iterator(reduct_iterator<U, V> const& it)
|
||||
: current(it.base())
|
||||
{}
|
||||
template<typename U, typename V>
|
||||
reduct_iterator& operator=(reduct_iterator<U, V> const& it) {
|
||||
reduct_iterator temp(it);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
SPROUT_CONSTEXPR iterator_type base() const {
|
||||
return current;
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return *current;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return &*current;
|
||||
}
|
||||
reduct_iterator& operator++() {
|
||||
--current;
|
||||
return *this;
|
||||
}
|
||||
reduct_iterator operator++(int) {
|
||||
reduct_iterator result(*this);
|
||||
--current;
|
||||
return result;
|
||||
}
|
||||
reduct_iterator& operator--() {
|
||||
++current;
|
||||
return *this;
|
||||
}
|
||||
reduct_iterator operator--(int) {
|
||||
reduct_iterator temp(*this);
|
||||
++current;
|
||||
return temp;
|
||||
}
|
||||
SPROUT_CONSTEXPR reduct_iterator operator+(difference_type n) const {
|
||||
return reduct_iterator(current + n);
|
||||
}
|
||||
SPROUT_CONSTEXPR reduct_iterator operator-(difference_type n) const {
|
||||
return reduct_iterator(current - n);
|
||||
}
|
||||
reduct_iterator& operator+=(difference_type n) {
|
||||
reduct_iterator temp(current + n);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
reduct_iterator& operator-=(difference_type n) {
|
||||
reduct_iterator temp(current - n);
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
|
||||
return current[n];
|
||||
}
|
||||
SPROUT_CONSTEXPR reduct_iterator next() const {
|
||||
return reduct_iterator(sprout::next(current));
|
||||
}
|
||||
SPROUT_CONSTEXPR reduct_iterator prev() const {
|
||||
return reduct_iterator(sprout::prev(current));
|
||||
}
|
||||
void swap(reduct_iterator& other)
|
||||
SPROUT_NOEXCEPT_EXPR(
|
||||
SPROUT_NOEXCEPT_EXPR(swap(current, other.current))
|
||||
)
|
||||
{
|
||||
swap(current, other.current);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
operator==(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return lhs.base() == rhs.base();
|
||||
}
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
operator!=(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
operator<(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return lhs.base() < rhs.base();
|
||||
}
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
operator>(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return rhs < lhs;
|
||||
}
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
operator<=(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
operator>=(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
template<typename Iterator1, typename Category1, typename Iterator2, typename Category2>
|
||||
inline SPROUT_CONSTEXPR decltype(std::declval<Iterator1>() - std::declval<Iterator2>())
|
||||
operator-(testspr::reduct_iterator<Iterator1, Category1> const& lhs, testspr::reduct_iterator<Iterator2, Category2> const& rhs) {
|
||||
return lhs.base() - rhs.base();
|
||||
}
|
||||
template<typename Iterator, typename Category>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, Category>
|
||||
operator+(
|
||||
typename testspr::reduct_iterator<Iterator, Category>::difference_type n,
|
||||
testspr::reduct_iterator<Iterator, Category> const& it
|
||||
)
|
||||
{
|
||||
return it + n;
|
||||
}
|
||||
|
||||
//
|
||||
// make_reduct_iterator
|
||||
//
|
||||
template<typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator>
|
||||
make_reduct_iterator(Iterator it) {
|
||||
return testspr::reduct_iterator<Iterator>(it);
|
||||
}
|
||||
template<typename Category, typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, Category>
|
||||
make_reduct_iterator(Iterator it) {
|
||||
return testspr::reduct_iterator<Iterator, Category>(it);
|
||||
}
|
||||
|
||||
//
|
||||
// reduct_input
|
||||
// reduct_forward
|
||||
// reduct_bidirectional
|
||||
// reduct_random_access
|
||||
//
|
||||
template<typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, std::input_iterator_tag>
|
||||
reduct_input(Iterator it) {
|
||||
return testspr::reduct_iterator<Iterator, std::input_iterator_tag>(it);
|
||||
}
|
||||
template<typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, std::forward_iterator_tag>
|
||||
reduct_forward(Iterator it) {
|
||||
return testspr::reduct_iterator<Iterator, std::forward_iterator_tag>(it);
|
||||
}
|
||||
template<typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, std::bidirectional_iterator_tag>
|
||||
reduct_bidirectional(Iterator it) {
|
||||
return testspr::reduct_iterator<Iterator, std::bidirectional_iterator_tag>(it);
|
||||
}
|
||||
template<typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, std::random_access_iterator_tag>
|
||||
reduct_random_access(Iterator it) {
|
||||
return testspr::reduct_iterator<Iterator, std::random_access_iterator_tag>(it);
|
||||
}
|
||||
|
||||
//
|
||||
// swap
|
||||
//
|
||||
template<typename Category, typename Iterator>
|
||||
inline void
|
||||
swap(testspr::reduct_iterator<Iterator, Category>& lhs, testspr::reduct_iterator<Iterator, Category>& rhs)
|
||||
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
//
|
||||
// iterator_distance
|
||||
//
|
||||
template<typename Category, typename Iterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<testspr::reduct_iterator<Iterator, Category> >::difference_type
|
||||
iterator_distance(testspr::reduct_iterator<Iterator, Category> first, testspr::reduct_iterator<Iterator, Category> last) {
|
||||
return sprout::distance(first.base(), last.base());
|
||||
}
|
||||
|
||||
//
|
||||
// iterator_next
|
||||
//
|
||||
template<typename Category, typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, Category>
|
||||
iterator_next(testspr::reduct_iterator<Iterator, Category> const& it) {
|
||||
return it.next();
|
||||
}
|
||||
template<typename Category, typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, Category>
|
||||
iterator_next(
|
||||
testspr::reduct_iterator<Iterator, Category> const& it,
|
||||
typename testspr::reduct_iterator<Iterator, Category>::difference_type n
|
||||
)
|
||||
{
|
||||
return testspr::reduct_iterator<Iterator, Category>(sprout::next(it.base(), n));
|
||||
}
|
||||
|
||||
//
|
||||
// iterator_prev
|
||||
//
|
||||
template<typename Category, typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, Category>
|
||||
iterator_prev(testspr::reduct_iterator<Iterator, Category> const& it) {
|
||||
return it.prev();
|
||||
}
|
||||
template<typename Category, typename Iterator>
|
||||
inline SPROUT_CONSTEXPR testspr::reduct_iterator<Iterator, Category>
|
||||
iterator_prev(
|
||||
testspr::reduct_iterator<Iterator, Category> const& it,
|
||||
typename testspr::reduct_iterator<Iterator, Category>::difference_type n
|
||||
)
|
||||
{
|
||||
return testspr::reduct_iterator<Iterator, Category>(sprout::next(it.base(), n));
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
#endif // #ifndef TESTSPR_ITERATOR_HPP
|
125
testspr/range.hpp
Normal file
125
testspr/range.hpp
Normal file
|
@ -0,0 +1,125 @@
|
|||
#ifndef TESTSPR_RANGE_HPP
|
||||
#define TESTSPR_RANGE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/pit.hpp>
|
||||
#include <sprout/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/range/adaptor/detail/adapted_range_default.hpp>
|
||||
#include <sprout/range/algorithm/copy.hpp>
|
||||
#include <sprout/type_traits/lvalue_reference.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/utility/lvalue_forward.hpp>
|
||||
#include <testspr/iterator.hpp>
|
||||
|
||||
namespace testspr {
|
||||
namespace range {
|
||||
//
|
||||
// reducted_range
|
||||
//
|
||||
template<typename Range, typename Category = typename testspr::reduct_iterator<typename sprout::container_traits<Range>::iterator>::iterator_category>
|
||||
class reducted_range
|
||||
: public sprout::adaptors::detail::adapted_range_default<
|
||||
Range,
|
||||
testspr::reduct_iterator<typename sprout::container_traits<Range>::iterator, Category>
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef sprout::adaptors::detail::adapted_range_default<
|
||||
Range,
|
||||
testspr::reduct_iterator<typename sprout::container_traits<Range>::iterator, Category>
|
||||
> base_type;
|
||||
typedef typename base_type::range_type range_type;
|
||||
typedef typename base_type::iterator iterator;
|
||||
public:
|
||||
reducted_range() = default;
|
||||
reducted_range(reducted_range const&) = default;
|
||||
explicit SPROUT_CONSTEXPR reducted_range(range_type& range)
|
||||
: base_type(
|
||||
iterator(sprout::end(range)),
|
||||
iterator(sprout::begin(range))
|
||||
)
|
||||
{}
|
||||
};
|
||||
|
||||
//
|
||||
// make_reduct_range
|
||||
//
|
||||
template<typename Range>
|
||||
inline SPROUT_CONSTEXPR testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
|
||||
>
|
||||
make_reduct_range(Range&& rng) {
|
||||
return testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
|
||||
>(
|
||||
sprout::lvalue_forward<Range>(rng)
|
||||
);
|
||||
}
|
||||
template<typename Category, typename Range>
|
||||
inline SPROUT_CONSTEXPR testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type,
|
||||
Category
|
||||
>
|
||||
make_reduct_range(Range&& rng) {
|
||||
return testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type,
|
||||
Category
|
||||
>(
|
||||
sprout::lvalue_forward<Range>(rng)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// reduct_input
|
||||
// reduct_forward
|
||||
// reduct_bidirectional
|
||||
// reduct_random_access
|
||||
//
|
||||
template<typename Range>
|
||||
inline SPROUT_CONSTEXPR testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type,
|
||||
std::input_iterator_tag
|
||||
>
|
||||
reduct_input(Range&& rng) {
|
||||
return testspr::range::make_reduct_range<std::input_iterator_tag>(sprout::forward<Range>(rng));
|
||||
}
|
||||
template<typename Range>
|
||||
inline SPROUT_CONSTEXPR testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type,
|
||||
std::forward_iterator_tag
|
||||
>
|
||||
reduct_forward(Range&& rng) {
|
||||
return testspr::range::make_reduct_range<std::forward_iterator_tag>(sprout::forward<Range>(rng));
|
||||
}
|
||||
template<typename Range>
|
||||
inline SPROUT_CONSTEXPR testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type,
|
||||
std::bidirectional_iterator_tag
|
||||
>
|
||||
reduct_bidirectional(Range&& rng) {
|
||||
return testspr::range::make_reduct_range<std::bidirectional_iterator_tag>(sprout::forward<Range>(rng));
|
||||
}
|
||||
template<typename Range>
|
||||
inline SPROUT_CONSTEXPR testspr::range::reducted_range<
|
||||
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type,
|
||||
std::random_access_iterator_tag
|
||||
>
|
||||
reduct_random_access(Range&& rng) {
|
||||
return testspr::range::make_reduct_range<std::random_access_iterator_tag>(sprout::forward<Range>(rng));
|
||||
}
|
||||
} // namespace range
|
||||
} // namespace testspr
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// container_construct_traits
|
||||
//
|
||||
template<typename Range, typename Category>
|
||||
struct container_construct_traits<testspr::range::reducted_range<Range, Category> >
|
||||
: public sprout::container_construct_traits<typename testspr::range::reducted_range<Range, Category>::base_type>
|
||||
{};
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef TESTSPR_RANGE_HPP
|
|
@ -1,357 +1,12 @@
|
|||
#ifndef TESTSPR_TOOLS_HPP
|
||||
#define TESTSPR_TOOLS_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/container.hpp>
|
||||
#ifdef TESTSPR_CONFIG_ENABLE_STATIC_WARNING
|
||||
# include <boost/serialization/static_warning.hpp>
|
||||
#endif
|
||||
|
||||
//
|
||||
// TESTSPR_STATIC_ASSERT
|
||||
// TESTSPR_ASSERT
|
||||
// TESTSPR_BOTH_ASSERT
|
||||
//
|
||||
#define TESTSPR_STATIC_ASSERT(expr) static_assert(expr, #expr)
|
||||
#define TESTSPR_ASSERT(expr) assert(expr)
|
||||
#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_ASSERT(expr) TESTSPR_STATIC_ASSERT(expr); TESTSPR_ASSERT(expr)
|
||||
#else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_ASSERT(expr) TESTSPR_ASSERT(expr)
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
|
||||
//
|
||||
// TESTSPR_STATIC_WARNING
|
||||
//
|
||||
#ifdef TESTSPR_CONFIG_ENABLE_STATIC_WARNING
|
||||
# define TESTSPR_STATIC_WARNING(expr) BOOST_STATIC_WARNING(expr)
|
||||
#else
|
||||
# define TESTSPR_STATIC_WARNING(expr)
|
||||
#endif
|
||||
|
||||
//
|
||||
// TESTSPR_STATIC_UNCHECKED
|
||||
// TESTSPR_UNCHECKED
|
||||
// TESTSPR_BOTH_UNCHECKED
|
||||
//
|
||||
#define TESTSPR_STATIC_UNCHECKED(expr) TESTSPR_STATIC_WARNING(expr)
|
||||
#define TESTSPR_UNCHECKED(expr) (expr)
|
||||
#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_UNCHECKED(expr) TESTSPR_STATIC_UNCHECKED(expr); TESTSPR_UNCHECKED(expr)
|
||||
#else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
# define TESTSPR_BOTH_UNCHECKED(expr) TESTSPR_UNCHECKED(expr)
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR
|
||||
|
||||
namespace testspr {
|
||||
//
|
||||
// do_nothing
|
||||
//
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
do_nothing(T const&) SPROUT_NOEXCEPT {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// is_even
|
||||
//
|
||||
template<typename T>
|
||||
struct is_even {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& t) const { return t % 2 == 0; }
|
||||
};
|
||||
//
|
||||
// is_odd
|
||||
//
|
||||
template<typename T>
|
||||
struct is_odd {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& t) const { return t % 2 != 0; }
|
||||
};
|
||||
//
|
||||
// is_multiple_of
|
||||
//
|
||||
template<typename T, typename U = T>
|
||||
struct is_multiple_of {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef U second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& t, U const& u) const { return t % u == 0; }
|
||||
};
|
||||
|
||||
//
|
||||
// less
|
||||
//
|
||||
template<typename T>
|
||||
struct less {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs < rhs; }
|
||||
};
|
||||
//
|
||||
// greater
|
||||
//
|
||||
template<typename T>
|
||||
struct greater {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs > rhs; }
|
||||
};
|
||||
//
|
||||
// equal_to
|
||||
//
|
||||
template<typename T>
|
||||
struct equal_to {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs == rhs; }
|
||||
};
|
||||
//
|
||||
// mod_less
|
||||
//
|
||||
template<typename T, T mod>
|
||||
struct mod_less {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR bool operator()(T const& lhs, T const& rhs) const { return lhs % mod < rhs % mod; }
|
||||
};
|
||||
|
||||
//
|
||||
// less_than
|
||||
//
|
||||
template<typename T>
|
||||
struct less_than {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
T value;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR less_than(T const& value) : value(value) {}
|
||||
SPROUT_CONSTEXPR bool operator()(T const& x) const { return x < value; }
|
||||
};
|
||||
//
|
||||
// greater_than
|
||||
//
|
||||
template<typename T>
|
||||
struct greater_than {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef bool result_type;
|
||||
public:
|
||||
T value;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR greater_than(T const& value) : value(value) {}
|
||||
SPROUT_CONSTEXPR bool operator()(T const& x) const { return x > value; }
|
||||
};
|
||||
|
||||
//
|
||||
// x2
|
||||
//
|
||||
template<typename T>
|
||||
struct x2 {
|
||||
public:
|
||||
typedef T argument_type;
|
||||
typedef T result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T operator()(T const& t) const { return t + t; }
|
||||
};
|
||||
|
||||
//
|
||||
// plus
|
||||
//
|
||||
template<typename T>
|
||||
struct plus {
|
||||
public:
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef T result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T operator()(T const& lhs, T const& rhs) const { return lhs + rhs; }
|
||||
};
|
||||
|
||||
//
|
||||
// gen_iota
|
||||
//
|
||||
template<typename T>
|
||||
struct gen_iota {
|
||||
public:
|
||||
struct result {
|
||||
public:
|
||||
T val;
|
||||
gen_iota gen;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T const& generated_value() const { return val; }
|
||||
SPROUT_CONSTEXPR gen_iota const& next_generator() const { return gen; }
|
||||
};
|
||||
private:
|
||||
T val;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR gen_iota(T const& val = T())
|
||||
: val(val)
|
||||
{}
|
||||
SPROUT_CONSTEXPR result operator()() const { return result{val, gen_iota(val + 1)}; }
|
||||
};
|
||||
//
|
||||
// unf_iota
|
||||
//
|
||||
template<typename T>
|
||||
struct unf_iota {
|
||||
public:
|
||||
struct result {
|
||||
public:
|
||||
T val;
|
||||
public:
|
||||
SPROUT_CONSTEXPR T const& generated_value() const { return val; }
|
||||
SPROUT_CONSTEXPR T next_generator() const { return val + 1; }
|
||||
};
|
||||
public:
|
||||
SPROUT_CONSTEXPR result operator()(T const& val) const { return result{val}; }
|
||||
};
|
||||
|
||||
//
|
||||
// x2_visitor
|
||||
//
|
||||
template<typename R = void>
|
||||
class x2_visitor {
|
||||
public:
|
||||
typedef R result_type;
|
||||
public:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR result_type operator()(T const& t) const { return static_cast<result_type>(t + t); }
|
||||
};
|
||||
//
|
||||
// x2_assign_visitor
|
||||
//
|
||||
template<typename R = void>
|
||||
class x2_assign_visitor {
|
||||
public:
|
||||
typedef R result_type;
|
||||
public:
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR result_type operator()(T& t) const { return static_cast<result_type>(t += t); }
|
||||
};
|
||||
|
||||
//
|
||||
// distance
|
||||
//
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
distance(InputIterator first, InputIterator last) {
|
||||
return first == last ? 0
|
||||
: 1 + testspr::distance(first + 1, last)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// equal
|
||||
//
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) {
|
||||
return first1 == last1 ? first2 == last2
|
||||
: first2 == last2 ? false
|
||||
: !(*first1 == *first2) ? false
|
||||
: testspr::equal(first1 + 1, last1, first2 + 1, last2)
|
||||
;
|
||||
}
|
||||
template<typename Range1, typename Range2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
equal(Range1 const& range1, Range2 const& range2) {
|
||||
return testspr::equal(sprout::begin(range1), sprout::end(range1), sprout::begin(range2), sprout::end(range2));
|
||||
}
|
||||
|
||||
//
|
||||
// is_found
|
||||
//
|
||||
template<class InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_found(InputIterator first, InputIterator last, T const& value) {
|
||||
return first == last ? false
|
||||
: *first == value ? true
|
||||
: testspr::is_found(first + 1, last, value)
|
||||
;
|
||||
}
|
||||
template<typename Range, typename T>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_found(Range const& range, T const& value) {
|
||||
return testspr::is_found(sprout::begin(range), sprout::end(range), value);
|
||||
}
|
||||
|
||||
//
|
||||
// count
|
||||
//
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count(InputIterator first, InputIterator last, T const& value) {
|
||||
return first == last ? 0
|
||||
: (*first == value ? 1 : 0) + testspr::count(first + 1, last, value)
|
||||
;
|
||||
}
|
||||
template<typename Range, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<typename Range::const_iterator>::difference_type
|
||||
count(Range const& range, T const& value) {
|
||||
return testspr::count(sprout::begin(range), sprout::end(range), value);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_permutation_impl(
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
ForwardIterator1 first1_, ForwardIterator2 first2_
|
||||
)
|
||||
{
|
||||
return first1_ == last1 && first2_ == last2 ? true
|
||||
: testspr::count(first1, last1, *first1_) != testspr::count(first2, first2 + testspr::distance(first1, last1), *first1_)
|
||||
? false
|
||||
: testspr::detail::is_permutation_impl(first1, last1, first2, last2, first1_ + 1, first2_ + 1)
|
||||
;
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// is_permutation
|
||||
//
|
||||
template<typename ForwardIterator1, typename ForwardIterator2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_permutation(
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2
|
||||
)
|
||||
{
|
||||
return testspr::detail::is_permutation_impl(first1, last1, first2, last2, first1, first2);
|
||||
}
|
||||
template<typename Range1, typename Range2>
|
||||
inline SPROUT_CONSTEXPR bool
|
||||
is_permutation(Range1 const& range1, Range2 const& range2) {
|
||||
return testspr::is_permutation(
|
||||
sprout::begin(range1), sprout::end(range1),
|
||||
sprout::begin(range2), sprout::end(range2)
|
||||
);
|
||||
}
|
||||
} // namespace testspr
|
||||
#include <testspr/assert.hpp>
|
||||
#include <testspr/functional.hpp>
|
||||
#include <testspr/algorithm.hpp>
|
||||
#include <testspr/iterator.hpp>
|
||||
#include <testspr/range.hpp>
|
||||
#include <testspr/typeinfo.hpp>
|
||||
#include <testspr/print.hpp>
|
||||
|
||||
#endif // #ifndef TESTSPR_TOOLS_HPP
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue