diff --git a/sprout/bitset.hpp b/sprout/bitset.hpp new file mode 100644 index 00000000..59fb0307 --- /dev/null +++ b/sprout/bitset.hpp @@ -0,0 +1,1424 @@ +#ifndef SPROUT_BITSET_HPP +#define SPROUT_BITSET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT +#include HDR_NUMERIC_SSCRISK_CEL_OR_SPROUT +#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR std::size_t + popcount(T n) { + return n == 0 ? 0 + : 1 + sprout::detail::popcount(n & (n - 1)) + ; + } + + template + inline SPROUT_CONSTEXPR std::size_t + clz_impl(T n, T m = 1 << (CHAR_BIT * sizeof(T))) { + return m == 0 || n & m ? 0 + : 1 + sprout::detail::clz_impl(n, m >> 1) + ; + } + template + inline SPROUT_CONSTEXPR std::size_t + clz(T n) { + return sprout::detail::clz_impl(n >> 1); + } + + template + inline SPROUT_CONSTEXPR std::size_t + ctz(T n) { + return n & 1 ? 0 + : 1 + sprout::detail::ctz(n >> 1) + ; + } + } // namespace detail + + namespace detail { + struct base_bitset_from_words_construct_tag {}; + + template + class base_bitset { + public: + typedef unsigned long word_type; + typedef word_type value_type; + typedef sprout::index_iterator&> iterator; + typedef sprout::index_iterator const&> const_iterator; + typedef value_type& reference; + typedef value_type const& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + SPROUT_STATIC_CONSTEXPR std::size_t static_size = N; + public: + struct are_all_pred { + public: + SPROUT_CONSTEXPR bool + operator()(word_type t) const SPROUT_NOEXCEPT { + return t != ~static_cast(0); + } + }; + struct is_any_pred { + public: + SPROUT_CONSTEXPR bool + operator()(word_type t) const SPROUT_NOEXCEPT { + return t != static_cast(0); + } + }; + struct to_ulong_pred { + public: + SPROUT_CONSTEXPR bool + operator()(word_type t) const SPROUT_NOEXCEPT { + return t != 0; + } + }; + struct count_op { + public: + SPROUT_CONSTEXPR std::size_t + operator()(std::size_t lhs, std::size_t rhs) const SPROUT_NOEXCEPT { + return lhs + sprout::detail::popcount(rhs); + } + }; + public: + static SPROUT_CONSTEXPR std::size_t + whichword(std::size_t pos) SPROUT_NOEXCEPT { + return pos / (CHAR_BIT * sizeof(unsigned long)); + } + static SPROUT_CONSTEXPR std::size_t + whichbyte(std::size_t pos) SPROUT_NOEXCEPT { + return (pos % (CHAR_BIT * sizeof(unsigned long))) / CHAR_BIT; + } + static SPROUT_CONSTEXPR std::size_t + whichbit(std::size_t pos) SPROUT_NOEXCEPT { + return pos % (CHAR_BIT * sizeof(unsigned long)); + } + static SPROUT_CONSTEXPR word_type + maskbit(std::size_t pos) SPROUT_NOEXCEPT { + return (static_cast(1)) << whichbit(pos); + } + private: + word_type w_[N]; + private: + SPROUT_CONSTEXPR std::size_t + find_first_impl( + std::size_t not_found, const_iterator first, const_iterator last, + std::size_t i = 0 + ) const SPROUT_NOEXCEPT + { + return first == last ? not_found + : *first != static_cast(0) + ? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::detail::ctz(*first) + : find_first_impl(not_found, sprout::next(first), last, i + 1) + ; + } + SPROUT_CONSTEXPR std::size_t + find_next_impl_2( + std::size_t not_found, const_iterator first, const_iterator last, + std::size_t i + ) const SPROUT_NOEXCEPT + { + return first == last ? not_found + : *first != static_cast(0) + ? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::detail::ctz(*first) + : find_next_impl_2(not_found, sprout::next(first), last) + ; + } + SPROUT_CONSTEXPR std::size_t + find_next_impl_1(std::size_t not_found, std::size_t i, word_type thisword) const SPROUT_NOEXCEPT { + return thisword != static_cast(0) + ? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::detail::ctz(thisword) + : find_next_impl_2(not_found, begin() + (i + 1), end(), i + 1) + ; + } + SPROUT_CONSTEXPR std::size_t + find_next_impl(std::size_t prev, std::size_t not_found, std::size_t i) const SPROUT_NOEXCEPT { + return find_next_impl_1(not_found, i, w_[i] & ~static_cast(0) << whichbit(prev)); + } + template + SPROUT_CONSTEXPR base_bitset + do_left_shift_impl_2( + std::size_t wshift, std::size_t offset, std::size_t sub_offset, + sprout::index_tuple + ) const SPROUT_NOEXCEPT + { + return base_bitset( + sprout::detail::base_bitset_from_words_construct_tag(), + (static_cast(Indexes) > wshift + ? (w_[Indexes - wshift] << offset) | (w_[Indexes - wshift - 1] >> sub_offset) + : Indexes == wshift ? w_[0] << offset + : static_cast(0) + )... + ) + ; + } + template + SPROUT_CONSTEXPR base_bitset + do_left_shift_impl_1( + std::size_t wshift, std::size_t offset, + sprout::index_tuple + ) const SPROUT_NOEXCEPT + { + return base_bitset( + sprout::detail::base_bitset_from_words_construct_tag(), + (static_cast(Indexes) >= wshift ? w_[Indexes - wshift] + : static_cast(0) + )... + ) + ; + } + SPROUT_CONSTEXPR base_bitset + do_left_shift_impl(std::size_t wshift, std::size_t offset) const SPROUT_NOEXCEPT { + return offset == 0 + ? do_left_shift_impl_1( + wshift, offset, + sprout::index_range<0, N>::make() + ) + : do_left_shift_impl_2( + wshift, offset, (CHAR_BIT * sizeof(unsigned long)) - offset, + sprout::index_range<0, N>::make() + ) + ; + } + template + SPROUT_CONSTEXPR base_bitset + do_right_shift_impl_2( + std::size_t wshift, std::size_t offset, std::size_t limit, std::size_t sub_offset, + sprout::index_tuple + ) const SPROUT_NOEXCEPT + { + return base_bitset( + sprout::detail::base_bitset_from_words_construct_tag(), + (static_cast(Indexes) < limit + ? (w_[Indexes + wshift] >> offset) | (w_[Indexes + wshift + 1] << sub_offset) + : Indexes == limit ? w_[N-1] >> offset + : static_cast(0) + )... + ) + ; + } + template + SPROUT_CONSTEXPR base_bitset + do_right_shift_impl_1( + std::size_t wshift, std::size_t offset, std::size_t limit, + sprout::index_tuple + ) const SPROUT_NOEXCEPT + { + return base_bitset( + sprout::detail::base_bitset_from_words_construct_tag(), + (static_cast(Indexes) <= limit ? w_[Indexes + wshift] + : static_cast(0) + )... + ) + ; + } + SPROUT_CONSTEXPR base_bitset + do_right_shift_impl(std::size_t wshift, std::size_t offset, std::size_t limit) const SPROUT_NOEXCEPT { + return offset == 0 + ? do_right_shift_impl_1( + wshift, offset, limit, + sprout::index_range<0, N>::make() + ) + : do_right_shift_impl_2( + wshift, offset, limit, (CHAR_BIT * sizeof(unsigned long)) - offset, + sprout::index_range<0, N>::make() + ) + ; + } + public: + SPROUT_CONSTEXPR base_bitset() SPROUT_NOEXCEPT + : w_() + {} + SPROUT_CONSTEXPR base_bitset(unsigned long long val) SPROUT_NOEXCEPT + : w_{word_type(val), word_type(val >> (CHAR_BIT * sizeof(unsigned long)))} + {} + template + SPROUT_CONSTEXPR base_bitset(sprout::detail::base_bitset_from_words_construct_tag, Words... words) + : w_{words...} + {} + + void + setword(std::size_t pos, word_type word) SPROUT_NOEXCEPT { + w_[whichword(pos)] = word; + } + SPROUT_CONSTEXPR base_bitset + setword(std::size_t pos, word_type word) const SPROUT_NOEXCEPT { + return sprout::fixed::set(*this, whichword(pos), word); + } + + word_type& + getword(std::size_t pos) SPROUT_NOEXCEPT { + return w_[whichword(pos)]; + } + SPROUT_CONSTEXPR word_type + getword(std::size_t pos) const SPROUT_NOEXCEPT { + return w_[whichword(pos)]; + } + SPROUT_CONSTEXPR word_type const* + getdata() const SPROUT_NOEXCEPT { + return w_; + } + word_type& + hiword() SPROUT_NOEXCEPT { + return w_[N - 1]; + } + SPROUT_CONSTEXPR word_type + hiword() const SPROUT_NOEXCEPT { + return w_[N - 1]; + } + + void + do_and(base_bitset const& x) SPROUT_NOEXCEPT { + for (std::size_t i = 0; i < N; i++) { + w_[i] &= x.w_[i]; + } + } + SPROUT_CONSTEXPR base_bitset + do_and(base_bitset const& x) const SPROUT_NOEXCEPT { + return sprout::fixed::transform( + begin(), end(), x.begin(), *this, NS_SSCRISK_CEL_OR_SPROUT::bit_and() + ); + } + void + do_or(base_bitset const& x) SPROUT_NOEXCEPT { + for (std::size_t i = 0; i < N; i++) { + w_[i] |= x.w_[i]; + } + } + SPROUT_CONSTEXPR base_bitset + do_or(base_bitset const& x) const SPROUT_NOEXCEPT { + return sprout::fixed::transform( + begin(), end(), x.begin(), *this, NS_SSCRISK_CEL_OR_SPROUT::bit_or() + ); + } + void + do_xor(base_bitset const& x) SPROUT_NOEXCEPT { + for (std::size_t i = 0; i < N; i++) { + w_[i] ^= x.w_[i]; + } + } + SPROUT_CONSTEXPR base_bitset + do_xor(base_bitset const& x) const SPROUT_NOEXCEPT { + return sprout::fixed::transform( + begin(), end(), x.begin(), *this, NS_SSCRISK_CEL_OR_SPROUT::bit_xor() + ); + } + void + do_left_shift(std::size_t shift) SPROUT_NOEXCEPT { + if (shift != 0) { + std::size_t const wshift = shift / (CHAR_BIT * sizeof(unsigned long)); + std::size_t const offset = shift % (CHAR_BIT * sizeof(unsigned long)); + if (offset == 0) { + for (std::size_t n = N - 1; n >= wshift; --n) { + w_[n] = w_[n - wshift]; + } + } else { + std::size_t const sub_offset = (CHAR_BIT * sizeof(unsigned long)) - offset; + for (std::size_t n = N - 1; n > wshift; --n) { + w_[n] = (w_[n - wshift] << offset) | (w_[n - wshift - 1] >> sub_offset); + } + w_[wshift] = w_[0] << offset; + } + std::fill(w_ + 0, w_ + wshift, static_cast(0)); + } + } + SPROUT_CONSTEXPR base_bitset + do_left_shift(std::size_t shift) const SPROUT_NOEXCEPT { + return shift != 0 ? do_left_shift_impl( + shift / (CHAR_BIT * sizeof(unsigned long)), + shift % (CHAR_BIT * sizeof(unsigned long)) + ) + : *this + ; + } + void + do_right_shift(std::size_t shift) SPROUT_NOEXCEPT { + if (shift != 0) { + std::size_t const wshift = shift / (CHAR_BIT * sizeof(unsigned long)); + std::size_t const offset = shift % (CHAR_BIT * sizeof(unsigned long)); + std::size_t const limit = N - wshift - 1; + if (offset == 0) { + for (std::size_t n = 0; n <= limit; ++n) { + w_[n] = w_[n + wshift]; + } + } else { + std::size_t const sub_offset = (CHAR_BIT * sizeof(unsigned long)) - offset; + for (std::size_t n = 0; n < limit; ++n) { + w_[n] = (w_[n + wshift] >> offset) | (w_[n + wshift + 1] << sub_offset); + } + w_[limit] = w_[N-1] >> offset; + } + std::fill(w_ + limit + 1, w_ + N, static_cast(0)); + } + } + SPROUT_CONSTEXPR base_bitset + do_right_shift(std::size_t shift) const SPROUT_NOEXCEPT { + return shift != 0 ? do_right_shift_impl( + shift / (CHAR_BIT * sizeof(unsigned long)), + shift % (CHAR_BIT * sizeof(unsigned long)), + N - shift / (CHAR_BIT * sizeof(unsigned long)) - 1 + ) + : *this + ; + } + void + do_flip() SPROUT_NOEXCEPT { + for (std::size_t i = 0; i < N; i++) { + w_[i] = ~w_[i]; + } + } + SPROUT_CONSTEXPR base_bitset + do_flip() const SPROUT_NOEXCEPT { + return sprout::fixed::transform( + begin(), end(), *this, NS_SSCRISK_CEL_OR_SPROUT::bit_not() + ); + } + SPROUT_CONSTEXPR base_bitset + do_set() const SPROUT_NOEXCEPT { + return sprout::fixed::fill(*this, ~static_cast(0)); + } + void + do_set() SPROUT_NOEXCEPT { + for (std::size_t i = 0; i < N; i++) { + w_[i] = ~static_cast(0); + } + } + SPROUT_CONSTEXPR base_bitset + do_reset() SPROUT_NOEXCEPT { + return base_bitset(); + } + void + do_reset() SPROUT_NOEXCEPT { + std::memset(w_, 0, N * sizeof(word_type)); + } + + SPROUT_CONSTEXPR bool + is_equal(base_bitset const& x) const SPROUT_NOEXCEPT { + return NS_SSCRISK_CEL_OR_SPROUT::equal(begin(), end(), x.begin()); + } + template + SPROUT_CONSTEXPR bool + are_all() const SPROUT_NOEXCEPT { + return NS_SSCRISK_CEL_OR_SPROUT::all_of(begin(), end(), are_all_pred()) + && hiword() == (~static_cast(0) >> (N * (CHAR_BIT * sizeof(unsigned long)) - N2)) + ; + } + SPROUT_CONSTEXPR bool + is_any() const SPROUT_NOEXCEPT { + return NS_SSCRISK_CEL_OR_SPROUT::any_of(begin(), end(), is_any_pred()); + } + SPROUT_CONSTEXPR std::size_t + count() const SPROUT_NOEXCEPT { + return NS_SSCRISK_CEL_OR_SPROUT::accumulate(begin(), end(),static_cast(0), count_op()); + } + + SPROUT_CONSTEXPR unsigned long + to_ulong() const { + return NS_SSCRISK_CEL_OR_SPROUT::find_if(begin() + 1, end(), to_ulong_pred()) != end() + ? throw std::overflow_error("base_bitset::to_ulong") + : w_[0] + ; + } + SPROUT_CONSTEXPR unsigned long long + to_ullong() const { + return NS_SSCRISK_CEL_OR_SPROUT::find_if( + sizeof(unsigned long long) > sizeof(unsigned long) ? begin() + 2 + : begin() + 1 + , + end(), + to_ulong_pred() + ) != end() + ? throw std::overflow_error("base_bitset::to_ullong") + : sizeof(unsigned long long) > sizeof(unsigned long) + ? w_[0] + (static_cast(w_[1]) << (CHAR_BIT * sizeof(unsigned long))) + : w_[0] + ; + } + + SPROUT_CONSTEXPR std::size_t + find_first(std::size_t not_found) const SPROUT_NOEXCEPT { + return find_first_impl(not_found, begin(), end()); + } + SPROUT_CONSTEXPR std::size_t + find_next(std::size_t prev, std::size_t not_found) const SPROUT_NOEXCEPT { + return prev + 1 >= N * (CHAR_BIT * sizeof(unsigned long)) ? not_found + : find_next_impl(prev + 1, not_found, whichword(prev + 1)); + ; + } + + word_type& operator[](std::size_t i) { + return w_[i]; + } + SPROUT_CONSTEXPR word_type const& operator[](std::size_t i) const { + return w_[i]; + } + iterator begin() SPROUT_NOEXCEPT { + return iterator(*this, 0); + } + SPROUT_CONSTEXPR const_iterator begin() const SPROUT_NOEXCEPT { + return const_iterator(*this, 0); + } + iterator end() SPROUT_NOEXCEPT { + return iterator(*this, N); + } + SPROUT_CONSTEXPR const_iterator end() const SPROUT_NOEXCEPT { + return const_iterator(*this, N); + } + }; + + template<> + class base_bitset<1> { + public: + typedef unsigned long word_type; + private: + word_type w_; + public: + static SPROUT_CONSTEXPR std::size_t + whichword(std::size_t pos) SPROUT_NOEXCEPT { + return pos / (CHAR_BIT * sizeof(unsigned long)); + } + static SPROUT_CONSTEXPR std::size_t + whichbyte(std::size_t pos) SPROUT_NOEXCEPT { + return (pos % (CHAR_BIT * sizeof(unsigned long))) / CHAR_BIT; + } + static SPROUT_CONSTEXPR std::size_t + whichbit(std::size_t pos) SPROUT_NOEXCEPT { + return pos % (CHAR_BIT * sizeof(unsigned long)); + } + static SPROUT_CONSTEXPR word_type + maskbit(std::size_t pos) SPROUT_NOEXCEPT { + return (static_cast(1)) << whichbit(pos); + } + private: + SPROUT_CONSTEXPR std::size_t + find_next_impl(std::size_t prev, std::size_t not_found, word_type x) const SPROUT_NOEXCEPT { + return x != 0 ? sprout::detail::ctz(x) + prev + : not_found + ; + } + public: + SPROUT_CONSTEXPR base_bitset() SPROUT_NOEXCEPT + : w_(0) + {} + SPROUT_CONSTEXPR base_bitset(unsigned long long val) SPROUT_NOEXCEPT + : w_(val) + {} + SPROUT_CONSTEXPR base_bitset(base_bitset_from_words_construct_tag, word_type word) + : w_{word} + {} + + word_type& + getword(std::size_t) SPROUT_NOEXCEPT { + return w_; + } + SPROUT_CONSTEXPR word_type + getword(std::size_t) const SPROUT_NOEXCEPT { + return w_; + } + SPROUT_CONSTEXPR word_type const* + getdata() const SPROUT_NOEXCEPT { + return &w_; + } + word_type& + hiword() SPROUT_NOEXCEPT { + return w_; + } + SPROUT_CONSTEXPR word_type + hiword() const SPROUT_NOEXCEPT { + return w_; + } + + void + do_and(base_bitset<1> const& x) SPROUT_NOEXCEPT { + w_ &= x.w_; + } + SPROUT_CONSTEXPR base_bitset<1> + do_and(base_bitset<1> const& x) const SPROUT_NOEXCEPT { + return base_bitset<1>(w_ & x.w_); + } + void + do_or(base_bitset<1> const& x) SPROUT_NOEXCEPT { + w_ |= x.w_; + } + SPROUT_CONSTEXPR base_bitset<1> + do_or(base_bitset<1> const& x) const SPROUT_NOEXCEPT { + return base_bitset<1>(w_ | x.w_); + } + void + do_xor(base_bitset<1> const& x) SPROUT_NOEXCEPT { + w_ ^= x.w_; + } + SPROUT_CONSTEXPR base_bitset<1> + do_xor(base_bitset<1> const& x) const SPROUT_NOEXCEPT { + return base_bitset<1>(w_ ^ x.w_); + } + void + do_left_shift(std::size_t shift) SPROUT_NOEXCEPT { + w_ <<= shift; + } + SPROUT_CONSTEXPR base_bitset<1> + do_left_shift(base_bitset<1> const& x) const SPROUT_NOEXCEPT { + return base_bitset<1>(w_ << x.w_); + } + void + do_right_shift(std::size_t shift) SPROUT_NOEXCEPT { + w_ >>= shift; + } + SPROUT_CONSTEXPR base_bitset<1> + do_right_shift(base_bitset<1> const& x) const SPROUT_NOEXCEPT { + return base_bitset<1>(w_ >> x.w_); + } + void + do_flip() SPROUT_NOEXCEPT { + w_ = ~w_; + } + SPROUT_CONSTEXPR base_bitset<1> + do_flip() const SPROUT_NOEXCEPT { + return base_bitset<1>(~w_); + } + void + do_set() SPROUT_NOEXCEPT { + w_ = ~static_cast(0); + } + SPROUT_CONSTEXPR base_bitset<1> + do_set() const SPROUT_NOEXCEPT { + return base_bitset<1>(~static_cast(0)); + } + void + do_reset() SPROUT_NOEXCEPT { + w_ = 0; + } + SPROUT_CONSTEXPR base_bitset<1> + do_reset() const SPROUT_NOEXCEPT { + return base_bitset<1>(0); + } + + SPROUT_CONSTEXPR bool + is_equal(base_bitset<1> const& x) const SPROUT_NOEXCEPT { + return w_ == x.w_; + } + template + SPROUT_CONSTEXPR bool + are_all() const SPROUT_NOEXCEPT { + return w_ == ~static_cast(0) >> ((CHAR_BIT * sizeof(unsigned long)) - N2); + } + SPROUT_CONSTEXPR bool + is_any() const SPROUT_NOEXCEPT { + return w_ != 0; + } + SPROUT_CONSTEXPR std::size_t + count() const SPROUT_NOEXCEPT { + return sprout::detail::popcount(w_); + } + + SPROUT_CONSTEXPR unsigned long + to_ulong() const SPROUT_NOEXCEPT { + return w_; + } + SPROUT_CONSTEXPR unsigned long long + to_ullong() const SPROUT_NOEXCEPT { + return w_; + } + + SPROUT_CONSTEXPR std::size_t + find_first(std::size_t not_found) const SPROUT_NOEXCEPT { + return w_ != 0 ? sprout::detail::ctz(w_) + : not_found + ; + } + SPROUT_CONSTEXPR std::size_t + find_next(std::size_t prev, std::size_t not_found) const SPROUT_NOEXCEPT { + return prev + 1 >= static_cast(CHAR_BIT * sizeof(unsigned long)) ? not_found + : find_next_impl(prev + 1, not_found, w_ >> (prev + 1)) + ; + } + }; + + template<> + class base_bitset<0> { + public: + typedef unsigned long word_type; + public: + static SPROUT_CONSTEXPR std::size_t + whichword(std::size_t pos) SPROUT_NOEXCEPT { + return pos / (CHAR_BIT * sizeof(unsigned long)); + } + + static SPROUT_CONSTEXPR std::size_t + whichbyte(std::size_t pos) SPROUT_NOEXCEPT { + return (pos % (CHAR_BIT * sizeof(unsigned long))) / CHAR_BIT; + } + + static SPROUT_CONSTEXPR std::size_t + whichbit(std::size_t pos) SPROUT_NOEXCEPT { + return pos % (CHAR_BIT * sizeof(unsigned long)); + } + + static SPROUT_CONSTEXPR word_type + maskbit(std::size_t pos) SPROUT_NOEXCEPT { + return (static_cast(1)) << whichbit(pos); + } + public: + SPROUT_CONSTEXPR base_bitset() SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset(unsigned long long) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset(base_bitset_from_words_construct_tag) {} + + word_type& + getword(std::size_t) SPROUT_NOEXCEPT { + return throw std::out_of_range("base_bitset::getword"), *new word_type(); + } + SPROUT_CONSTEXPR word_type + getword(std::size_t pos) const SPROUT_NOEXCEPT { + return 0; + } + SPROUT_CONSTEXPR word_type + hiword() const SPROUT_NOEXCEPT { + return 0; + } + + void + do_and(base_bitset<0> const&) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_and(base_bitset<0> const&) const SPROUT_NOEXCEPT { + return *this; + } + void + do_or(base_bitset<0> const&) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_or(base_bitset<0> const&) const SPROUT_NOEXCEPT { + return *this; + } + void + do_xor(base_bitset<0> const&) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_xor(base_bitset<0> const&) const SPROUT_NOEXCEPT { + return *this; + } + void + do_left_shift(std::size_t) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_left_shift(base_bitset<0> const&) const SPROUT_NOEXCEPT { + return *this; + } + void + do_right_shift(std::size_t) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_right_shift(base_bitset<0> const&) const SPROUT_NOEXCEPT { + return *this; + } + void + do_flip() SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_flip() const SPROUT_NOEXCEPT { + return *this; + } + void + do_set() SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_set() SPROUT_NOEXCEPT { + return base_bitset<0>(); + } + void + do_reset() SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR base_bitset<0> + do_reset() SPROUT_NOEXCEPT { + return base_bitset<0>(); + } + + SPROUT_CONSTEXPR bool + is_equal(base_bitset<0> const&) const SPROUT_NOEXCEPT { + return true; + } + template + SPROUT_CONSTEXPR bool + are_all() const SPROUT_NOEXCEPT { + return true; + } + SPROUT_CONSTEXPR bool + is_any() const SPROUT_NOEXCEPT { + return false; + } + SPROUT_CONSTEXPR std::size_t + count() const SPROUT_NOEXCEPT { + return 0; + } + + SPROUT_CONSTEXPR unsigned long + to_ulong() const SPROUT_NOEXCEPT { + return 0; + } + SPROUT_CONSTEXPR unsigned long long + to_ullong() const SPROUT_NOEXCEPT { + return 0; + } + + SPROUT_CONSTEXPR std::size_t + find_first(std::size_t) const SPROUT_NOEXCEPT { + return 0; + } + SPROUT_CONSTEXPR std::size_t + find_next(std::size_t, std::size_t) const SPROUT_NOEXCEPT { + return 0; + } + }; + + template + struct sanitize { + public: + typedef unsigned long word_type; + public: + static void + do_sanitize(word_type& val) SPROUT_NOEXCEPT { + val &= ~((~static_cast(0)) << Extrabits); + } + static SPROUT_CONSTEXPR word_type + do_sanitize_c(word_type val) SPROUT_NOEXCEPT { + return val & ~((~static_cast(0)) << Extrabits); + } + }; + template<> + struct sanitize<0> { + public: + typedef unsigned long word_type; + public: + static void + do_sanitize(word_type) SPROUT_NOEXCEPT {} + static SPROUT_CONSTEXPR word_type + do_sanitize_c(word_type val) SPROUT_NOEXCEPT { + return val; + } + }; + + template + struct sanitize_val { + public: + static SPROUT_CONSTEXPR unsigned long long + do_sanitize_val(unsigned long long val) { + return val; + } + }; + template + struct sanitize_val { + public: + static SPROUT_CONSTEXPR unsigned long long + do_sanitize_val(unsigned long long val) { + return val & ~((~static_cast(0)) << N2); + } + }; + } // namespace detail + + template + struct container_construct_traits > { + public: + typedef sprout::detail::base_bitset copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::forward(cont); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return copied_type(sprout::detail::base_bitset_from_words_construct_tag(), args...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return make(args...); + } + }; + + template + class bitset; + + template + inline SPROUT_CONSTEXPR bitset + operator&(sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT; + template + inline SPROUT_CONSTEXPR bitset + operator|(sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT; + template + inline SPROUT_CONSTEXPR bitset + operator^(sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT; + template + inline std::basic_istream& + operator>>(std::basic_istream& lhs, sprout::bitset& rhs); + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::bitset const& rhs); + + template + inline SPROUT_CONSTEXPR std::size_t + hash_value(sprout::bitset const& v); + + // + // bitset + // + template + class bitset + : private sprout::detail::base_bitset< + N / (CHAR_BIT * sizeof(unsigned long)) + (N % (CHAR_BIT * sizeof(unsigned long)) == 0 ? 0 : 1) + > + { + private: + typedef sprout::detail::base_bitset< + N / (CHAR_BIT * sizeof(unsigned long)) + (N % (CHAR_BIT * sizeof(unsigned long)) == 0 ? 0 : 1) + > base_type; + typedef unsigned long word_type; + public: + class reference { + friend class bitset; + private: + word_type* wp_; + std::size_t bpos_; + private: + reference() = delete; + public: + reference(bitset& b, std::size_t pos) SPROUT_NOEXCEPT + : wp_(&b.getword(pos)) + , bpos_(base_type::whichbit(pos)) + {} + ~reference() SPROUT_NOEXCEPT {} + + reference& + operator=(bool x) SPROUT_NOEXCEPT { + if (x) { + *wp_ |= base_type::maskbit(bpos_); + } else { + *wp_ &= ~base_type::maskbit(bpos_); + } + return *this; + } + reference& + operator=(const reference& j) SPROUT_NOEXCEPT { + if ((*(j.wp_) & base_type::maskbit(j.bpos_))) { + *wp_ |= base_type::maskbit(bpos_); + } else { + *wp_ &= ~base_type::maskbit(bpos_); + } + return *this; + } + + bool + operator~() const SPROUT_NOEXCEPT { + return (*wp_ & base_type::maskbit(bpos_)) == 0; + } + operator bool() const SPROUT_NOEXCEPT { + return (*wp_ & base_type::maskbit(bpos_)) != 0; + } + reference& + flip() SPROUT_NOEXCEPT { + *wp_ ^= base_type::maskbit(bpos_); + return *this; + } + }; + friend class reference; + private: + explicit SPROUT_CONSTEXPR bitset(base_type const& base) SPROUT_NOEXCEPT + : base_type(base) + {} + + void + do_sanitize() SPROUT_NOEXCEPT { + typedef sprout::detail::sanitize sanitize_type; + sanitize_type::do_sanitize(this->hiword()); + } + SPROUT_CONSTEXPR bitset + do_sanitize() const SPROUT_NOEXCEPT { + typedef sprout::detail::sanitize sanitize_type; + return sanitize_type::do_sanitize_c(this->hiword()); + } + + bitset& + unchecked_set(std::size_t pos) SPROUT_NOEXCEPT { + this->getword(pos) |= base_type::maskbit(pos); + return *this; + } + SPROUT_CONSTEXPR bitset + unchecked_set(std::size_t pos) const SPROUT_NOEXCEPT { + return bitset(this->setword(pos, this->getword(pos) | base_type::maskbit(pos))); + } + bitset& + unchecked_set(std::size_t pos, int val) SPROUT_NOEXCEPT { + if (val) { + this->getword(pos) |= base_type::maskbit(pos); + } else { + this->getword(pos) &= ~base_type::maskbit(pos); + } + return *this; + } + SPROUT_CONSTEXPR bitset + unchecked_set(std::size_t pos, int val) const SPROUT_NOEXCEPT { + return val ? bitset(this->setword(pos, this->getword(pos) | base_type::maskbit(pos))) + : bitset(this->setword(pos, this->getword(pos) & base_type::maskbit(pos))) + ; + } + bitset& + unchecked_reset(std::size_t pos) SPROUT_NOEXCEPT { + this->getword(pos) &= ~base_type::maskbit(pos); + return *this; + } + SPROUT_CONSTEXPR bitset + unchecked_reset(std::size_t pos) const SPROUT_NOEXCEPT { + return bitset(this->setword(pos, this->getword(pos) & ~base_type::maskbit(pos))); + } + bitset& + unchecked_flip(std::size_t pos) SPROUT_NOEXCEPT { + this->getword(pos) ^= base_type::maskbit(pos); + return *this; + } + SPROUT_CONSTEXPR bitset + unchecked_flip(std::size_t pos) const SPROUT_NOEXCEPT { + return bitset(this->setword(pos, this->getword(pos) ^ base_type::maskbit(pos))); + } + SPROUT_CONSTEXPR bool + unchecked_test(std::size_t pos) const SPROUT_NOEXCEPT { + return (this->getword(pos) & base_type::maskbit(pos)) != static_cast(0); + } + + template + void + copy_from_ptr(const Char* s, std::size_t len, std::size_t pos, std::size_t n, Char zero, Char one) { + reset(); + std::size_t const nbits = std::min(N, std::min(n, len - pos)); + for (std::size_t i = nbits; i > 0; --i) { + Char const c = s[pos + nbits - i]; + if (Traits::eq(c, zero)) { + } else if (Traits::eq(c, one)) { + unchecked_set(i - 1); + } else { + throw std::invalid_argument("bitset::copy_from_ptr"); + } + } + } + template + void + copy_from_string( + std::basic_string const& s, + std::size_t pos, std::size_t n, Char zero, Char one + ) + { + copy_from_ptr(s.data(), s.size(), pos, n, zero, one); + } + template + void + copy_to_string(std::basic_string& s, Char zero, Char one) const { + s.assign(N, zero); + for (std::size_t i = N; i > 0; --i) { + if (unchecked_test(i - 1)) { + Traits::assign(s[N - i], one); + } + } + } + template + void + copy_from_string(std::basic_string const& s, std::size_t pos, std::size_t n) { + copy_from_string(s, pos, n, Char('0'), Char('1')); + } + template + void + copy_to_string(std::basic_string& s) const { + copy_to_string(s, Char('0'), Char('1')); + } + public: + // 20.5.1 constructors: + SPROUT_CONSTEXPR bitset() SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR bitset(unsigned long long val) SPROUT_NOEXCEPT + : base_type(sprout::detail::sanitize_val::do_sanitize_val(val)) + {} + template + explicit bitset(std::basic_string const& s, std::size_t position = 0) + : base_type() + { + if (position > s.size()) { + throw std::out_of_range("bitset::bitset initial position not valid"); + } + copy_from_string(s, position, std::basic_string::npos, Char('0'), Char('1')); + } + template + bitset(std::basic_string const& s, std::size_t position, std::size_t n) + : base_type() + { + if (position > s.size()) { + throw std::out_of_range("bitset::bitset initial position not valid"); + } + copy_from_string(s, position, n, Char('0'), Char('1')); + } + + template + bitset( + std::basic_string const& s, std::size_t position, std::size_t n, + Char zero, Char one = Char('1') + ) + : base_type() + { + if (position > s.size()) { + throw std::out_of_range("bitset::bitset initial position not valid"); + } + copy_from_string(s, position, n, zero, one); + } + template + explicit bitset( + Char const* str, typename std::basic_string::std::size_type n = std::basic_string::npos, + Char zero = Char('0'), Char one = Char('1') + ) + : base_type() + { + if (!str) { + throw std::out_of_range("bitset::bitset"); + } + if (n == std::basic_string::npos) { + n = std::char_traits::length(str); + } + copy_from_ptr>(str, n, 0, n, zero, one); + } + // 20.5.2 bitset operations: + bitset& + operator&=(bitset const& rhs) SPROUT_NOEXCEPT { + this->do_and(rhs); + return *this; + } + bitset& + operator|=(bitset const& rhs) SPROUT_NOEXCEPT { + this->do_or(rhs); + return *this; + } + bitset& + operator^=(bitset const& rhs) SPROUT_NOEXCEPT { + this->do_xor(rhs); + return *this; + } + bitset& + operator<<=(std::size_t position) SPROUT_NOEXCEPT { + if (position < N) { + this->do_left_shift(position); + this->do_sanitize(); + } else { + this->do_reset(); + } + return *this; + } + bitset& + operator>>=(std::size_t position) SPROUT_NOEXCEPT { + if (position < N) { + this->do_right_shift(position); + this->do_sanitize(); + } else { + this->do_reset(); + } + return *this; + } + bitset& + set() SPROUT_NOEXCEPT { + this->do_set(); + this->do_sanitize(); + return *this; + } + SPROUT_CONSTEXPR bitset + set() const SPROUT_NOEXCEPT { + return bitset(this->do_set()).do_sanitize(); + } + bitset& + set(std::size_t position, bool val = true) { + if (position >= N) { + throw std::out_of_range("bitset::set"); + } + return unchecked_set(position, val); + } + SPROUT_CONSTEXPR bitset + set(std::size_t position, bool val = true) const { + return position >= N ? throw std::out_of_range("bitset::set") + : unchecked_set(position, val) + ; + } + bitset& + reset() SPROUT_NOEXCEPT { + this->do_reset(); + return *this; + } + SPROUT_CONSTEXPR bitset + reset() const SPROUT_NOEXCEPT { + return bitset(this->do_reset()); + } + bitset& + reset(std::size_t position) { + if (position >= N) { + throw std::out_of_range("bitset::reset"); + } + return unchecked_reset(position); + } + SPROUT_CONSTEXPR bitset + reset(std::size_t position) const { + return position >= N ? throw std::out_of_range("bitset::reset") + : unchecked_reset(position) + ; + } + bitset& + flip() SPROUT_NOEXCEPT { + this->do_flip(); + this->do_sanitize(); + return *this; + } + SPROUT_CONSTEXPR bitset + flip() const SPROUT_NOEXCEPT { + return bitset(this->do_flip()).do_sanitize(); + } + bitset& + flip(std::size_t position) { + if (position >= N) { + throw std::out_of_range("bitset::flip"); + } + return unchecked_flip(position); + } + SPROUT_CONSTEXPR bitset + flip(std::size_t position) const { + return position >= N ? throw std::out_of_range("bitset::flip") + : unchecked_flip(position) + ; + } + SPROUT_CONSTEXPR bitset + operator~() const SPROUT_NOEXCEPT { + return flip(); + } + + // element access: + reference + operator[](std::size_t position) { + return reference(*this, position); + } + SPROUT_CONSTEXPR bool + operator[](std::size_t position) const { + return unchecked_test(position); + } + SPROUT_CONSTEXPR unsigned long + to_ulong() const { + return this->to_ulong(); + } + SPROUT_CONSTEXPR unsigned long long + to_ullong() const { + return this->to_ullong(); + } + template + std::basic_string + to_string() const { + std::basic_string result; + copy_to_string(result, Char('0'), Char('1')); + return result; + } + template + std::basic_string + to_string(Char zero, Char one = Char('1')) const { + std::basic_string result; + copy_to_string(result, zero, one); + return result; + } + template + std::basic_string > + to_string() const { + return to_string >(); + } + template + std::basic_string > + to_string(Char zero, Char one = Char('1')) const { + return to_string >(zero, one); + } + template + std::basic_string, std::allocator > + to_string() const { + return to_string, std::allocator >(); + } + template + std::basic_string, std::allocator > + to_string(Char zero, Char one = Char('1')) const { + return to_string, std::allocator >(zero, one); + } + std::basic_string, std::allocator > + to_string() const { + return to_string, std::allocator >(); + } + std::basic_string, std::allocator > + to_string(char zero, char one = '1') const { + return to_string, std::allocator >(zero, one); + } + + SPROUT_CONSTEXPR std::size_t + count() const SPROUT_NOEXCEPT { + return this->count(); + } + SPROUT_CONSTEXPR std::size_t + size() const SPROUT_NOEXCEPT { + return N; + } + SPROUT_CONSTEXPR bool + operator==(bitset const& rhs) const SPROUT_NOEXCEPT { + return this->is_equal(rhs); + } + SPROUT_CONSTEXPR bool + operator!=(bitset const& rhs) const SPROUT_NOEXCEPT { + return !this->is_equal(rhs); + } + SPROUT_CONSTEXPR bool + test(std::size_t position) const { + return position >= N ? throw std::out_of_range("bitset::test") + : unchecked_test(position) + ; + } + SPROUT_CONSTEXPR bool + all() const SPROUT_NOEXCEPT { + return this->template are_all(); + } + SPROUT_CONSTEXPR bool + any() const SPROUT_NOEXCEPT { + return this->is_any(); + } + SPROUT_CONSTEXPR bool + none() const SPROUT_NOEXCEPT { + return !this->is_any(); + } + SPROUT_CONSTEXPR bitset + operator<<(std::size_t position) const SPROUT_NOEXCEPT { + return position < N + ? bitset(this->do_left_shift(position)).do_sanitize() + : bitset(this->do_reset()) + ; + } + SPROUT_CONSTEXPR bitset + operator>>(std::size_t position) const SPROUT_NOEXCEPT { + return position < N + ? bitset(this->do_right_shift(position)).do_sanitize() + : bitset(this->do_reset()) + ; + } + + SPROUT_CONSTEXPR std::size_t + find_first() const SPROUT_NOEXCEPT { + return this->find_first(N); + } + SPROUT_CONSTEXPR std::size_t + find_next(std::size_t prev) const SPROUT_NOEXCEPT { + return this->find_next(prev, N); + } + + public: + friend sprout::bitset + sprout::operator& (sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT; + friend sprout::bitset + sprout::operator| (sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT; + friend sprout::bitset + sprout::operator^ (sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT; + template + friend std::basic_istream& + sprout::operator>>(std::basic_istream& lhs, sprout::bitset& rhs); + template + friend std::basic_ostream& + sprout::operator<<(std::basic_ostream& lhs, sprout::bitset const& rhs); + + friend std::size_t + hash_value(sprout::bitset const& v); + }; + + // 20.5.4 bitset operators: + template + inline SPROUT_CONSTEXPR bitset + operator&(sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT { + return bitset(lhs.do_and(rhs)); + } + template + inline SPROUT_CONSTEXPR bitset + operator|(sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT { + return bitset(lhs.do_or(rhs)); + } + template + inline SPROUT_CONSTEXPR bitset + operator^(sprout::bitset const& lhs, sprout::bitset const& rhs) SPROUT_NOEXCEPT { + return bitset(lhs.do_xor(rhs)); + } + template + inline std::basic_istream& + operator>>(std::basic_istream& lhs, sprout::bitset& rhs) { + typedef typename Traits::char_type char_type; + typedef std::basic_istream istream_type; + typedef typename istream_type::ios_base ios_base; + + std::basic_string tmp; + tmp.reserve(N); + char_type const zero = lhs.widen('0'); + char_type const one = lhs.widen('1'); + typename ios_base::iostate state = ios_base::goodbit; + typename istream_type::sentry sentry(lhs); + if (sentry) { + try { + for (std::size_t i = N; i > 0; --i) { + static typename Traits::int_type eof = Traits::eof(); + typename Traits::int_type c1 = lhs.rdbuf()->sbumpc(); + if (Traits::eq_int_type(c1, eof)) { + state |= ios_base::eofbit; + break; + } else { + char_type const c2 = Traits::to_char_type(c1); + if (Traits::eq(c2, zero)) { + tmp.push_back(zero); + } else if (Traits::eq(c2, one)) { + tmp.push_back(one); + } else if (Traits::eq_int_type(lhs.rdbuf()->sputbackc(c2), eof)) { + state |= ios_base::failbit; + break; + } + } + } + } catch(...) { + lhs.setstate(ios_base::badbit); + } + } + if (tmp.empty() && N) { + state |= ios_base::failbit; + } else { + rhs.copy_from_string(tmp, static_cast(0), N, zero, one); + if (state) { + lhs.setstate(state); + return lhs; + } + } + return lhs; + } + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::bitset const& rhs) { + std::basic_string tmp; + std::ctype const& ct = std::use_facet >(lhs.getloc()); + rhs.copy_to_string(tmp, ct.widen('0'), ct.widen('1')); + return lhs << tmp; + } + + // 20.5.3 hash support + template + inline SPROUT_CONSTEXPR std::size_t + hash_value(sprout::bitset const& v); // !!! + inline SPROUT_CONSTEXPR std::size_t + hash_value(sprout::bitset<0> const& v) { + return 0; + } +} // namespace sprout + +#endif // #ifndef SPROUT_BITSET_HPP diff --git a/sprout/functional/bitwise.hpp b/sprout/functional/bitwise.hpp index 97cf269a..8a9e06c6 100644 --- a/sprout/functional/bitwise.hpp +++ b/sprout/functional/bitwise.hpp @@ -5,5 +5,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_FUNCTIONAL_BITWISE_HPP diff --git a/sprout/random/bernoulli_distribution.hpp b/sprout/random/bernoulli_distribution.hpp index 998fc85b..51bd8c3c 100644 --- a/sprout/random/bernoulli_distribution.hpp +++ b/sprout/random/bernoulli_distribution.hpp @@ -73,10 +73,10 @@ namespace sprout { { return lhs << rhs.p_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.p_ == rhs.p_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -146,10 +146,10 @@ namespace sprout { { return lhs << rhs.param(); } - SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { return lhs.param() == rhs.param(); } - SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/binomial_distribution.hpp b/sprout/random/binomial_distribution.hpp index 8753f5cc..066e7e6c 100644 --- a/sprout/random/binomial_distribution.hpp +++ b/sprout/random/binomial_distribution.hpp @@ -131,10 +131,10 @@ namespace sprout { { return lhs << rhs.t_ << " " << rhs.p_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -442,10 +442,10 @@ namespace sprout { { return lhs << rhs.param(); } - SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) { return lhs.param() == rhs.param(); } - SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/geometric_distribution.hpp b/sprout/random/geometric_distribution.hpp index 2c79a0ae..d769bed2 100644 --- a/sprout/random/geometric_distribution.hpp +++ b/sprout/random/geometric_distribution.hpp @@ -77,10 +77,10 @@ namespace sprout { { return lhs << rhs.p_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.p_ == rhs.p_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -162,10 +162,10 @@ namespace sprout { { return lhs << rhs.param(); } - SPROUT_CONSTEXPR friend bool operator==(geometric_distribution const& lhs, geometric_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(geometric_distribution const& lhs, geometric_distribution const& rhs) { return lhs.param() == rhs.param(); } - SPROUT_CONSTEXPR friend bool operator!=(geometric_distribution const& lhs, geometric_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(geometric_distribution const& lhs, geometric_distribution const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/normal_distribution.hpp b/sprout/random/normal_distribution.hpp index 3e403d31..7f3ac36e 100644 --- a/sprout/random/normal_distribution.hpp +++ b/sprout/random/normal_distribution.hpp @@ -91,10 +91,10 @@ namespace sprout { { return lhs << rhs.mean_ << " " << rhs.sigma_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.mean_ == rhs.mean_ && lhs.sigma_ == rhs.sigma_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -239,10 +239,10 @@ namespace sprout { { return lhs << rhs.param() << " " << rhs.valid_ << " " << rhs.cached_rho_ << " " << rhs.r1_ << " " << rhs.r2_; } - SPROUT_CONSTEXPR friend bool operator==(normal_distribution const& lhs, normal_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(normal_distribution const& lhs, normal_distribution const& rhs) { return lhs.param() == rhs.param() && lhs.valid_ == rhs.valid_ && lhs.cached_rho_ == rhs.cached_rho_ && lhs.r1_ == rhs.r1_ && lhs.r2_ == rhs.r2_; } - SPROUT_CONSTEXPR friend bool operator!=(normal_distribution const& lhs, normal_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(normal_distribution const& lhs, normal_distribution const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/uniform_01.hpp b/sprout/random/uniform_01.hpp index 8d7a7108..0da25304 100644 --- a/sprout/random/uniform_01.hpp +++ b/sprout/random/uniform_01.hpp @@ -41,10 +41,10 @@ namespace sprout { { return lhs; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return true; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -116,10 +116,10 @@ namespace sprout { { return lhs; } - SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) { return true; } - SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/uniform_int_distribution.hpp b/sprout/random/uniform_int_distribution.hpp index 74334442..5ca2de27 100644 --- a/sprout/random/uniform_int_distribution.hpp +++ b/sprout/random/uniform_int_distribution.hpp @@ -455,10 +455,10 @@ namespace sprout { { return lhs << rhs.min_ << " " << rhs.max_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -530,10 +530,10 @@ namespace sprout { { return lhs << rhs.param(); } - SPROUT_CONSTEXPR friend bool operator==(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { return lhs.param() == rhs.param(); } - SPROUT_CONSTEXPR friend bool operator!=(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/uniform_real_distribution.hpp b/sprout/random/uniform_real_distribution.hpp index 9c685d12..6bb4b1f7 100644 --- a/sprout/random/uniform_real_distribution.hpp +++ b/sprout/random/uniform_real_distribution.hpp @@ -247,10 +247,10 @@ namespace sprout { { return lhs << rhs.min_ << " " << rhs.max_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -322,10 +322,10 @@ namespace sprout { { return lhs << rhs.param(); } - SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { return lhs.param() == rhs.param(); } - SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { return !(lhs == rhs); } }; diff --git a/sprout/random/uniform_smallint.hpp b/sprout/random/uniform_smallint.hpp index ad631c67..debdf814 100644 --- a/sprout/random/uniform_smallint.hpp +++ b/sprout/random/uniform_smallint.hpp @@ -85,10 +85,10 @@ namespace sprout { { return lhs << rhs.min_ << " " << rhs.max_; } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(param_type const& lhs, param_type const& rhs) { return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(param_type const& lhs, param_type const& rhs) { return !(lhs == rhs); } }; @@ -258,10 +258,10 @@ namespace sprout { { return lhs << rhs.param(); } - SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) { + friend SPROUT_CONSTEXPR bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) { return lhs.param() == rhs.param(); } - SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) { + friend SPROUT_CONSTEXPR bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) { return !(lhs == rhs); } };