fix recursion depth O(logN): some algorithms

This commit is contained in:
bolero-MURAKAMI 2013-01-03 17:01:50 +09:00
commit 5019f6aa96
162 changed files with 3600 additions and 1659 deletions

109
testspr/algorithm.hpp Normal file
View 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
View 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
View 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
View 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
View 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

View file

@ -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