From f40ee0a2ff7a3049a7bef5569fb6a2a29cf497de Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 27 Sep 2012 21:26:32 +0900 Subject: [PATCH] add generator_iterator rename fix random/random_iterator.hpp -> random/iterator.hpp --- sprout/iterator.hpp | 3 +- sprout/iterator/adaptor.hpp | 2 +- sprout/iterator/generator_iterator.hpp | 157 ++++++++++++ sprout/iterator/predefined.hpp | 7 +- sprout/iterator/various.hpp | 10 + sprout/random.hpp | 2 +- sprout/random/iterator.hpp | 62 +++++ sprout/random/random_iterator.hpp | 323 ------------------------- 8 files changed, 235 insertions(+), 331 deletions(-) create mode 100644 sprout/iterator/generator_iterator.hpp create mode 100644 sprout/iterator/various.hpp create mode 100644 sprout/random/iterator.hpp delete mode 100644 sprout/random/random_iterator.hpp diff --git a/sprout/iterator.hpp b/sprout/iterator.hpp index 2505b216..b01316d3 100644 --- a/sprout/iterator.hpp +++ b/sprout/iterator.hpp @@ -2,9 +2,8 @@ #define SPROUT_ITERATOR_HPP #include +#include #include #include -#include -#include #endif // #ifndef SPROUT_ITERATOR_HPP diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index 8cf57b4d..c870d5b2 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -5,7 +5,7 @@ #include #include #include -#include #include +#include #endif // #ifndef SPROUT_ITERATOR_ADAPTOR_HPP diff --git a/sprout/iterator/generator_iterator.hpp b/sprout/iterator/generator_iterator.hpp new file mode 100644 index 00000000..39e4fee3 --- /dev/null +++ b/sprout/iterator/generator_iterator.hpp @@ -0,0 +1,157 @@ +#ifndef SPROUT_ITERATOR_GENERATOR_ITERATOR_HPP +#define SPROUT_ITERATOR_GENERATOR_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // generator_iterator + // + template + class generator_iterator + : public std::iterator< + std::forward_iterator_tag, + typename std::remove_reference()))>::type, + std::ptrdiff_t, + typename std::remove_reference()))>::type*, + decltype(sprout::generators::generated_value(std::declval())) + > + { + public: + typedef Generator generator_type; + typedef std::forward_iterator_tag iterator_category; + typedef decltype(sprout::generators::generated_value(std::declval())) reference; + typedef typename std::remove_reference::type value_type; + typedef std::ptrdiff_t difference_type; + typedef value_type* pointer; + private: + generator_type gen_; + difference_type count_; + public: + SPROUT_CONSTEXPR generator_iterator() + : gen_() + , count_() + {} + explicit SPROUT_CONSTEXPR generator_iterator( + generator_type const& gen, + difference_type count = -1 + ) + : gen_(gen) + , count_(count) + {} + generator_type& generator() { + return gen_; + } + SPROUT_CONSTEXPR generator_type const& generator() const { + return gen_; + } + SPROUT_CONSTEXPR difference_type count() const { + return count_; + } + SPROUT_CONSTEXPR generator_iterator operator()() const { + return count_ != 0 + ? generator_iterator(sprout::generators::next_generator(gen_)(), count_ > 0 ? count_ - 1 : count_) + : throw std::out_of_range("generator_iterator<>: increment at out of range") + ; + } + SPROUT_CONSTEXPR generator_iterator next() const { + return (*this)(); + } + SPROUT_CONSTEXPR reference generated_value() const { + return sprout::generators::generated_value(gen_); + } + SPROUT_CONSTEXPR generator_iterator next_generator() const { + return (*this)(); + } + void swap(generator_iterator& other) { + using std::swap; + swap(gen_, other.gen_); + swap(count_, other.count_); + } + friend SPROUT_CONSTEXPR bool operator==(generator_iterator const& lhs, generator_iterator const& rhs) { + return lhs.count_ == rhs.count_; + } + friend SPROUT_CONSTEXPR bool operator!=(generator_iterator const& lhs, generator_iterator const& rhs) { + return !(lhs == rhs); + } + friend SPROUT_CONSTEXPR bool operator<(generator_iterator const& lhs, generator_iterator const& rhs) { + typedef typename std::make_unsigned::type unsigned_type; + return static_cast(lhs.count_) > static_cast(rhs.count_); + } + friend SPROUT_CONSTEXPR bool operator>(generator_iterator const& lhs, generator_iterator const& rhs) { + return rhs < lhs; + } + friend SPROUT_CONSTEXPR bool operator<=(generator_iterator const& lhs, generator_iterator const& rhs) { + return !(rhs < lhs); + } + friend SPROUT_CONSTEXPR bool operator>=(generator_iterator const& lhs, generator_iterator const& rhs) { + return !(lhs < rhs); + } + SPROUT_CONSTEXPR reference operator*() const { + return count_ != 0 + ? sprout::generators::generated_value(gen_) + : (throw std::out_of_range("generator_iterator<>: dereference at out of range"), gen_.result()) + ; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*(*this); + } + generator_iterator& operator++() { + generator_iterator temp((*this)()); + temp.swap(*this); + return *this; + } + generator_iterator operator++(int) { + generator_iterator result(*this); + ++*this; + return result; + } + friend SPROUT_CONSTEXPR difference_type operator-(generator_iterator const& lhs, generator_iterator const& rhs) { + return rhs.count_ - lhs.count_; + } + }; + + // + // swap + // + template + void swap( + sprout::generator_iterator& lhs, + sprout::generator_iterator& rhs + ) + { + lhs.swap(rhs); + } + + // + // iterator_distance + // + template + inline SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type + iterator_distance( + sprout::generator_iterator first, + sprout::generator_iterator last + ) + { + return last - first; + } + + // + // iterator_next + // + template + SPROUT_CONSTEXPR sprout::generator_iterator iterator_next( + sprout::generator_iterator const& it + ) + { + return it.next(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_GENERATOR_ITERATOR_HPP diff --git a/sprout/iterator/predefined.hpp b/sprout/iterator/predefined.hpp index f125f729..c51c965d 100644 --- a/sprout/iterator/predefined.hpp +++ b/sprout/iterator/predefined.hpp @@ -2,9 +2,8 @@ #define SPROUT_ITERATOR_PREDEFINED_HPP #include -#include -#include -#include -#include +#include +#include +#include #endif // #ifndef SPROUT_ITERATOR_PREDEFINED_HPP diff --git a/sprout/iterator/various.hpp b/sprout/iterator/various.hpp new file mode 100644 index 00000000..32e9b38d --- /dev/null +++ b/sprout/iterator/various.hpp @@ -0,0 +1,10 @@ +#ifndef SPROUT_ITERATOR_VARIOUS_HPP +#define SPROUT_ITERATOR_VARIOUS_HPP + +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_ITERATOR_VARIOUS_HPP diff --git a/sprout/random.hpp b/sprout/random.hpp index 5697fc03..39cdd24c 100644 --- a/sprout/random.hpp +++ b/sprout/random.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #endif // #ifndef SPROUT_RANDOM_HPP diff --git a/sprout/random/iterator.hpp b/sprout/random/iterator.hpp new file mode 100644 index 00000000..f5fb6f6a --- /dev/null +++ b/sprout/random/iterator.hpp @@ -0,0 +1,62 @@ +#ifndef SPROUT_RANDOM_ITERATOR_HPP +#define SPROUT_RANDOM_ITERATOR_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // begin + // + template< + typename Engine, typename Distribution, + typename sprout::enabler_if::value>::tyep = sprout::enabler + > + inline SPROUT_CONSTEXPR auto + begin( + Engine const& engine, Distribution const& distribution, + typename sprout::generator_iterator::type>::difference_type count = -1 + ) + -> sprout::generator_iterator::type> + { + return sprout::generator_iterator::type>(distribution(engine), count); + } + template + inline SPROUT_CONSTEXPR auto + begin( + Engine const& engine, + typename sprout::generator_iterator::type>::difference_type count = -1 + ) + -> sprout::generator_iterator::type> + { + return sprout::generator_iterator::type>(engine(), count); + } + + // + // end + // + template< + typename Engine, typename Distribution, + typename sprout::enabler_if::value>::tyep = sprout::enabler + > + inline SPROUT_CONSTEXPR auto + end(Engine const& engine, Distribution const& distribution) + -> sprout::generator_iterator::type> + { + return sprout::generator_iterator::type>(); + } + template + inline SPROUT_CONSTEXPR auto + end(Engine const& engine) + -> sprout::generator_iterator::type> + { + return sprout::generator_iterator::type>(); + } + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_ITERATOR_HPP diff --git a/sprout/random/random_iterator.hpp b/sprout/random/random_iterator.hpp deleted file mode 100644 index addb305a..00000000 --- a/sprout/random/random_iterator.hpp +++ /dev/null @@ -1,323 +0,0 @@ -#ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP -#define SPROUT_RANDOM_RANDOM_ITERATOR_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // random_iterator - // - template - class random_iterator; - - template - class random_iterator< - Engine, - Distribution, - typename std::enable_if::value>::type - > - : public std::iterator< - typename std::iterator_traits >::iterator_category, - typename std::iterator_traits >::value_type, - typename std::iterator_traits >::difference_type, - typename std::iterator_traits >::pointer, - typename std::iterator_traits >::reference - > - { - public: - typedef sprout::random::random_result random_result_type; - typedef typename random_result_type::engine_type engine_type; - typedef typename random_result_type::distribution_type distribution_type; - typedef typename random_result_type::result_type result_type; - typedef typename std::iterator_traits::iterator_category iterator_category; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - private: - random_result_type random_; - difference_type count_; - public: - SPROUT_CONSTEXPR random_iterator() - : random_() - , count_() - {} - SPROUT_CONSTEXPR random_iterator( - engine_type const& engine, - distribution_type const& distribution, - difference_type count = -1 - ) - : random_(distribution(engine)) - , count_(count) - {} - explicit SPROUT_CONSTEXPR random_iterator( - random_result_type const& random, - difference_type count = -1 - ) - : random_(random) - , count_(count) - {} - SPROUT_CONSTEXPR random_iterator operator()() const { - return count_ != 0 - ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) - : throw std::out_of_range("random_iterator<>: increment at out of range") - ; - } - random_result_type& random_result() { - return random_; - } - SPROUT_CONSTEXPR random_result_type const& random_result() const { - return random_; - } - result_type& result() { - return random_.result(); - } - SPROUT_CONSTEXPR result_type const& result() const { - return random_.result(); - } - engine_type& engine() { - return random_.engine(); - } - SPROUT_CONSTEXPR engine_type const& engine() const { - return random_.engine(); - } - distribution_type& distribution() { - return random_.distribution(); - } - SPROUT_CONSTEXPR distribution_type const& distribution() const { - return random_.distribution(); - } - SPROUT_CONSTEXPR result_type min() const { - return random_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return random_.max(); - } - SPROUT_CONSTEXPR result_type count() const { - return count_; - } - void swap(random_iterator& other) { - using std::swap; - swap(random_, other.random_); - swap(count_, other.count_); - } - friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { - return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_); - } - friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) { - return !(lhs == rhs); - } - SPROUT_CONSTEXPR reference operator*() const { - return count_ != 0 - ? random_.result() - : (throw std::out_of_range("random_iterator<>: dereference at out of range"), random_.result()) - ; - } - SPROUT_CONSTEXPR pointer operator->() const { - return count_ != 0 - ? &random_.result() - : throw std::out_of_range("random_iterator<>: dereference at out of range") - ; - } - random_iterator& operator++() { - random_iterator temp((*this)()); - temp.swap(*this); - return *this; - } - random_iterator operator++(int) { - random_iterator result(*this); - ++*this; - return result; - } - }; - template - class random_iterator< - Engine, - Distribution, - typename std::enable_if::value>::type - > - : public std::iterator< - typename std::iterator_traits >::iterator_category, - typename std::iterator_traits >::value_type, - typename std::iterator_traits >::difference_type, - typename std::iterator_traits >::pointer, - typename std::iterator_traits >::reference - > - { - public: - typedef sprout::random::random_result random_result_type; - typedef typename random_result_type::engine_type engine_type; - typedef typename random_result_type::result_type result_type; - typedef typename std::iterator_traits::iterator_category iterator_category; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - private: - random_result_type random_; - difference_type count_; - public: - SPROUT_CONSTEXPR random_iterator() - : random_() - , count_() - {} - SPROUT_CONSTEXPR random_iterator( - engine_type const& engine, - difference_type count = -1 - ) - : random_(engine()) - , count_(count) - {} - explicit SPROUT_CONSTEXPR random_iterator( - random_result_type const& random, - difference_type count = -1 - ) - : random_(random) - , count_(count) - {} - SPROUT_CONSTEXPR random_iterator operator()() const { - return count_ != 0 - ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) - : throw std::out_of_range("random_iterator<>: increment at out of range") - ; - } - random_result_type& random_result() { - return random_; - } - SPROUT_CONSTEXPR random_result_type const& random_result() const { - return random_; - } - result_type& result() { - return random_.result(); - } - SPROUT_CONSTEXPR result_type const& result() const { - return random_.result(); - } - engine_type& engine() { - return random_.engine(); - } - SPROUT_CONSTEXPR engine_type const& engine() const { - return random_.engine(); - } - SPROUT_CONSTEXPR result_type min() const { - return random_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return random_.max(); - } - SPROUT_CONSTEXPR result_type count() const { - return count_; - } - void swap(random_iterator& other) { - using std::swap; - swap(random_, other.random_); - swap(count_, other.count_); - } - friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { - return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_); - } - friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) { - return !(lhs == rhs); - } - SPROUT_CONSTEXPR reference operator*() const { - return count_ != 0 - ? random_.result() - : (throw std::out_of_range("random_iterator<>: dereference at out of range"), random_.result()) - ; - } - SPROUT_CONSTEXPR pointer operator->() const { - return count_ > 0 - ? &random_.result() - : throw std::out_of_range("random_iterator<>: dereference at out of range") - ; - } - random_iterator& operator++() { - random_iterator temp((*this)()); - temp.swap(*this); - return *this; - } - random_iterator operator++(int) { - random_iterator result(*this); - ++*this; - return result; - } - }; - // - // swap - // - template - void swap( - sprout::random::random_iterator& lhs, - sprout::random::random_iterator& rhs - ) - { - lhs.swap(rhs); - } - - // - // begin - // - template - SPROUT_CONSTEXPR typename std::enable_if< - !std::is_integral::value, - sprout::random::random_iterator - >::type begin( - Engine const& engine, - Distribution const& distribution, - typename sprout::random::random_iterator::difference_type count = -1 - ) - { - return sprout::random::random_iterator(engine, distribution, count); - } - template - SPROUT_CONSTEXPR sprout::random::random_iterator begin( - Engine const& engine, - typename sprout::random::random_iterator::difference_type count = -1 - ) - { - return sprout::random::random_iterator(engine, count); - } - - // - // end - // - template - SPROUT_CONSTEXPR sprout::random::random_iterator end( - Engine const& engine, - Distribution const& distribution - ) - { - return sprout::random::random_iterator(); - } - template - SPROUT_CONSTEXPR sprout::random::random_iterator end( - Engine const& engine - ) - { - return sprout::random::random_iterator(); - } - - // - // iterator_next - // - template - SPROUT_CONSTEXPR sprout::random::random_iterator iterator_next( - sprout::random::random_iterator const& it - ) - { - return it(); - } - } // namespace random - - using sprout::random::random_iterator; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP