diff --git a/accumulate.hpp b/accumulate.hpp index b96cc2b5..4ca8d600 100644 --- a/accumulate.hpp +++ b/accumulate.hpp @@ -71,7 +71,7 @@ class iter::impl::Accumulator { acc_val{other.acc_val ? new AccumVal(*other.acc_val) : nullptr} {} Iterator& operator=(const Iterator& other) { - if (this == &other) return *this; + if (this == &other) { return *this; } this->sub_iter = other.sub_iter; this->sub_end = other.sub_end; this->accumulate_func = other.accumulate_func; diff --git a/chain.hpp b/chain.hpp index 59369982..66fd0f91 100644 --- a/chain.hpp +++ b/chain.hpp @@ -176,6 +176,7 @@ class iter::impl::ChainedFromIterable { : container(std::forward(in_container)) {} public: + ChainedFromIterable(ChainedFromIterable&&) = default; class Iterator : public std::iterator>> { private: @@ -224,7 +225,7 @@ class iter::impl::ChainedFromIterable { sub_end_p{clone_sub_pointer(other.sub_end_p.get())} {} Iterator& operator=(const Iterator& other) { - if (this == &other) return *this; + if (this == &other) { return *this; } this->top_level_iter = other.top_level_iter; this->top_level_end = other.top_level_end; diff --git a/groupby.hpp b/groupby.hpp index 1da7117e..c551d7a8 100644 --- a/groupby.hpp +++ b/groupby.hpp @@ -80,7 +80,7 @@ class iter::impl::GroupProducer { key_func{other.key_func} {} Iterator& operator=(const Iterator& other) { - if (this == &other) return *this; + if (this == &other) { return *this; } this->sub_iter = other.sub_iter; this->sub_end = other.sub_end; this->item = other.item; diff --git a/internal/iterbase.hpp b/internal/iterbase.hpp index c215d003..20d0fc39 100644 --- a/internal/iterbase.hpp +++ b/internal/iterbase.hpp @@ -54,7 +54,7 @@ namespace iter { template struct ArrowHelper { using type = void; - void operator()(T&) const noexcept { } + void operator()(T&) const noexcept {} }; template @@ -239,8 +239,7 @@ namespace iter { // get() returns a reference to the held item // get_ptr() returns a pointer to the held item // reset() replaces the currently held item - - template + template class DerefHolder { private: static_assert(!std::is_lvalue_reference::value, @@ -283,17 +282,16 @@ namespace iter { } explicit operator bool() const { - return this->item_p; + return static_cast(this->item_p); } }; - // Specialization for when T is an lvalue ref. Keep this in mind - // wherever a T appears. + // Specialization for when T is an lvalue ref template - class DerefHolder::value>> { + class DerefHolder { public: - using reference = T; - using pointer = std::remove_reference_t*; + using reference = T&; + using pointer = T*; private: pointer item_p{}; @@ -309,7 +307,7 @@ namespace iter { return this->item_p; } - void reset(T item) { + void reset(reference item) { this->item_p = &item; } diff --git a/range.hpp b/range.hpp index 74d6bc5d..67a0c267 100644 --- a/range.hpp +++ b/range.hpp @@ -68,7 +68,7 @@ namespace iter { T start_{}; T value_{}; T step_{}; - unsigned long steps_taken{}; + std::size_t steps_taken{}; public: constexpr RangeIterData() noexcept = default; @@ -162,9 +162,8 @@ class iter::impl::Range { const Iterator& lhs, const Iterator& rhs) noexcept { if (rhs.is_end) { return not_equal_to_impl(lhs, rhs, std::is_unsigned{}); - } else { - return not_equal_to_impl(rhs, lhs, std::is_unsigned{}); } + return not_equal_to_impl(rhs, lhs, std::is_unsigned{}); } public: diff --git a/sliding_window.hpp b/sliding_window.hpp index cffc0e0f..11b633d1 100644 --- a/sliding_window.hpp +++ b/sliding_window.hpp @@ -55,7 +55,7 @@ class iter::impl::WindowSlider { while (i < window_sz && this->sub_iter != in_end) { this->window.get().push_back(this->sub_iter); ++i; - if (i != window_sz) ++this->sub_iter; + if (i != window_sz) { ++this->sub_iter; } } } diff --git a/test/SConstruct b/test/SConstruct index e825019c..cbf3cd3c 100644 --- a/test/SConstruct +++ b/test/SConstruct @@ -2,12 +2,11 @@ import os env = Environment( ENV = os.environ, - CXX='c++', CXXFLAGS= ['-g', '-Wall', '-Wextra', '-pedantic', '-std=c++14', '-I/usr/local/include', '-I.'], CPPPATH='..', - LINKFLAGS='-L/usr/local/lib') + LINKFLAGS=['-L/usr/local/lib']) # allows highighting to print to terminal from compiler output env['ENV']['TERM'] = os.environ['TERM'] @@ -44,6 +43,7 @@ progs = Split( zip iteratoriterator + iterbase mixed helpers ''' diff --git a/test/test_iterbase.cpp b/test/test_iterbase.cpp new file mode 100644 index 00000000..91671155 --- /dev/null +++ b/test/test_iterbase.cpp @@ -0,0 +1,91 @@ +// AGAIN the contents of iterbase are completely subject to change, do not rely +// on any of this. Users of the library must consider all of this undocumented +// + +#include +#include +#include +#include +#include +#include +#include + +#include "catch.hpp" +#include "helpers.hpp" + +namespace it = iter::impl; + +using IVec = std::vector; + +template +using hrai = it::has_random_access_iter; +TEST_CASE("Detects random access iterators correctly", "[iterbase]") { + REQUIRE(hrai>::value); + REQUIRE(hrai::value); + REQUIRE(hrai::value); + + REQUIRE_FALSE(hrai>::value); + REQUIRE_FALSE(hrai{}))>::value); + REQUIRE_FALSE(hrai>::value); +} + +TEST_CASE("Detects correct iterator types", "[iterbase]") { + REQUIRE((std::is_same, IVec::iterator>::value)); + REQUIRE((std::is_same, IVec::iterator>::value)); + REQUIRE((std::is_same, + IVec::iterator::reference>::value)); + REQUIRE((std::is_same, + IVec::iterator::reference>::value)); + REQUIRE((std::is_same, + IVec::iterator::value_type>::value)); + + REQUIRE( + (std::is_same, IVec::iterator::pointer>::value)); + REQUIRE((std::is_same, int*>::value)); +} + +TEST_CASE("advance, next, size", "[iterbase]") { + IVec v = {2, 4, 6, 8, 10, 12, 14, 16, 18}; + auto itr = std::begin(v); + REQUIRE(it::apply_arrow(itr) == &v[0]); + + it::dumb_advance(itr, 3); + REQUIRE(itr == (std::begin(v) + 3)); + REQUIRE(it::dumb_next(std::begin(v), 3) == std::begin(v) + 3); + REQUIRE(it::dumb_size(v) == v.size()); +} + +TEST_CASE("are_same", "[iterbase]") { + REQUIRE((it::are_same::value)); + REQUIRE_FALSE((it::are_same::value)); + REQUIRE_FALSE((it::are_same::value)); + REQUIRE_FALSE((it::are_same::value)); +} + +TEST_CASE("DerefHolder lvalue reference", "[iterbase]") { + it::DerefHolder dh; + int a = 2; + int b = 5; + REQUIRE_FALSE(dh); + dh.reset(a); + REQUIRE(dh); + + REQUIRE(dh.get_ptr() == &a); + REQUIRE(&dh.get() == &a); + dh.reset(b); + REQUIRE(dh.get_ptr() == &b); + REQUIRE(&dh.get() == &b); +} + +TEST_CASE("DerefHolder non-reference", "[iterbase]") { + it::DerefHolder dh; + int a = 2; + int b = 5; + REQUIRE_FALSE(dh); + dh.reset(std::move(a)); + REQUIRE(dh.get() == 2); + REQUIRE(&dh.get() != &a); + + dh.reset(std::move(b)); + REQUIRE(dh.get() == 5); +}