diff options
Diffstat (limited to 'src/boost/libs/histogram/test/detail_iterator_adaptor_test.cpp')
-rw-r--r-- | src/boost/libs/histogram/test/detail_iterator_adaptor_test.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/boost/libs/histogram/test/detail_iterator_adaptor_test.cpp b/src/boost/libs/histogram/test/detail_iterator_adaptor_test.cpp new file mode 100644 index 000000000..c7a3303db --- /dev/null +++ b/src/boost/libs/histogram/test/detail_iterator_adaptor_test.cpp @@ -0,0 +1,191 @@ +// (C) Copyright Thomas Witt 2003. +// (C) Copyright Hans Dembinski 2019. + +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version including documentation. + +#include <boost/core/lightweight_test.hpp> +#include <boost/core/lightweight_test_trait.hpp> +#include <boost/histogram/detail/detect.hpp> +#include <boost/histogram/detail/iterator_adaptor.hpp> +#include "std_ostream.hpp" +#include "utility_iterator.hpp" + +#include <deque> +#include <set> +#include <vector> + +using namespace boost::histogram; +using boost::histogram::detail::iterator_adaptor; + +typedef std::deque<int> storage; +typedef std::deque<int*> pointer_deque; +typedef std::set<storage::iterator> iterator_set; + +template <class T> +struct foo; + +void blah(int) {} + +struct my_gen { + typedef int result_type; + my_gen() : n(0) {} + int operator()() { return ++n; } + int n; +}; + +template <class V> +struct ptr_iterator : iterator_adaptor<ptr_iterator<V>, V*> { +private: + typedef iterator_adaptor<ptr_iterator<V>, V*> super_t; + +public: + using base_type = typename super_t::base_type; + + ptr_iterator() {} + ptr_iterator(V* d) : super_t(d) {} + + template <class V2, class = detail::requires_convertible<V2*, V*>> + ptr_iterator(const ptr_iterator<V2>& x) : super_t(x.base()) {} + + V& operator*() const { return *(this->base()); } +}; + +template <class Iter> +struct constant_iterator + : iterator_adaptor<constant_iterator<Iter>, Iter, + typename std::iterator_traits<Iter>::value_type const&> { + typedef iterator_adaptor<constant_iterator<Iter>, Iter, + typename std::iterator_traits<Iter>::value_type const&> + base_t; + + constant_iterator() {} + constant_iterator(Iter it) : base_t(it) {} + + typename std::iterator_traits<Iter>::value_type const& operator*() const { + this->base().operator*(); + } +}; + +struct mutable_it : iterator_adaptor<mutable_it, int*> { + typedef iterator_adaptor<mutable_it, int*> super_t; + + mutable_it(); + explicit mutable_it(int* p) : super_t(p) {} + + bool equal(mutable_it const& rhs) const { return this->base() == rhs.base(); } +}; + +struct constant_it : iterator_adaptor<constant_it, int const*> { + typedef iterator_adaptor<constant_it, int const*> super_t; + + constant_it(); + explicit constant_it(int* p) : super_t(p) {} + constant_it(mutable_it const& x) : super_t(x.base()) {} + + bool equal(constant_it const& rhs) const { return this->base() == rhs.base(); } +}; + +template <class T> +class static_object { +public: + static T& get() { + static char d[sizeof(T)]; + return *reinterpret_cast<T*>(d); + } +}; + +int main() { + dummyT array[] = {dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5)}; + const int N = sizeof(array) / sizeof(dummyT); + + // Test the iterator_adaptor + { + ptr_iterator<dummyT> i(array); + using reference = typename std::iterator_traits<ptr_iterator<dummyT>>::reference; + using pointer = typename std::iterator_traits<ptr_iterator<dummyT>>::pointer; + BOOST_TEST_TRAIT_SAME(reference, dummyT&); + BOOST_TEST_TRAIT_SAME(pointer, dummyT*); + + random_access_iterator_test(i, N, array); + + ptr_iterator<const dummyT> j(array); + random_access_iterator_test(j, N, array); + const_nonconst_iterator_test(i, ++j); + } + + // Test the iterator_traits + { + // Test computation of defaults + typedef ptr_iterator<int> Iter1; + // don't use std::iterator_traits here to avoid VC++ problems + BOOST_TEST_TRAIT_SAME(Iter1::value_type, int); + BOOST_TEST_TRAIT_SAME(Iter1::reference, int&); + BOOST_TEST_TRAIT_SAME(Iter1::pointer, int*); + BOOST_TEST_TRAIT_SAME(Iter1::difference_type, std::ptrdiff_t); + } + + { + // Test computation of default when the Value is const + typedef ptr_iterator<int const> Iter1; + BOOST_TEST_TRAIT_SAME(Iter1::value_type, int); + BOOST_TEST_TRAIT_SAME(Iter1::reference, const int&); + BOOST_TEST_TRAIT_SAME(Iter1::pointer, int const*); + } + + { + // Test constant iterator idiom + typedef ptr_iterator<int> BaseIter; + typedef constant_iterator<BaseIter> Iter; + + BOOST_TEST_TRAIT_SAME(Iter::value_type, int); + BOOST_TEST_TRAIT_SAME(Iter::reference, int const&); + BOOST_TEST_TRAIT_SAME(Iter::pointer, int const*); + } + + // Test the iterator_adaptor + { + ptr_iterator<dummyT> i(array); + random_access_iterator_test(i, N, array); + + ptr_iterator<const dummyT> j(array); + random_access_iterator_test(j, N, array); + const_nonconst_iterator_test(i, ++j); + } + + // check that base_type is correct + { + // Test constant iterator idiom + typedef ptr_iterator<int> BaseIter; + + BOOST_TEST_TRAIT_SAME(BaseIter::base_type, int*); + BOOST_TEST_TRAIT_SAME(constant_iterator<BaseIter>::base_type, BaseIter); + } + + { + int data[] = {49, 77}; + + mutable_it i(data); + constant_it j(data + 1); + BOOST_TEST(i < j); + BOOST_TEST(j > i); + BOOST_TEST(i <= j); + BOOST_TEST(j >= i); + BOOST_TEST(j - i == 1); + BOOST_TEST(i - j == -1); + + constant_it k = i; + + BOOST_TEST(!(i < k)); + BOOST_TEST(!(k > i)); + BOOST_TEST(i <= k); + BOOST_TEST(k >= i); + BOOST_TEST(k - i == 0); + BOOST_TEST(i - k == 0); + } + + return boost::report_errors(); +} |