From ea22a6ba5c789800261a4b7a08ac3e0348e7485a Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Tue, 22 May 2012 21:16:16 +0900 Subject: [PATCH] add adaptors::counting --- example/fizzbuzz/main.cpp | 198 ++++++++--------- libs/string/example/literals_to_string.cpp | 120 +++++----- libs/string/example/simple.cpp | 172 +++++++-------- libs/weed/example/__TIME__.cpp | 136 ++++++------ libs/weed/example/remove_space.cpp | 72 +++--- sprout/iterator/counting_iterator.hpp | 243 +++++++++++++++++++++ sprout/range/adaptor.hpp | 1 + sprout/range/adaptor/counting.hpp | 174 +++++++++++++++ sprout/range/adaptor/transformed.hpp | 8 +- 9 files changed, 771 insertions(+), 353 deletions(-) create mode 100644 sprout/iterator/counting_iterator.hpp create mode 100644 sprout/range/adaptor/counting.hpp diff --git a/example/fizzbuzz/main.cpp b/example/fizzbuzz/main.cpp index 07159fe7..0737c9f0 100644 --- a/example/fizzbuzz/main.cpp +++ b/example/fizzbuzz/main.cpp @@ -1,99 +1,99 @@ -// -// Sprout C++ Library -// -// Copyright (c) 2012 -// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ -// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ -// -// Readme: -// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README -// -// License: -// Boost Software License - Version 1.0 -// -// -#include -#include -#include -#include -#include -#include - - -struct fizzbuzz{ - typedef sprout::string<12> result_type; - - constexpr result_type - operator ()(int n) const{ - return n % 15 == 0 ? sprout::to_string("FizzBuzz") - : n % 3 == 0 ? sprout::to_string("Fizz") - : n % 5 == 0 ? sprout::to_string("Buzz") - : sprout::to_string(n); - } -}; - - -int -main(){ - typedef fizzbuzz::result_type string; - - // - // Test - // - static_assert(fizzbuzz()( 1) == "1", ""); - static_assert(fizzbuzz()( 2) == "2", ""); - static_assert(fizzbuzz()( 3) == "Fizz", ""); - static_assert(fizzbuzz()( 5) == "Buzz", ""); - static_assert(fizzbuzz()(15) == "FizzBuzz", ""); - - // - // Sequence [1..15] - // - constexpr auto source = sprout::iota( - sprout::pit >(), - 1 - ); - - // - // Transform to FizzBuzz - // - constexpr auto result = sprout::transform( - sprout::begin(source), - sprout::end(source), - sprout::pit >(), - fizzbuzz() - ); - - // - // Check result - // - constexpr auto fizzbuzz_result = sprout::make_array( - sprout::to_string("1"), - sprout::to_string("2"), - sprout::to_string("Fizz"), - sprout::to_string("4"), - sprout::to_string("Buzz"), - sprout::to_string("Fizz"), - sprout::to_string("7"), - sprout::to_string("8"), - sprout::to_string("Fizz"), - sprout::to_string("Buzz"), - sprout::to_string("11"), - sprout::to_string("Fizz"), - sprout::to_string("13"), - sprout::to_string("14"), - sprout::to_string("FizzBuzz") - ); - // Equal result sequence - static_assert(result == fizzbuzz_result, ""); - - // - // Output - // - for(auto&& str : result){ - std::cout << str << ", "; - } - std::cout << std::endl; - - return 0; -} +// +// Sprout C++ Library +// +// Copyright (c) 2012 +// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ +// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ +// +// Readme: +// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README +// +// License: +// Boost Software License - Version 1.0 +// +// +#include +#include +#include +#include +#include +#include + + +struct fizzbuzz{ + typedef sprout::string<12> result_type; + + constexpr result_type + operator ()(int n) const{ + return n % 15 == 0 ? sprout::to_string("FizzBuzz") + : n % 3 == 0 ? sprout::to_string("Fizz") + : n % 5 == 0 ? sprout::to_string("Buzz") + : sprout::to_string(n); + } +}; + + +int +main(){ + typedef fizzbuzz::result_type string; + + // + // Test + // + static_assert(fizzbuzz()( 1) == "1", ""); + static_assert(fizzbuzz()( 2) == "2", ""); + static_assert(fizzbuzz()( 3) == "Fizz", ""); + static_assert(fizzbuzz()( 5) == "Buzz", ""); + static_assert(fizzbuzz()(15) == "FizzBuzz", ""); + + // + // Sequence [1..15] + // + constexpr auto source = sprout::iota( + sprout::pit >(), + 1 + ); + + // + // Transform to FizzBuzz + // + constexpr auto result = sprout::transform( + sprout::begin(source), + sprout::end(source), + sprout::pit >(), + fizzbuzz() + ); + + // + // Check result + // + constexpr auto fizzbuzz_result = sprout::make_array( + sprout::to_string("1"), + sprout::to_string("2"), + sprout::to_string("Fizz"), + sprout::to_string("4"), + sprout::to_string("Buzz"), + sprout::to_string("Fizz"), + sprout::to_string("7"), + sprout::to_string("8"), + sprout::to_string("Fizz"), + sprout::to_string("Buzz"), + sprout::to_string("11"), + sprout::to_string("Fizz"), + sprout::to_string("13"), + sprout::to_string("14"), + sprout::to_string("FizzBuzz") + ); + // Equal result sequence + static_assert(result == fizzbuzz_result, ""); + + // + // Output + // + for(auto&& str : result){ + std::cout << str << ", "; + } + std::cout << std::endl; + + return 0; +} diff --git a/libs/string/example/literals_to_string.cpp b/libs/string/example/literals_to_string.cpp index 6be849c5..7aad1c08 100644 --- a/libs/string/example/literals_to_string.cpp +++ b/libs/string/example/literals_to_string.cpp @@ -1,60 +1,60 @@ -// -// Sprout C++ Library -// -// Copyright (c) 2012 -// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ -// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ -// -// Readme: -// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README -// -// License: -// Boost Software License - Version 1.0 -// -// -#include - - -int -main(){ - - // - // String literal to Sprout.String - // - { - static constexpr auto str1 = sprout::to_string("homu"); - static_assert(str1 == "homu", ""); - static_assert(std::is_same const>{}, ""); - - static constexpr auto str2 = sprout::to_string(L"ほむほむ"); - static_assert(str2 == L"ほむほむ", ""); - static_assert(std::is_same const>{}, ""); - } - - // - // Integer literal to Sprout.String - // - { - static constexpr auto str = sprout::to_string(42); - static_assert(str == "42", ""); - } - - // - // Float literal to Sprout.String - // - { - static constexpr auto str = sprout::to_string(3.14f); - static_assert(str == "3.140000", ""); - } - - // - // Char literal to Sprout.String - // - { - static constexpr auto str = sprout::make_string('m', 'a', 'd', 'o'); - static_assert(str == "mado", ""); - static_assert(std::is_same const>{}, ""); - } - - return 0; -} +// +// Sprout C++ Library +// +// Copyright (c) 2012 +// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ +// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ +// +// Readme: +// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README +// +// License: +// Boost Software License - Version 1.0 +// +// +#include + + +int +main(){ + + // + // String literal to Sprout.String + // + { + static constexpr auto str1 = sprout::to_string("homu"); + static_assert(str1 == "homu", ""); + static_assert(std::is_same const>{}, ""); + + static constexpr auto str2 = sprout::to_string(L"ほむほむ"); + static_assert(str2 == L"ほむほむ", ""); + static_assert(std::is_same const>{}, ""); + } + + // + // Integer literal to Sprout.String + // + { + static constexpr auto str = sprout::to_string(42); + static_assert(str == "42", ""); + } + + // + // Float literal to Sprout.String + // + { + static constexpr auto str = sprout::to_string(3.14f); + static_assert(str == "3.140000", ""); + } + + // + // Char literal to Sprout.String + // + { + static constexpr auto str = sprout::make_string('m', 'a', 'd', 'o'); + static_assert(str == "mado", ""); + static_assert(std::is_same const>{}, ""); + } + + return 0; +} diff --git a/libs/string/example/simple.cpp b/libs/string/example/simple.cpp index 6e1c97a0..38c624c6 100644 --- a/libs/string/example/simple.cpp +++ b/libs/string/example/simple.cpp @@ -1,86 +1,86 @@ -// -// Sprout C++ Library -// -// Copyright (c) 2012 -// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ -// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ -// -// Readme: -// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README -// -// License: -// Boost Software License - Version 1.0 -// -// -#include -#include -#include - - -// -// Sprout.String is constexpr string object -// -int -main(){ - - // - // String literal to Sprout.String - // - static constexpr sprout::string<4> str1 = sprout::to_string("homu"); - static constexpr auto str2 = sprout::to_string("mado"); - static constexpr auto str3 = sprout::to_string(42); - - // - // Comparison - // - static_assert(str1 == sprout::to_string("homu"), ""); - static_assert(str2 == "mado", ""); - static_assert(str3 == "42", ""); - static_assert(str1 != str2, ""); - - // - // Accessor - // - static_assert(str1.front() == 'h', ""); - static_assert(str1[1] == 'o', ""); - static_assert(str1.at(2) == 'm', ""); - static_assert(str1.back() == 'u', ""); - - // - // String concatenation - // - static_assert((str1 + "homu") == "homuhomu", ""); - static_assert((str1 + str2) == "homumado", ""); - static_assert((str1 + sprout::to_string("42")) == "homu42", ""); - - // - // C style string - // - constexpr char const* cp = str1.c_str(); - static_assert(cp[0] == 'h', ""); - - // - // Iterator - // - static_assert(*str1.begin() == 'h', ""); - static_assert(*(str1.end() - 1) == 'u', ""); - static_assert(*(str1.rbegin() + 1) == 'm', ""); - static_assert(*(str1.rend() - 2) == 'o', ""); - - // - // IOStream - // - { - std::ostringstream os; - os << str1; - assert(os.str() == "homu"); - } - { - std::istringstream is("mami"); - sprout::string<4> str; - is >> str; - assert(str == "mami"); - } - - return 0; -} +// +// Sprout C++ Library +// +// Copyright (c) 2012 +// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ +// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ +// +// Readme: +// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README +// +// License: +// Boost Software License - Version 1.0 +// +// +#include +#include +#include + + +// +// Sprout.String is constexpr string object +// +int +main(){ + + // + // String literal to Sprout.String + // + static constexpr sprout::string<4> str1 = sprout::to_string("homu"); + static constexpr auto str2 = sprout::to_string("mado"); + static constexpr auto str3 = sprout::to_string(42); + + // + // Comparison + // + static_assert(str1 == sprout::to_string("homu"), ""); + static_assert(str2 == "mado", ""); + static_assert(str3 == "42", ""); + static_assert(str1 != str2, ""); + + // + // Accessor + // + static_assert(str1.front() == 'h', ""); + static_assert(str1[1] == 'o', ""); + static_assert(str1.at(2) == 'm', ""); + static_assert(str1.back() == 'u', ""); + + // + // String concatenation + // + static_assert((str1 + "homu") == "homuhomu", ""); + static_assert((str1 + str2) == "homumado", ""); + static_assert((str1 + sprout::to_string("42")) == "homu42", ""); + + // + // C style string + // + constexpr char const* cp = str1.c_str(); + static_assert(cp[0] == 'h', ""); + + // + // Iterator + // + static_assert(*str1.begin() == 'h', ""); + static_assert(*(str1.end() - 1) == 'u', ""); + static_assert(*(str1.rbegin() + 1) == 'm', ""); + static_assert(*(str1.rend() - 2) == 'o', ""); + + // + // IOStream + // + { + std::ostringstream os; + os << str1; + assert(os.str() == "homu"); + } + { + std::istringstream is("mami"); + sprout::string<4> str; + is >> str; + assert(str == "mami"); + } + + return 0; +} diff --git a/libs/weed/example/__TIME__.cpp b/libs/weed/example/__TIME__.cpp index 7f4f6868..26ec1eab 100644 --- a/libs/weed/example/__TIME__.cpp +++ b/libs/weed/example/__TIME__.cpp @@ -1,68 +1,68 @@ -// -// Sprout C++ Library -// -// Copyright (c) 2012 -// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ -// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ -// -// Readme: -// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README -// -// License: -// Boost Software License - Version 1.0 -// -// -#include -#include -#include -#include - -// -// __TIME__ Parser -// -int -main(){ - namespace w = sprout::weed; - - // - // __TIME__ to Sprout.String - // - static constexpr auto time = sprout::to_string(__TIME__); -// static constexpr auto time = sprout::to_string("23:22:45"); - - - // - // parse __TIME__ - // - constexpr auto parser = w::int_ >> ':' >> w::int_ >> ':' >> w::int_; - static constexpr auto result = w::parse(time.begin(), time.end(), parser); - static_assert(result.success(), "failed parse"); - - - // - // get result - // - static constexpr sprout::array result_attr = result.attr(); - static constexpr auto hour = result_attr[0]; - static constexpr auto minute = result_attr[1]; - static constexpr auto second = result_attr[2]; - -// static_assert(hour == 23, ""); -// static_assert(minute == 22, ""); -// static_assert(second == 45, ""); - - std::cout << hour << std::endl; - std::cout << minute << std::endl; - std::cout << second << std::endl; - - - // - // compile time output - // - namespace m = boost::mpl; - typedef m::print>::type hour_; - typedef m::print>::type minute_; - typedef m::print>::type second_; - - return 0; -} +// +// Sprout C++ Library +// +// Copyright (c) 2012 +// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ +// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ +// +// Readme: +// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README +// +// License: +// Boost Software License - Version 1.0 +// +// +#include +#include +#include +#include + +// +// __TIME__ Parser +// +int +main(){ + namespace w = sprout::weed; + + // + // __TIME__ to Sprout.String + // + static constexpr auto time = sprout::to_string(__TIME__); +// static constexpr auto time = sprout::to_string("23:22:45"); + + + // + // parse __TIME__ + // + constexpr auto parser = w::int_ >> ':' >> w::int_ >> ':' >> w::int_; + static constexpr auto result = w::parse(time.begin(), time.end(), parser); + static_assert(result.success(), "failed parse"); + + + // + // get result + // + static constexpr sprout::array result_attr = result.attr(); + static constexpr auto hour = result_attr[0]; + static constexpr auto minute = result_attr[1]; + static constexpr auto second = result_attr[2]; + +// static_assert(hour == 23, ""); +// static_assert(minute == 22, ""); +// static_assert(second == 45, ""); + + std::cout << hour << std::endl; + std::cout << minute << std::endl; + std::cout << second << std::endl; + + + // + // compile time output + // + namespace m = boost::mpl; + typedef m::print>::type hour_; + typedef m::print>::type minute_; + typedef m::print>::type second_; + + return 0; +} diff --git a/libs/weed/example/remove_space.cpp b/libs/weed/example/remove_space.cpp index 60a72142..29c3786b 100644 --- a/libs/weed/example/remove_space.cpp +++ b/libs/weed/example/remove_space.cpp @@ -1,36 +1,36 @@ -// -// Sprout C++ Library -// -// Copyright (c) 2012 -// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ -// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ -// -// Readme: -// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README -// -// License: -// Boost Software License - Version 1.0 -// -// -#include - - -int -main(){ - namespace w = sprout::weed; - - static constexpr auto max_string_size = 32; - static constexpr auto space = *w::omit[ w::space ]; - static constexpr auto remove_space = *w::lim(space >> w::char_); - - static constexpr auto source = sprout::to_string(" homu : mami= 10 "); - static constexpr auto result = w::parse( - sprout::begin(source), sprout::end(source), - remove_space - ); - - static_assert(result.success(), "fail remove_space parse"); - static_assert(result.attr() == "homu:mami=10", ""); - - return 0; -} +// +// Sprout C++ Library +// +// Copyright (c) 2012 +// bolero-MURAKAMI : http://d.hatena.ne.jp/boleros/ +// osyo-manga : http://d.hatena.ne.jp/osyo-manga/ +// +// Readme: +// https://github.com/bolero-MURAKAMI/Sprout/blob/master/README +// +// License: +// Boost Software License - Version 1.0 +// +// +#include + + +int +main(){ + namespace w = sprout::weed; + + static constexpr auto max_string_size = 32; + static constexpr auto space = *w::omit[ w::space ]; + static constexpr auto remove_space = *w::lim(space >> w::char_); + + static constexpr auto source = sprout::to_string(" homu : mami= 10 "); + static constexpr auto result = w::parse( + sprout::begin(source), sprout::end(source), + remove_space + ); + + static_assert(result.success(), "fail remove_space parse"); + static_assert(result.attr() == "homu:mami=10", ""); + + return 0; +} diff --git a/sprout/iterator/counting_iterator.hpp b/sprout/iterator/counting_iterator.hpp new file mode 100644 index 00000000..727adf7e --- /dev/null +++ b/sprout/iterator/counting_iterator.hpp @@ -0,0 +1,243 @@ +#ifndef SPROUT_ITERATOR_COUNTING_ITERATOR_HPP +#define SPROUT_ITERATOR_COUNTING_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // counting_iterator + // + template + class counting_iterator + : public std::iterator< + std::random_access_iterator_tag, + Incrementable, + std::ptrdiff_t, + Incrementable*, + Incrementable + > + { + public: + typedef std::random_access_iterator_tag iterator_category; + typedef Incrementable value_type; + typedef std::ptrdiff_t difference_type; + typedef value_type* pointer; + typedef value_type reference; + private: + value_type current_; + private: + public: + counting_iterator() = default; + counting_iterator(counting_iterator const&) = default; + explicit SPROUT_CONSTEXPR counting_iterator(value_type const& v) + : current_(v) + {} + template + SPROUT_CONSTEXPR counting_iterator(counting_iterator const& it) + : current_(it.current_) + {} + template + counting_iterator& operator=(counting_iterator const& it) { + counting_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator*() const { + return current_; + } + SPROUT_CONSTEXPR pointer operator->() const { + return ¤t_; + } + counting_iterator& operator++() { + ++current_; + return *this; + } + counting_iterator operator++(int) { + counting_iterator result(*this); + ++current_; + return result; + } + counting_iterator& operator--() { + --current_; + return *this; + } + counting_iterator operator--(int) { + counting_iterator temp(*this); + --current_; + return temp; + } + SPROUT_CONSTEXPR counting_iterator operator+(difference_type n) const { + return counting_iterator(current_ + n); + } + SPROUT_CONSTEXPR counting_iterator operator-(difference_type n) const { + return counting_iterator(current_ - n); + } + counting_iterator& operator+=(difference_type n) { + counting_iterator temp(current_ + n); + temp.swap(*this); + return *this; + } + counting_iterator& operator-=(difference_type n) { + counting_iterator temp(current_ - n); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return current_ + n; + } + SPROUT_CONSTEXPR counting_iterator next() const { + return counting_iterator(current_ + 1); + } + SPROUT_CONSTEXPR counting_iterator prev() const { + return counting_iterator(current_ - 1); + } + void swap(counting_iterator& other) { + using std::swap; + swap(current_, other.current_); + } + }; + + template + SPROUT_CONSTEXPR bool operator==( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return *lhs == *rhs; + } + template + SPROUT_CONSTEXPR bool operator!=( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return !(lhs == rhs); + } + template + SPROUT_CONSTEXPR bool operator<( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return *lhs < *rhs; + } + template + SPROUT_CONSTEXPR bool operator>( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return rhs < lhs; + } + template + SPROUT_CONSTEXPR bool operator<=( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return !(rhs < lhs); + } + template + SPROUT_CONSTEXPR bool operator>=( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return !(lhs < rhs); + } + template + SPROUT_CONSTEXPR typename sprout::counting_iterator::difference_type operator-( + sprout::counting_iterator const& lhs, + sprout::counting_iterator const& rhs + ) + { + return static_cast::difference_type>(*lhs - *rhs); + } + template + SPROUT_CONSTEXPR sprout::counting_iterator operator+( + typename sprout::counting_iterator::difference_type n, + sprout::counting_iterator const& it + ) + { + return it + n; + } + + // + // make_counting_iterator + // + template + SPROUT_CONSTEXPR sprout::counting_iterator + make_counting_iterator(Incrementable const& v) { + return sprout::counting_iterator(v); + } + + // + // swap + // + template + void swap(sprout::counting_iterator& lhs, sprout::counting_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // next + // + template + SPROUT_CONSTEXPR sprout::counting_iterator next( + sprout::counting_iterator const& it + ) + { + return it.next(); + } + template + SPROUT_CONSTEXPR sprout::counting_iterator next( + sprout::counting_iterator const& it, + typename sprout::counting_iterator::difference_type n + ) + { + return it + n; + } + + // + // prev + // + template + SPROUT_CONSTEXPR sprout::counting_iterator prev( + sprout::counting_iterator const& it + ) + { + return it.prev(); + } + template + SPROUT_CONSTEXPR sprout::counting_iterator prev( + sprout::counting_iterator const& it, + typename sprout::counting_iterator::difference_type n + ) + { + return it - n; + } + + // + // distance + // + template + SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type + distance( + sprout::counting_iterator first, + sprout::counting_iterator last + ) + { + return last - first; + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_COUNTING_ITERATOR_HPP diff --git a/sprout/range/adaptor.hpp b/sprout/range/adaptor.hpp index 7108e00c..7f9d5938 100644 --- a/sprout/range/adaptor.hpp +++ b/sprout/range/adaptor.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #endif // #ifndef SPROUT_RANGE_ADAPTOR_HPP diff --git a/sprout/range/adaptor/counting.hpp b/sprout/range/adaptor/counting.hpp new file mode 100644 index 00000000..ccd2d6c7 --- /dev/null +++ b/sprout/range/adaptor/counting.hpp @@ -0,0 +1,174 @@ +#ifndef SPROUT_RANGE_ADAPTOR_COUNTING_HPP +#define SPROUT_RANGE_ADAPTOR_COUNTING_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // counting_range + // + template + class counting_range + : public sprout::range::range_container< + sprout::counting_iterator + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::counting_iterator + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + typedef typename base_type::difference_type difference_type; + public: + counting_range() = default; + counting_range(counting_range const&) = default; + explicit SPROUT_CONSTEXPR counting_range(range_type& range) + : base_type( + iterator(), + sprout::next(iterator(), sprout::size(range)) + ) + {} + SPROUT_CONSTEXPR counting_range( + range_type& range, + value_type const& first + ) + : base_type( + iterator(first), + sprout::next(iterator(first), sprout::size(range)) + ) + {} + SPROUT_CONSTEXPR counting_range( + range_type& range, + value_type const& first, + value_type const& last + ) + : base_type( + iterator(first), + sprout::size(range) < last - first ? sprout::next(iterator(first), sprout::size(range)) + : iterator(last) + ) + {} + }; + + template + class counting_range + : public sprout::range::range_container< + sprout::counting_iterator + > + { + public: + typedef sprout::range::range_container< + sprout::counting_iterator + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + typedef typename base_type::difference_type difference_type; + public: + counting_range() = default; + counting_range(counting_range const&) = default; + explicit SPROUT_CONSTEXPR counting_range(value_type const& first) + : base_type( + iterator(first), + iterator(std::numeric_limits::max()) + ) + {} + SPROUT_CONSTEXPR counting_range( + value_type const& first, + value_type const& last + ) + : base_type( + iterator(first), + iterator(last) + ) + {} + }; + + // + // counting_forwarder + // + class counting_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::counting_range + operator()(Incrementable const& first) const { + return sprout::adaptors::counting_range(first); + } + template + SPROUT_CONSTEXPR sprout::adaptors::counting_range + operator()(Incrementable const& first, Incrementable const& last) const { + return sprout::adaptors::counting_range(first, last); + } + }; + + // + // counting + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::counting_forwarder counting{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::counting_range< + Incrementable, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::counting_range const& rhs) { + return sprout::adaptors::counting_range< + Incrementable, + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs), + *rhs.begin(), + *rhs.end() + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_COUNTING_HPP diff --git a/sprout/range/adaptor/transformed.hpp b/sprout/range/adaptor/transformed.hpp index d984a5fb..cddfc138 100644 --- a/sprout/range/adaptor/transformed.hpp +++ b/sprout/range/adaptor/transformed.hpp @@ -45,8 +45,8 @@ namespace sprout { typedef typename base_type::iterator iterator; typedef typename base_type::size_type size_type; public: - SPROUT_CONSTEXPR transformed_range() = default; - SPROUT_CONSTEXPR transformed_range(transformed_range const&) = default; + transformed_range() = default; + transformed_range(transformed_range const&) = default; SPROUT_CONSTEXPR transformed_range(functor_type func, range_type& range1, range2_type& range2) : base_type( iterator(sprout::begin(range1), sprout::begin(range2), func), @@ -77,8 +77,8 @@ namespace sprout { > base_type; typedef typename base_type::iterator iterator; public: - SPROUT_CONSTEXPR transformed_range() = default; - SPROUT_CONSTEXPR transformed_range(transformed_range const&) = default; + transformed_range() = default; + transformed_range(transformed_range const&) = default; SPROUT_CONSTEXPR transformed_range(functor_type func, range_type& range) : base_type( iterator(sprout::begin(range), func),