Skip to content

Commit a9189de

Browse files
authored
Merge pull request #13 from njoy/feature/std-ranges-part4
Feature/std ranges part4
2 parents 48c6ab0 + ae30f85 commit a9189de

19 files changed

+2201
-13
lines changed

cmake/unit_testing.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ endfunction()
2828

2929
add_subdirectory( src/tools/Log/test )
3030

31+
add_subdirectory( src/tools/std20/algorithm/test )
3132
add_subdirectory( src/tools/std20/concepts/test )
3233
add_subdirectory( src/tools/std20/functional/test )
3334
add_subdirectory( src/tools/std20/iterator/concepts/test )
@@ -36,3 +37,4 @@ add_subdirectory( src/tools/std20/iterator/reverse_iterator/test )
3637
add_subdirectory( src/tools/std20/ranges/access/test )
3738
add_subdirectory( src/tools/std20/ranges/concepts/test )
3839
add_subdirectory( src/tools/std20/type_traits/test )
40+
add_subdirectory( src/tools/std20/views/test )

src/tools/std20/algorithm.hpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// nanorange/algorithm.hpp
2+
//
3+
// Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com)
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
7+
#ifndef NANORANGE_ALGORITHM_HPP_INCLUDED
8+
#define NANORANGE_ALGORITHM_HPP_INCLUDED
9+
10+
// Algorithms reimplemented in Nanorange
11+
//#include <nanorange/algorithm/adjacent_find.hpp>
12+
//#include <nanorange/algorithm/all_of.hpp>
13+
//#include <nanorange/algorithm/any_of.hpp>
14+
//#include <nanorange/algorithm/binary_search.hpp>
15+
//#include <nanorange/algorithm/clamp.hpp>
16+
//#include <nanorange/algorithm/copy.hpp>
17+
//#include <nanorange/algorithm/count.hpp>
18+
#include "tools/std20/algorithm/equal.hpp"
19+
//#include <nanorange/algorithm/equal_range.hpp>
20+
//#include <nanorange/algorithm/fill.hpp>
21+
//#include <nanorange/algorithm/fill_n.hpp>
22+
//#include <nanorange/algorithm/find.hpp>
23+
//#include <nanorange/algorithm/find_end.hpp>
24+
//#include <nanorange/algorithm/find_first_of.hpp>
25+
//#include <nanorange/algorithm/for_each.hpp>
26+
//#include <nanorange/algorithm/generate.hpp>
27+
//#include <nanorange/algorithm/generate_n.hpp>
28+
//#include <nanorange/algorithm/includes.hpp>
29+
//#include <nanorange/algorithm/inplace_merge.hpp>
30+
//#include <nanorange/algorithm/is_heap.hpp>
31+
//#include <nanorange/algorithm/is_heap_until.hpp>
32+
//#include <nanorange/algorithm/is_partitioned.hpp>
33+
//#include <nanorange/algorithm/is_permutation.hpp>
34+
//#include <nanorange/algorithm/is_sorted.hpp>
35+
//#include <nanorange/algorithm/is_sorted_until.hpp>
36+
//#include <nanorange/algorithm/lexicographical_compare.hpp>
37+
//#include <nanorange/algorithm/lower_bound.hpp>
38+
//#include <nanorange/algorithm/make_heap.hpp>
39+
//#include <nanorange/algorithm/max.hpp>
40+
//#include <nanorange/algorithm/max_element.hpp>
41+
//#include <nanorange/algorithm/merge.hpp>
42+
//#include <nanorange/algorithm/min.hpp>
43+
//#include <nanorange/algorithm/min_element.hpp>
44+
//#include <nanorange/algorithm/minmax.hpp>
45+
//#include <nanorange/algorithm/minmax_element.hpp>
46+
//#include <nanorange/algorithm/mismatch.hpp>
47+
//#include <nanorange/algorithm/move.hpp>
48+
//#include <nanorange/algorithm/next_permutation.hpp>
49+
//#include <nanorange/algorithm/none_of.hpp>
50+
//#include <nanorange/algorithm/nth_element.hpp>
51+
//#include <nanorange/algorithm/partial_sort.hpp>
52+
//#include <nanorange/algorithm/partial_sort_copy.hpp>
53+
//#include <nanorange/algorithm/partition.hpp>
54+
//#include <nanorange/algorithm/partition_copy.hpp>
55+
//#include <nanorange/algorithm/partition_point.hpp>
56+
//#include <nanorange/algorithm/pop_heap.hpp>
57+
//#include <nanorange/algorithm/prev_permutation.hpp>
58+
//#include <nanorange/algorithm/push_heap.hpp>
59+
//#include <nanorange/algorithm/remove.hpp>
60+
//#include <nanorange/algorithm/remove_copy.hpp>
61+
//#include <nanorange/algorithm/remove_copy_if.hpp>
62+
//#include <nanorange/algorithm/remove_if.hpp>
63+
//#include <nanorange/algorithm/replace.hpp>
64+
//#include <nanorange/algorithm/replace_copy.hpp>
65+
//#include <nanorange/algorithm/replace_copy_if.hpp>
66+
//#include <nanorange/algorithm/replace_if.hpp>
67+
//#include <nanorange/algorithm/reverse.hpp>
68+
//#include <nanorange/algorithm/reverse_copy.hpp>
69+
//#include <nanorange/algorithm/rotate.hpp>
70+
//#include <nanorange/algorithm/rotate_copy.hpp>
71+
//#include <nanorange/algorithm/search.hpp>
72+
//#include <nanorange/algorithm/search_n.hpp>
73+
//#include <nanorange/algorithm/set_difference.hpp>
74+
//#include <nanorange/algorithm/set_intersection.hpp>
75+
//#include <nanorange/algorithm/set_symmetric_difference.hpp>
76+
//#include <nanorange/algorithm/set_union.hpp>
77+
//#include <nanorange/algorithm/sample.hpp>
78+
//#include <nanorange/algorithm/shuffle.hpp>
79+
//#include <nanorange/algorithm/sort.hpp>
80+
//#include <nanorange/algorithm/sort_heap.hpp>
81+
//#include <nanorange/algorithm/stable_partition.hpp>
82+
//#include <nanorange/algorithm/stable_sort.hpp>
83+
//#include <nanorange/algorithm/swap_ranges.hpp>
84+
//#include <nanorange/algorithm/transform.hpp>
85+
//#include <nanorange/algorithm/unique.hpp>
86+
//#include <nanorange/algorithm/unique_copy.hpp>
87+
//#include <nanorange/algorithm/upper_bound.hpp>
88+
89+
#endif

