diff --git a/sprout/algorithm/fixed/generate.hpp b/sprout/algorithm/fixed/generate.hpp index d31d0651..ada409c3 100644 --- a/sprout/algorithm/fixed/generate.hpp +++ b/sprout/algorithm/fixed/generate.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace sprout { @@ -82,7 +82,7 @@ namespace sprout { Args const&... args ) { - return sizeof...(Args) < offset + return sizeof...(Args) < static_cast(offset) ? generate_impl_3(cont, gen, offset, args..., call_gen(gen, args...)) : generate_impl_4(cont, args...) ; @@ -161,7 +161,7 @@ namespace sprout { Args const&... args ) { - return sizeof...(Args) - InitSize < offset + return sizeof...(Args) - InitSize < static_cast(offset) ? generate_impl_1(cont, gen, offset, size, args..., *sprout::next(sprout::fixed_begin(cont), sizeof...(Args) - InitSize)) : generate_impl_2(cont, gen, offset, size, InitSize, args...) ; diff --git a/sprout/algorithm/string.hpp b/sprout/algorithm/string.hpp new file mode 100644 index 00000000..44386251 --- /dev/null +++ b/sprout/algorithm/string.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_ALGORITHM_STRING_HPP +#define SPROUT_ALGORITHM_STRING_HPP + +#include +#include + +#endif // #ifndef SPROUT_ALGORITHM_STRING_HPP diff --git a/sprout/algorithm/string/join.hpp b/sprout/algorithm/string/join.hpp new file mode 100644 index 00000000..6bf935a2 --- /dev/null +++ b/sprout/algorithm/string/join.hpp @@ -0,0 +1,108 @@ +#ifndef SPROUT_ALGORITHM_STRING_JOIN_HPP +#define SPROUT_ALGORITHM_STRING_JOIN_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace algorithm { + namespace result_of { + // + // join + // + template + struct join { + public: + typedef typename sprout::rebind_fixed_size< + typename sprout::fixed_container_traits::value_type + >::template apply< + sprout::fixed_container_traits::fixed_size != 0 + ? ( + sprout::fixed_container_traits< + typename sprout::fixed_container_traits::value_type + >::fixed_size + + (sprout::fixed_container_traits::fixed_size - 1) * ( + sprout::fixed_container_traits::fixed_size + + sprout::fixed_container_traits< + typename sprout::fixed_container_traits::value_type + >::fixed_size + ) + ) + : 0 + >::type type; + }; + } // namespace result_of + + namespace detail { + template + SPROUT_CONSTEXPR inline typename std::enable_if< + (sprout::fixed_container_traits::fixed_size == sprout::fixed_container_traits::fixed_size), + Result + >::type join_impl_1( + ContainerIterator first, + ContainerIterator last, + Separator const& separator, + Container const& current + ) + { + return current; + } + template + SPROUT_CONSTEXPR inline typename std::enable_if< + (sprout::fixed_container_traits::fixed_size < sprout::fixed_container_traits::fixed_size), + Result + >::type join_impl_1( + ContainerIterator first, + ContainerIterator last, + Separator const& separator, + Container const& current + ) + { + return sprout::algorithm::detail::join_impl_1( + sprout::next(first), + last, + separator, + sprout::fixed::append_back(sprout::fixed::append_back(current, separator), *first) + ); + } + template + SPROUT_CONSTEXPR inline Result join_impl( + ContainerIterator first, + ContainerIterator last, + Separator const& separator + ) + { + return first != last + ? sprout::algorithm::detail::join_impl_1( + sprout::next(first), + last, + separator, + *first + ) + : sprout::make_clone() + ; + } + } // namespace detail + // + // join + // + template + SPROUT_CONSTEXPR inline typename sprout::algorithm::result_of::join::type join( + ContainerContainer const& cont_cont, + Separator const& separator + ) + { + return sprout::algorithm::detail::join_impl::type>( + sprout::begin(cont_cont), + sprout::end(cont_cont), + separator + ); + } + } // namespace algorithm +} // namespace sprout + +#endif // #ifndef SPROUT_ALGORITHM_STRING_JOIN_HPP diff --git a/sprout/array.hpp b/sprout/array.hpp index 6b85d320..ebaf7249 100644 --- a/sprout/array.hpp +++ b/sprout/array.hpp @@ -181,6 +181,7 @@ namespace sprout { }; // + // operator== // operator!= // operator< // operator> @@ -267,7 +268,7 @@ namespace sprout { template struct is_array_impl { public: - typedef std::integral_constant type; + typedef std::false_type type; SPROUT_STATIC_CONSTEXPR bool value = type::value; }; template @@ -281,7 +282,7 @@ namespace sprout { >::type > { public: - typedef std::integral_constant type; + typedef std::true_type type; SPROUT_STATIC_CONSTEXPR bool value = type::value; }; } // namespace detail diff --git a/sprout/null_array.hpp b/sprout/null_array.hpp index bfcbaf1c..99dc88b0 100644 --- a/sprout/null_array.hpp +++ b/sprout/null_array.hpp @@ -126,6 +126,7 @@ namespace sprout { }; // + // operator== // operator!= // operator< // operator> diff --git a/sprout/random.hpp b/sprout/random.hpp index 60ec27c7..8e18490f 100644 --- a/sprout/random.hpp +++ b/sprout/random.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/random/bernoulli_distribution.hpp b/sprout/random/bernoulli_distribution.hpp new file mode 100644 index 00000000..c94a7d09 --- /dev/null +++ b/sprout/random/bernoulli_distribution.hpp @@ -0,0 +1,142 @@ +#ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP +#define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP + +#include +#include +#include + +namespace sprout { + namespace random { + // + // bernoulli_distribution + // + template + class bernoulli_distribution { + public: + typedef int input_type; + typedef bool result_type; + private: + static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) { + return p_arg >= 0 && p_arg <= 1 + ? p_arg + : throw "assert(p_arg >= 0 && p_arg <= 1)" + ; + } + public: + // + // param_type + // + class param_type { + public: + typedef bernoulli_distribution distribution_type; + private: + RealType p_; + public: + SPROUT_CONSTEXPR param_type() + : p_(RealType(0.5)) + {} + SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5)) + : p_(arg_check(p_arg)) + {} + SPROUT_CONSTEXPR RealType p() const { + return p_; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + param_type const& rhs + ) + { + return lhs >> rhs.p_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + param_type const& rhs + ) + { + return lhs << rhs.p_; + } + SPROUT_CONSTEXPR friend 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) { + return !(lhs == rhs); + } + }; + private: + RealType p_; + private: + template + SPROUT_CONSTEXPR sprout::random::random_result generate( + sprout::random::random_result const& rnd + ) const + { + return sprout::random::random_result( + RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()), + rnd.engine(), + *this + ); + } + public: + SPROUT_CONSTEXPR bernoulli_distribution() + : p_(RealType(0.5)) + {} + SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5)) + : p_(arg_check(p_arg)) + {} + SPROUT_CONSTEXPR RealType p() const { + return p_; + } + SPROUT_CONSTEXPR result_type min() const { + return false; + } + SPROUT_CONSTEXPR result_type max() const { + return true; + } + SPROUT_CONSTEXPR param_type param() const { + return param_type(p_); + } + void param(param_type const& parm) { + p_ = parm.p(); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + return p_ == RealType(0) + ? sprout::random::random_result(false, eng, *this) + : generate(eng()) + ; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + bernoulli_distribution const& rhs + ) + { + param_type parm; + return lhs >> parm; + param(parm); + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + bernoulli_distribution const& rhs + ) + { + return lhs << param(); + } + SPROUT_CONSTEXPR friend 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) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::bernoulli_distribution; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP + diff --git a/sprout/random/uniform_01.hpp b/sprout/random/uniform_01.hpp index 3adc08a6..64742980 100644 --- a/sprout/random/uniform_01.hpp +++ b/sprout/random/uniform_01.hpp @@ -2,6 +2,7 @@ #define SPROUT_RANDOM_UNIFORM_01_HPP #include +#include #include #include #include diff --git a/sprout/string.hpp b/sprout/string.hpp index 164abd70..1fd4a70e 100644 --- a/sprout/string.hpp +++ b/sprout/string.hpp @@ -89,39 +89,55 @@ namespace sprout { return impl_type::eof(); } #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION - template - static SPROUT_CONSTEXPR int compare(CharIterator s1, CharIterator s2, std::size_t n) { + template + static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstIterator s2, std::size_t n) { return !n ? 0 : lt(*s1, *s2) ? -1 : lt(*s2, *s1) ? 1 : compare(s1 + 1, s2 + 1, n - 1) ; } - template - static SPROUT_CONSTEXPR std::size_t length(CharIterator s) { + template + static SPROUT_CONSTEXPR int compare(ConstIterator s1, char_type const* s2, std::size_t n) { + return !n ? 0 + : lt(*s1, *s2) ? -1 + : lt(*s2, *s1) ? 1 + : compare(s1 + 1, s2 + 1, n - 1) + ; + } + template + static SPROUT_CONSTEXPR int compare(ConstIterator1 s1, ConstIterator2 s2, std::size_t n) { + return !n ? 0 + : lt(*s1, *s2) ? -1 + : lt(*s2, *s1) ? 1 + : compare(s1 + 1, s2 + 1, n - 1) + ; + } + template + static SPROUT_CONSTEXPR std::size_t length(ConstIterator s) { return !*s ? 0 : 1 + length(s + 1) ; } - template - static SPROUT_CONSTEXPR CharIterator find(CharIterator s, std::size_t n, char_type const& a) { + template + static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) { return !n ? nullptr : eq(*s, a) ? s : find(s + 1, n - 1, a) ; } - template - static CharIterator1 move(CharIterator1 s1, CharIterator2 s2, std::size_t n) { + template + static Iterator move(Iterator s1, ConstIterator s2, std::size_t n) { std::copy_backward(s2, s2 + n, s1); return s1; } - template - static CharIterator1 copy(CharIterator1 s1, CharIterator2 s2, std::size_t n) { + template + static Iterator copy(Iterator s1, ConstIterator s2, std::size_t n) { std::copy(s2, s2 + n, s1); return s1; } - template - static CharIterator assign(CharIterator s, std::size_t n, char_type a) { + template + static Iterator assign(Iterator s, std::size_t n, char_type a) { std::fill(s, s + n, a); return s; } @@ -151,6 +167,37 @@ namespace sprout { typedef sprout::reverse_iterator reverse_iterator; typedef sprout::reverse_iterator const_reverse_iterator; typedef Traits traits_type; +#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION + private: + template + struct is_index_iterator_impl { + public: + typedef std::false_type type; + SPROUT_STATIC_CONSTEXPR bool value = type::value; + }; + template + struct is_index_iterator_impl< + U, + typename std::enable_if< + std::is_same< + U, + sprout::index_iterator + >::value + && std::is_same< + typename std::iterator_traits::value_type, + value_type + >::value + >::type + > { + public: + typedef std::true_type type; + SPROUT_STATIC_CONSTEXPR bool value = type::value; + }; + template + struct is_index_iterator + : public is_index_iterator_impl + {}; +#endif public: SPROUT_STATIC_CONSTEXPR size_type npos = -1; SPROUT_STATIC_CONSTEXPR size_type static_size = N; @@ -180,7 +227,29 @@ namespace sprout { return sprout::basic_string{{(Indexes < n ? s[Indexes] : T())...}, n}; } #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION - static SPROUT_CONSTEXPR int compare_impl_1(const_iterator dest, size_type pos1, size_type n1, const_iterator s, size_type n2) { + template + static SPROUT_CONSTEXPR typename std::enable_if< + is_index_iterator::value, + int + >::type compare_impl_1(value_type const* dest, size_type pos1, size_type n1, ConstIterator s, size_type n2) { + return compare_impl_2( + traits_type::compare(dest + pos1, s, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, n2)), + n1, + n2 + ); + } + static SPROUT_CONSTEXPR int compare_impl_1(const_iterator dest, size_type pos1, size_type n1, value_type const* s, size_type n2) { + return compare_impl_2( + traits_type::compare(dest + pos1, s, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, n2)), + n1, + n2 + ); + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + is_index_iterator::value, + int + >::type compare_impl_1(const_iterator dest, size_type pos1, size_type n1, ConstIterator s, size_type n2) { return compare_impl_2( traits_type::compare(dest + pos1, s, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, n2)), n1, @@ -401,7 +470,7 @@ namespace sprout { } template SPROUT_CONSTEXPR int compare(basic_string const& str) const { - return compare(0, size(), str.c_str(), str.size()); + return compare(0, size(), str.begin(), str.size()); } SPROUT_CONSTEXPR int compare(value_type const* s) const { return compare(0, size(), s, traits_type::length(s)); @@ -416,13 +485,13 @@ namespace sprout { template SPROUT_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string const& str, size_type pos2, size_type n2) const { return !(str.size() < pos2) - ? compare(pos1, n1, str.c_str() + pos2, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n2, str.size() - pos2)) + ? compare(pos1, n1, str.begin() + pos2, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n2, str.size() - pos2)) : throw "basic_string<>: index out of range" ; } SPROUT_CONSTEXPR int compare(size_type pos1, size_type n1, value_type const* s, size_type n2) const { return !(size() < pos1) - ? compare_impl_1(c_str(), pos1, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, size() - pos1), s, n2) + ? compare_impl_1(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, size() - pos1), s, n2) : throw "basic_string<>: index out of range" ; } @@ -441,7 +510,11 @@ namespace sprout { } } #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION - basic_string& assign(const_iterator s, size_type n) { + template + typename std::enable_if< + is_index_iterator::value, + basic_string& + >::type assign(ConstIterator s, size_type n) { maxcheck(n); for (size_type i = 0; i < n; ++i) { traits_type::assign(elems[i], s[i]); @@ -452,21 +525,41 @@ namespace sprout { len = n; return *this; } - basic_string& assign(const_iterator s) { + template + typename std::enable_if< + is_index_iterator::value, + basic_string& + >::type assign(ConstIterator s) { return assign(s, traits_type::length(s)); } - basic_string& operator=(const_iterator rhs) { + template + typename std::enable_if< + is_index_iterator::value, + basic_string& + >::type operator=(ConstIterator rhs) { return assign(rhs); } - SPROUT_CONSTEXPR int compare(const_iterator s) const { + template + SPROUT_CONSTEXPR typename std::enable_if< + is_index_iterator::value, + int + >::type compare(ConstIterator s) const { return compare(0, size(), s, traits_type::length(s)); } - SPROUT_CONSTEXPR int compare(size_type pos1, size_type n1, const_iterator s) const { + template + SPROUT_CONSTEXPR typename std::enable_if< + is_index_iterator::value, + int + >::type compare(size_type pos1, size_type n1, ConstIterator s) const { return compare(pos1, n1, s, traits_type::length(s)); } - SPROUT_CONSTEXPR int compare(size_type pos1, size_type n1, const_iterator s, size_type n2) const { + template + SPROUT_CONSTEXPR typename std::enable_if< + is_index_iterator::value, + int + >::type compare(size_type pos1, size_type n1, ConstIterator s, size_type n2) const { return !(size() < pos1) - ? compare_impl_1(c_str(), pos1, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, size() - pos1), s, n2) + ? compare_impl_1(begin(), pos1, NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(n1, size() - pos1), s, n2) : throw "basic_string<>: index out of range" ; } @@ -474,6 +567,7 @@ namespace sprout { }; // + // operator== // operator!= // operator< // operator> diff --git a/sprout/sub_array.hpp b/sprout/sub_array.hpp index da8600e5..8d7992d0 100644 --- a/sprout/sub_array.hpp +++ b/sprout/sub_array.hpp @@ -381,6 +381,7 @@ namespace sprout { }; // + // operator== // operator!= // operator< // operator>