123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #include "simple/support/iterator.hpp"
- #include <vector>
- #include <algorithm>
- #include <cassert>
- using namespace simple::support;
- void Offset()
- {
- std::vector x{10};
- offset_iterator ofi {x};
- while(*ofi != 0) x.push_back(*ofi++ - 1);
- assert(( x == std::vector{10,9,8,7,6,5,4,3,2,1,0} ));
- }
- void OffsetExpander()
- {
- std::vector x{10};
- offset_expander ofe {x};
- offset_expander prev = ofe++;
- while(*prev != 0) *ofe++ = *prev++ - 1;
- assert(( x == std::vector{10,9,8,7,6,5,4,3,2,1,0} ));
- }
- void OutAccumulate()
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- assert(( std::copy_if(x.begin(), x.end(), out_accumulate(0), [](auto x){ return x%2 == 0;} ).accumulator == 30 ));
- assert(( std::copy_if(x.begin(), x.end(), out_accumulate(0), [](auto x){ return x%2 == 1;} ).accumulator == 25 ));
- }
- void OutTransform()
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- auto end = std::copy_if(x.begin(), x.end(),
- out_transform([](auto x){ return x + 2; }, x.begin()),
- [](auto x) { return x%3 == 0; }
- ).out;
- std::vector y{5,8,11};
- assert(( std::equal(x.begin(), end, y.begin(), y.end()) ));
- }
- void OutFilter()
- {
- // omg omg, is transform going to be applied twice, once for filter condition and once again for assignment??
- // do I need to cache the valueeeee omgggg?!
- // no... nothing of sorts... who hurt you so?
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- auto end = std::transform(x.begin(), x.end(),
- out_filter([](auto x){ return x%3 == 0; }, x.begin()),
- [](auto x){ return x + 2; }
- ).out;
- std::vector y{3,6,9,12};
- assert(( std::equal(x.begin(), end, y.begin(), y.end()) ));
- }
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- auto end = std::copy(x.begin(), x.end(),
- out_transform([](auto x){ return x + 2; },
- out_filter([](auto x){ return x%3 == 0; }, x.begin()
- ))).out.out;
- std::vector y{3,6,9,12};
- assert(( std::equal(x.begin(), end, y.begin(), y.end()) ));
- }
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- std::vector y{21,22};
- std::copy(x.begin(), x.end(),
- out_transform([](auto x){ return x + 2; },
- out_filter([](auto x){ return x%3 == 0; },
- offset_expander(y)
- )));
- assert(( y == std::vector{3,6,9,12} ));
- }
- }
- void OutFlattenRange()
- {
- std::vector x {
- std::vector{0},
- std::vector{1,2},
- std::vector{3,4,5,6},
- std::vector{0},
- std::vector{0},
- std::vector{7},
- std::vector{8,9,10},
- std::vector{0}
- };
- std::vector y(10,0);
- std::copy_if(x.begin(), x.end(), out_flatten_range(y.begin()),
- [](auto& x) { return x != std::vector{0}; });
- assert(( y == std::vector{1,2,3,4,5,6,7,8,9,10} ));
- }
- void OutFlattenTuple()
- {
- std::vector x {
- std::tuple{0,0,0},
- std::tuple{1,2,3},
- std::tuple{4,5,6},
- std::tuple{0,0,0},
- std::tuple{0,0,0},
- std::tuple{7,8,9},
- std::tuple{0,0,0},
- };
- std::vector y(9,0);
- std::copy_if(x.begin(), x.end(), out_flatten_tuple(y.begin()),
- [](auto& x) { return x != std::tuple{0,0,0}; });
- assert(( y == std::vector{1,2,3,4,5,6,7,8,9} ));
- }
- void OutInvoke()
- {
- std::vector x {
- std::vector{1,2,3},
- std::vector{1,3,2},
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{3,1,2},
- std::vector{2,3,1},
- std::vector{1,2,3},
- std::vector{3,2,1}
- };
- std::copy_if(x.begin(), x.end(),
- out_invoke([](auto& x) { std::sort(x.begin(), x.end()); }),
- [](auto& x) { return not std::is_sorted(x.begin(), x.end()); }
- );
- assert(( x == std::vector{
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{1,2,3},
- std::vector{1,2,3}
- } ));
- }
- void OutOptional()
- {
- const int a = 1, b = 2, c = 3, d = 4;
- std::vector<const int*> x{&a, nullptr, &b, &c, nullptr, nullptr, nullptr, &d};
- std::vector y(4,0);
- std::copy(x.begin(), x.end(), out_optional(y.begin()));
- assert(( y == std::vector{1,2,3,4} ));
- }
- void OutPartition()
- {
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- auto part = std::copy_if(x.begin(), x.end(),
- out_partition([](auto x) { return x%2 == 0; }, x.begin(), x.begin()),
- [](auto x) { return x > 3; }
- );
- std::vector y{4,6,8,10};
- assert(( std::equal(x.begin(), part.partition_point, y.begin(), y.end()) ));
- std::vector z{4,6,8,10, 5,9,7};
- assert(( std::equal(x.begin(), part.out, z.begin(), z.end()) ));
- assert(( x == std::vector{4,6,8,10, 5,9,7, 8,9,10} ));
- }
- {
- std::vector x{1,2,3,4,5,6,7,8,9,10};
- std::vector y{99,88};
- auto part = std::copy(x.begin(), x.end(),
- out_filter([](auto x) { return x > 3; },
- out_partition([](auto x) { return x%2 == 0; }, offset_iterator(y),
- out_transform([](auto x) { return x + x; },
- offset_expander(y)
- )))).out.partition_point.base();
- std::vector z{8,12,16,20};
- assert(( std::equal(y.begin(), part, z.begin(), z.end()) ));
- std::vector w{10,18,14};
- assert(( std::equal(part, y.end(), w.begin(), w.end()) ));
- assert(( y == std::vector{8,12,16,20, 10,18,14} ));
- }
- }
- int main()
- {
- Offset();
- OffsetExpander();
- OutAccumulate();
- OutTransform();
- OutFilter();
- OutFlattenRange();
- OutFlattenTuple();
- OutInvoke();
- OutOptional();
- OutPartition();
- return 0;
- }
|