src/tools/std20/algorithm/equal.hpp

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// nanorange/algorithm/equal.hpp
2+
//
3+
// Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com)
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
7+
#ifndef NANORANGE_ALGORITHM_EQUAL_HPP_INCLUDED
8+
#define NANORANGE_ALGORITHM_EQUAL_HPP_INCLUDED
9+
10+
#include "tools/std20/iterator/operations.hpp"
11+
#include "tools/std20/ranges.hpp"
12+
13+
NANO_BEGIN_NAMESPACE
14+
15+
namespace detail {
16+
17+
struct equal_fn {
18+
private:
19+
template <typename I1, typename S1, typename I2, typename S2, typename Pred,
20+
typename Proj1, typename Proj2>
21+
static constexpr bool impl4(I1 first1, S1 last1, I2 first2, S2 last2,
22+
Pred& pred, Proj1& proj1, Proj2& proj2)
23+
{
24+
while (first1 != last1 && first2 != last2) {
25+
if (!nano::invoke(pred, nano::invoke(proj1, *first1),
26+
nano::invoke(proj2, *first2))) {
27+
return false;
28+
}
29+
++first1;
30+
++first2;
31+
}
32+
33+
return first1 == last1 && first2 == last2;
34+
}
35+
36+
template <typename I1, typename S1, typename I2, typename Pred,
37+
typename Proj1, typename Proj2>
38+
static constexpr bool impl3(I1 first1, S1 last1, I2 first2, Pred pred,
39+
Proj1& proj1, Proj2& proj2)
40+
{
41+
while (first1 != last1) {
42+
if (!nano::invoke(pred, nano::invoke(proj1, *first1),
43+
nano::invoke(proj2, *first2))) {
44+
return false;
45+
}
46+
++first1;
47+
++first2;
48+
}
49+
50+
return true;
51+
}
52+
53+
public:
54+
// Four-legged, sized sentinels
55+
template <typename I1, typename S1, typename I2, typename S2,
56+
typename Pred = ranges::equal_to, typename Proj1 = identity,
57+
typename Proj2 = identity>
58+
constexpr std::enable_if_t<
59+
input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> &&
60+
sentinel_for<S2, I2> &&
61+
indirectly_comparable<I1, I2, Pred, Proj1, Proj2> &&
62+
sized_sentinel_for<S1, I1> && sized_sentinel_for<S2, I2>,
63+
bool>
64+
operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = Pred{},
65+
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
66+
{
67+
if (last1 - first1 != last2 - first2) {
68+
return false;
69+
}
70+
71+
// Ranges are the same size, so call the 3-legged version
72+
// and save ourselves a comparison
73+
return equal_fn::impl3(std::move(first1), std::move(last1),
74+
std::move(first2), pred,
75+
proj1, proj2);
76+
}
77+
78+
// Four-legged, unsized sentinels
79+
template <typename I1, typename S1, typename I2, typename S2,
80+
typename Pred = ranges::equal_to, typename Proj1 = identity,
81+
typename Proj2 = identity>
82+
constexpr std::enable_if_t<
83+
input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> &&
84+
sentinel_for<S2, I2> &&
85+
indirectly_comparable<I1, I2, Pred, Proj1, Proj2> &&
86+
!(sized_sentinel_for<S1, I1> && sized_sentinel_for<S2, I2>),
87+
bool>
88+
operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = Pred{},
89+
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
90+
{
91+
return equal_fn::impl4(std::move(first1), std::move(last1),
92+
std::move(first2), std::move(last2),
93+
pred, proj1, proj2);
94+
}
95+
96+
// Three legged
97+
template <typename I1, typename S1, typename I2, typename Pred = ranges::equal_to,
98+
typename Proj1 = identity, typename Proj2 = identity>
99+
NANO_DEPRECATED constexpr std::enable_if_t<
100+
input_iterator<I1> && sentinel_for<S1, I1> &&
101+
input_iterator<std::decay_t<I2>> &&
102+
!input_range<I2> &&
103+
indirectly_comparable<I1, std::decay_t<I2>, Pred, Proj1, Proj2>,
104+
bool>
105+
operator()(I1 first1, S1 last1, I2 first2, Pred pred = Pred{},
106+
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
107+
{
108+
return equal_fn::impl3(std::move(first1), std::move(last1),
109+
std::forward<I2>(first2), pred, proj1, proj2);
110+
}
111+
112+
// Two ranges, both sized
113+
template <typename Rng1, typename Rng2, typename Pred = ranges::equal_to,
114+
typename Proj1 = identity, typename Proj2 = identity>
115+
constexpr std::enable_if_t<
116+
input_range<Rng1> && input_range<Rng2> &&
117+
indirectly_comparable<iterator_t<Rng1>, iterator_t<Rng2>, Pred,
118+
Proj1, Proj2> &&
119+
sized_range<Rng1> && sized_range<Rng2>,
120+
bool>
121+
operator()(Rng1&& rng1, Rng2&& rng2, Pred pred = Pred{},
122+
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
123+
{
124+
if (nano::distance(rng1) != nano::distance(rng2)) {
125+
return false;
126+
}
127+
128+
return equal_fn::impl3(nano::begin(rng1), nano::end(rng1),
129+
nano::begin(rng2), pred, proj1, proj2);
130+
}
131+
132+
// Two ranges, not both sized
133+
template <typename Rng1, typename Rng2, typename Pred = ranges::equal_to,
134+
typename Proj1 = identity, typename Proj2 = identity>
135+
constexpr std::enable_if_t<
136+
input_range<Rng1> && input_range<Rng2> &&
137+
indirectly_comparable<iterator_t<Rng1>, iterator_t<Rng2>, Pred,
138+
Proj1, Proj2> &&
139+
!(sized_range<Rng1> && sized_range<Rng2>),
140+
bool>
141+
operator()(Rng1&& rng1, Rng2&& rng2, Pred pred = Pred{},
142+
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
143+
{
144+
return equal_fn::impl4(nano::begin(rng1), nano::end(rng1),
145+
nano::begin(rng2), nano::end(rng2),
146+
pred, proj1, proj2);
147+
}
148+
149+
// Range and a half
150+
template <typename Rng1, typename I2, typename Pred = ranges::equal_to,
151+
typename Proj1 = identity, typename Proj2 = identity>
152+
NANO_DEPRECATED constexpr std::enable_if_t<
153+
input_range<Rng1> && input_iterator<std::decay_t<I2>> &&
154+
!input_range<I2> &&
155+
indirectly_comparable<iterator_t<Rng1>, std::decay_t<I2>, Pred, Proj1, Proj2>,
156+
bool>
157+
operator()(Rng1&& rng1, I2&& first2, Pred pred = Pred{},
158+
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
159+
{
160+
return equal_fn::impl3(nano::begin(rng1), nano::end(rng1),
161+
std::forward<I2>(first2), pred, proj1, proj2);
162+
}
163+
};
164+
165+
} // namespace detail
166+
167+
NANO_INLINE_VAR(detail::equal_fn, equal)
168+
169+
NANO_END_NAMESPACE
170+
171+
#endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_cpp_test( std20.algorithm.equal equal.test.cpp )
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// include Catch2
2+
#include <catch2/catch_test_macros.hpp>
3+
4+
// what we are testing
5+
#include "tools/std20/algorithm.hpp"
6+
7+
// other includes
8+
9+
// convenience typedefs
10+
//using namespace njoy::tools;
11+
namespace std20 = nano;
12+
13+
SCENARIO( "equal" ) {
14+
15+
int a[] = { 1, 2, 3 };
16+
int b[] = { 1, 2, 3 };
17+
int c[] = { 1, 2 };
18+
int d[] = { 3, 2, 1 };
19+
20+
std::vector< int > va = { 1, 2, 3 };
21+
std::vector< int > vb = { 1, 2, 3 };
22+
std::vector< int > vc = { 1, 2 };
23+
std::vector< int > vd = { 3, 2, 1 };
24+
25+
// without predicate
26+
CHECK( std20::ranges::equal( a, a ) );
27+
CHECK( std20::ranges::equal( a, b ) );
28+
CHECK( ! std20::ranges::equal( a, c ) );
29+
CHECK( ! std20::ranges::equal( a, d ) );
30+
CHECK( std20::ranges::equal( b, a ) );
31+
CHECK( ! std20::ranges::equal( c, a ) );
32+
CHECK( ! std20::ranges::equal( d, a ) );
33+
34+
CHECK( std20::ranges::equal( a, a + 3, a, a + 3 ) );
35+
CHECK( std20::ranges::equal( a, a + 3, b, b + 3 ) );
36+
CHECK( ! std20::ranges::equal( a, a + 3, c, c + 2 ) );
37+
CHECK( !std20::ranges::equal( a, a + 3, d, d + 3 ) );
38+
CHECK( std20::ranges::equal( b, b + 3, a, a + 3 ) );
39+
CHECK( ! std20::ranges::equal( c, c + 2, a, a + 3 ) );
40+
CHECK( !std20::ranges::equal( d, d + 3, a, a + 3 ) );
41+
42+
CHECK( std20::ranges::equal( va, va ) );
43+
CHECK( std20::ranges::equal( va, vb ) );
44+
CHECK( ! std20::ranges::equal( va, vc ) );
45+
CHECK( ! std20::ranges::equal( va, vd ) );
46+
CHECK( std20::ranges::equal( vb, va ) );
47+
CHECK( ! std20::ranges::equal( vc, va ) );
48+
CHECK( ! std20::ranges::equal( vd, va ) );
49+
50+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( va ), std::end( va ) ) );
51+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( vb ), std::end( vb ) ) );
52+
CHECK( ! std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( vc ), std::end( vc ) ) );
53+
CHECK( !std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( vd ), std::end( vd ) ) );
54+
CHECK( std20::ranges::equal( std::begin( vb ), std::end( vb ), std::begin( va ), std::end( va ) ) );
55+
CHECK( ! std20::ranges::equal( std::begin( vc ), std::end( vc ), std::begin( va ), std::end( va ) ) );
56+
CHECK( !std20::ranges::equal( std::begin( vd ), std::end( vd ), std::begin( va ), std::end( va ) ) );
57+
58+
CHECK( std20::ranges::equal( va, a ) );
59+
CHECK( std20::ranges::equal( va, b ) );
60+
CHECK( ! std20::ranges::equal( va, c ) );
61+
CHECK( ! std20::ranges::equal( va, d ) );
62+
CHECK( std20::ranges::equal( b, va ) );
63+
CHECK( ! std20::ranges::equal( c, va ) );
64+
CHECK( ! std20::ranges::equal( d, va ) );
65+
66+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), a, a + 3 ) );
67+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), b, b + 3 ) );
68+
CHECK( ! std20::ranges::equal( std::begin( va ), std::end( va ), c, c + 2 ) );
69+
CHECK( !std20::ranges::equal( std::begin( va ), std::end( va ), d, d + 3 ) );
70+
CHECK( std20::ranges::equal( b, b + 3, std::begin( va ), std::end( va ) ) );
71+
CHECK( ! std20::ranges::equal( c, c + 2, std::begin( va ), std::end( va ) ) );
72+
CHECK( !std20::ranges::equal( d, d + 3, std::begin( va ), std::end( va ) ) );
73+
74+
// with predicate
75+
CHECK( std20::ranges::equal( a, a + 3, a, a + 3, std::equal_to<int>() ) );
76+
CHECK( std20::ranges::equal( a, a + 3, b, b + 3, std::equal_to<int>() ) );
77+
CHECK( ! std20::ranges::equal( a, a + 3, c, c + 2, std::equal_to<int>() ) );
78+
CHECK( !std20::ranges::equal( a, a + 3, d, d + 3, std::equal_to<int>() ) );
79+
CHECK( std20::ranges::equal( b, b + 3, a, a + 3, std::equal_to<int>() ) );
80+
CHECK( ! std20::ranges::equal( c, c + 2, a, a + 3, std::equal_to<int>() ) );
81+
CHECK( !std20::ranges::equal( d, d + 3, a, a + 3, std::equal_to<int>() ) );
82+
83+
CHECK( std20::ranges::equal( va, va, std::equal_to<int>() ) );
84+
CHECK( std20::ranges::equal( va, vb, std::equal_to<int>() ) );
85+
CHECK( ! std20::ranges::equal( va, vc, std::equal_to<int>() ) );
86+
CHECK( ! std20::ranges::equal( va, vd, std::equal_to<int>() ) );
87+
CHECK( std20::ranges::equal( vb, va, std::equal_to<int>() ) );
88+
CHECK( ! std20::ranges::equal( vc, va, std::equal_to<int>() ) );
89+
CHECK( ! std20::ranges::equal( vd, va, std::equal_to<int>() ) );
90+
91+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( va ), std::end( va ), std::equal_to<int>() ) );
92+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( vb ), std::end( vb ), std::equal_to<int>() ) );
93+
CHECK( ! std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( vc ), std::end( vc ), std::equal_to<int>() ) );
94+
CHECK( !std20::ranges::equal( std::begin( va ), std::end( va ), std::begin( vd ), std::end( vd ), std::equal_to<int>() ) );
95+
CHECK( std20::ranges::equal( std::begin( vb ), std::end( vb ), std::begin( va ), std::end( va ), std::equal_to<int>() ) );
96+
CHECK( ! std20::ranges::equal( std::begin( vc ), std::end( vc ), std::begin( va ), std::end( va ), std::equal_to<int>() ) );
97+
CHECK( !std20::ranges::equal( std::begin( vd ), std::end( vd ), std::begin( va ), std::end( va ), std::equal_to<int>() ) );
98+
99+
CHECK( std20::ranges::equal( va, a, std::equal_to<int>() ) );
100+
CHECK( std20::ranges::equal( va, b, std::equal_to<int>() ) );
101+
CHECK( ! std20::ranges::equal( va, c, std::equal_to<int>() ) );
102+
CHECK( ! std20::ranges::equal( va, d, std::equal_to<int>() ) );
103+
CHECK( std20::ranges::equal( b, va, std::equal_to<int>() ) );
104+
CHECK( ! std20::ranges::equal( c, va, std::equal_to<int>() ) );
105+
CHECK( ! std20::ranges::equal( d, va, std::equal_to<int>() ) );
106+
107+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), a, a + 3, std::equal_to<int>() ) );
108+
CHECK( std20::ranges::equal( std::begin( va ), std::end( va ), b, b + 3, std::equal_to<int>() ) );
109+
CHECK( ! std20::ranges::equal( std::begin( va ), std::end( va ), c, c + 2, std::equal_to<int>() ) );
110+
CHECK( !std20::ranges::equal( std::begin( va ), std::end( va ), d, d + 3, std::equal_to<int>() ) );
111+
CHECK( std20::ranges::equal( b, b + 3, std::begin( va ), std::end( va ), std::equal_to<int>() ) );
112+
CHECK( ! std20::ranges::equal( c, c + 2, std::begin( va ), std::end( va ), std::equal_to<int>() ) );
113+
CHECK( !std20::ranges::equal( d, d + 3, std::begin( va ), std::end( va ), std::equal_to<int>() ) );
114+
} // SCENARIO

0 commit comments

Comments
 (0)