diff --git a/sprout/algorithm/fixed/merge.hpp b/sprout/algorithm/fixed/merge.hpp index 771d84d3..5e4c644e 100644 --- a/sprout/algorithm/fixed/merge.hpp +++ b/sprout/algorithm/fixed/merge.hpp @@ -6,10 +6,11 @@ #include #include #include +#include +#include #include #include #include -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { @@ -67,6 +68,43 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + merge( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::fixed::detail::merge_impl( + first1, last1, + first2, last2, + result, comp, + sprout::size(result) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + merge( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::remake( + result, sprout::size(result), + sprout::make_merge_iterator(first1, last1, first2, last2, comp), + sprout::make_merge_iterator(last1, last1, last2, last2, comp) + ); + } } // namespace detail // // merge @@ -79,12 +117,7 @@ namespace sprout { Result const& result, Compare comp ) { - return sprout::fixed::detail::merge_impl( - first1, last1, - first2, last2, - result, comp, - sprout::size(result) - ); + return sprout::fixed::detail::merge(first1, last1, first2, last2, result, comp); } template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type @@ -94,12 +127,7 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::merge_impl( - first1, last1, - first2, last2, - result, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), - sprout::size(result) - ); + return sprout::fixed::merge(first1, last1, first2, last2, result, sprout::less<>()); } template diff --git a/sprout/algorithm/fixed/set_difference.hpp b/sprout/algorithm/fixed/set_difference.hpp index df2713fd..b25365ec 100644 --- a/sprout/algorithm/fixed/set_difference.hpp +++ b/sprout/algorithm/fixed/set_difference.hpp @@ -6,10 +6,10 @@ #include #include #include +#include #include #include #include -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { @@ -72,6 +72,25 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + set_difference( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::fixed::detail::set_difference_impl( + first1, last1, + first2, last2, + result, comp, + sprout::size(result) + ); + } } // namespace detail // // set_difference @@ -84,12 +103,7 @@ namespace sprout { Result const& result, Compare comp ) { - return sprout::fixed::detail::set_difference_impl( - first1, last1, - first2, last2, - result, comp, - sprout::size(result) - ); + return sprout::fixed::detail::set_difference(first1, last1, first2, last2, result, comp); } template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type @@ -99,12 +113,7 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::set_difference_impl( - first1, last1, - first2, last2, - result, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), - sprout::size(result) - ); + return sprout::fixed::set_difference(first1, last1, first2, last2, result, sprout::less<>()); } template diff --git a/sprout/algorithm/fixed/set_intersection.hpp b/sprout/algorithm/fixed/set_intersection.hpp index b81e4a3b..8567d35e 100644 --- a/sprout/algorithm/fixed/set_intersection.hpp +++ b/sprout/algorithm/fixed/set_intersection.hpp @@ -6,10 +6,10 @@ #include #include #include +#include #include #include #include -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { @@ -72,6 +72,25 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + set_intersection( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::fixed::detail::set_intersection_impl( + first1, last1, + first2, last2, + result, comp, + sprout::size(result) + ); + } } // namespace detail // // set_intersection @@ -84,12 +103,7 @@ namespace sprout { Result const& result, Compare comp ) { - return sprout::fixed::detail::set_intersection_impl( - first1, last1, - first2, last2, - result, comp, - sprout::size(result) - ); + return sprout::fixed::detail::set_intersection(first1, last1, first2, last2, result, comp); } template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type @@ -99,12 +113,7 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::set_intersection_impl( - first1, last1, - first2, last2, - result, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), - sprout::size(result) - ); + return sprout::fixed::set_intersection(first1, last1, first2, last2, result, sprout::less<>()); } template diff --git a/sprout/algorithm/fixed/set_symmetric_difference.hpp b/sprout/algorithm/fixed/set_symmetric_difference.hpp index 46105b61..a95dcbcd 100644 --- a/sprout/algorithm/fixed/set_symmetric_difference.hpp +++ b/sprout/algorithm/fixed/set_symmetric_difference.hpp @@ -6,10 +6,10 @@ #include #include #include +#include #include #include #include -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { @@ -72,6 +72,25 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + set_symmetric_difference( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::fixed::detail::set_symmetric_difference_impl( + first1, last1, + first2, last2, + result, comp, + sprout::size(result) + ); + } } // namespace detail // // set_symmetric_difference @@ -84,12 +103,7 @@ namespace sprout { Result const& result, Compare comp ) { - return sprout::fixed::detail::set_symmetric_difference_impl( - first1, last1, - first2, last2, - result, comp, - sprout::size(result) - ); + return sprout::fixed::detail::set_symmetric_difference(first1, last1, first2, last2, result, comp); } template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type @@ -99,12 +113,7 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::set_symmetric_difference_impl( - first1, last1, - first2, last2, - result, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), - sprout::size(result) - ); + return sprout::fixed::set_symmetric_difference(first1, last1, first2, last2, result, sprout::less<>()); } template diff --git a/sprout/algorithm/fixed/set_union.hpp b/sprout/algorithm/fixed/set_union.hpp index 9a33646d..23cbd695 100644 --- a/sprout/algorithm/fixed/set_union.hpp +++ b/sprout/algorithm/fixed/set_union.hpp @@ -6,10 +6,11 @@ #include #include #include +#include +#include #include #include #include -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fixed { @@ -72,6 +73,43 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + set_union( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::fixed::detail::set_union_impl( + first1, last1, + first2, last2, + result, comp, + sprout::size(result) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + set_union( + InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Result const& result, Compare comp + ) + { + return sprout::remake( + result, sprout::size(result), + sprout::make_set_union_iterator(first1, last1, first2, last2, comp), + sprout::make_set_union_iterator(last1, last1, last2, last2, comp) + ); + } } // namespace detail // // set_union @@ -84,12 +122,7 @@ namespace sprout { Result const& result, Compare comp ) { - return sprout::fixed::detail::set_union_impl( - first1, last1, - first2, last2, - result, comp, - sprout::size(result) - ); + return sprout::fixed::detail::set_union(first1, last1, first2, last2, result, comp); } template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type @@ -99,12 +132,7 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::set_union_impl( - first1, last1, - first2, last2, - result, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), - sprout::size(result) - ); + return sprout::fixed::set_union(first1, last1, first2, last2, result, sprout::less<>()); } template diff --git a/sprout/algorithm/fixed/unique_copy.hpp b/sprout/algorithm/fixed/unique_copy.hpp index b38ccf87..a61e1f5c 100644 --- a/sprout/algorithm/fixed/unique_copy.hpp +++ b/sprout/algorithm/fixed/unique_copy.hpp @@ -61,6 +61,12 @@ namespace sprout { ; } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unique_copy(InputIterator first, InputIterator last) { + return sprout::fixed::unique_copy(first, last, sprout::pit()); + } + namespace detail { template inline SPROUT_CONSTEXPR typename std::enable_if< diff --git a/sprout/array/tuple.hpp b/sprout/array/tuple.hpp index 652f48f9..c732d309 100644 --- a/sprout/array/tuple.hpp +++ b/sprout/array/tuple.hpp @@ -50,8 +50,8 @@ namespace std { // template struct tuple_element > { - public: static_assert(I < N, "tuple_element<>: index out of range"); + public: typedef T type; }; #if defined(__clang__) diff --git a/sprout/index_tuple.hpp b/sprout/index_tuple.hpp index f7e8b228..19bc2b92 100644 --- a/sprout/index_tuple.hpp +++ b/sprout/index_tuple.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include diff --git a/sprout/index_tuple/detail/make_indexes_helper.hpp b/sprout/index_tuple/detail/make_indexes_helper.hpp index 30604190..37c48f9d 100644 --- a/sprout/index_tuple/detail/make_indexes_helper.hpp +++ b/sprout/index_tuple/detail/make_indexes_helper.hpp @@ -6,7 +6,9 @@ namespace sprout { namespace detail { template - struct make_indexes_helper { + struct make_indexes_helper + : public IndexTupleType::type + { public: typedef typename IndexTupleType::type type; public: diff --git a/sprout/index_tuple/index_n.hpp b/sprout/index_tuple/index_n.hpp index 32424971..cf284bf8 100644 --- a/sprout/index_tuple/index_n.hpp +++ b/sprout/index_tuple/index_n.hpp @@ -32,8 +32,7 @@ namespace sprout { struct index_n_impl; template struct index_n_impl< - I, - N, + I, N, typename std::enable_if<(N == 0)>::type > { public: @@ -41,8 +40,7 @@ namespace sprout { }; template struct index_n_impl< - I, - N, + I, N, typename std::enable_if<(N == 1)>::type > { public: @@ -50,8 +48,7 @@ namespace sprout { }; template struct index_n_impl< - I, - N, + I, N, typename std::enable_if<(N > 1 && N % 2 == 0)>::type > : public sprout::detail::index_n_next< @@ -60,8 +57,7 @@ namespace sprout { {}; template struct index_n_impl< - I, - N, + I, N, typename std::enable_if<(N > 1 && N % 2 == 1)>::type > : public sprout::detail::index_n_next2< diff --git a/sprout/index_tuple/index_range.hpp b/sprout/index_tuple/index_range.hpp index d7cc57b4..4fb1c63b 100644 --- a/sprout/index_tuple/index_range.hpp +++ b/sprout/index_tuple/index_range.hpp @@ -32,9 +32,7 @@ namespace sprout { struct index_range_impl; template struct index_range_impl< - First, - Step, - N, + First, Step, N, typename std::enable_if<(N == 0)>::type > { public: @@ -42,9 +40,7 @@ namespace sprout { }; template struct index_range_impl< - First, - Step, - N, + First, Step, N, typename std::enable_if<(N == 1)>::type > { public: @@ -52,9 +48,7 @@ namespace sprout { }; template struct index_range_impl< - First, - Step, - N, + First, Step, N, typename std::enable_if<(N > 1 && N % 2 == 0)>::type > : public sprout::detail::index_range_next< @@ -64,9 +58,7 @@ namespace sprout { {}; template struct index_range_impl< - First, - Step, - N, + First, Step, N, typename std::enable_if<(N > 1 && N % 2 == 1)>::type > : public sprout::detail::index_range_next2< @@ -80,9 +72,7 @@ namespace sprout { struct index_range : public sprout::detail::make_indexes_helper< sprout::detail::index_range_impl< - First, - Step, - ((Last - First) + (Step - 1)) / Step + First, Step, ((Last - First) + (Step - 1)) / Step > > {}; diff --git a/sprout/index_tuple/index_tuple.hpp b/sprout/index_tuple/index_tuple.hpp index 0afcc9b3..69138ef3 100644 --- a/sprout/index_tuple/index_tuple.hpp +++ b/sprout/index_tuple/index_tuple.hpp @@ -17,7 +17,12 @@ namespace sprout { struct index_tuple { public: typedef index_tuple type; + typedef sprout::index_t value_type; + public: + SPROUT_STATIC_CONSTEXPR std::size_t size = sizeof...(Indexes); }; + template + SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::index_tuple::size; } // namespace sprout #endif // #ifndef SPROUT_INDEX_TUPLE_INDEX_TUPLE_HPP diff --git a/sprout/index_tuple/pack_indexes.hpp b/sprout/index_tuple/pack_indexes.hpp index 57f92947..a6e6bfa1 100644 --- a/sprout/index_tuple/pack_indexes.hpp +++ b/sprout/index_tuple/pack_indexes.hpp @@ -2,6 +2,7 @@ #define SPROUT_INDEX_TUPLE_PACK_INDEXES_HPP #include +#include #include namespace sprout { diff --git a/sprout/index_tuple/tuple.hpp b/sprout/index_tuple/tuple.hpp new file mode 100644 index 00000000..99c3456d --- /dev/null +++ b/sprout/index_tuple/tuple.hpp @@ -0,0 +1,37 @@ +#ifndef SPROUT_INDEX_TUPLE_TUPLE_HPP +#define SPROUT_INDEX_TUPLE_TUPLE_HPP + +#include +#include +#include +#include +#include + +namespace std { +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + // + // tuple_size + // + template + struct tuple_size > + : public std::integral_constant + {}; + + // + // tuple_element + // + template + struct tuple_element > { + static_assert(I < sizeof...(Indexes), "tuple_element<>: index out of range"); + public: + typedef sprout::index_t type; + }; +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +} // namespace std + +#endif // #ifndef SPROUT_INDEX_TUPLE_TUPLE_HPP diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index b4f40618..307feb18 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/iterator/alternate_iterator.hpp b/sprout/iterator/alternate_iterator.hpp index 6607d12b..279d4f59 100644 --- a/sprout/iterator/alternate_iterator.hpp +++ b/sprout/iterator/alternate_iterator.hpp @@ -11,7 +11,6 @@ #include #include #include -#include namespace sprout { // diff --git a/sprout/iterator/merge_iterator.hpp b/sprout/iterator/merge_iterator.hpp new file mode 100644 index 00000000..8aaf2cc4 --- /dev/null +++ b/sprout/iterator/merge_iterator.hpp @@ -0,0 +1,241 @@ +#ifndef SPROUT_ITERATOR_MERGE_ITERATOR_HPP +#define SPROUT_ITERATOR_MERGE_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // merge_iterator + // + template< + typename LIterator, typename RIterator, + typename Compare = sprout::less<> + > + class merge_iterator + : public std::iterator< + typename sprout::min_iterator_category< + typename sprout::common_iterator_category::type, + std::forward_iterator_tag + >::type, + typename sprout::common_iterator_value_type::type, + typename sprout::common_iterator_difference_type::type, + typename sprout::common_iterator_pointer::type, + typename sprout::common_iterator_reference::type + > + { + public: + typedef LIterator iterator_type; + typedef RIterator iterator2_type; + typedef Compare compare_type; + typedef typename sprout::min_iterator_category< + typename sprout::common_iterator_category::type, + std::forward_iterator_tag + >::type iterator_category; + typedef typename sprout::common_iterator_value_type::type value_type; + typedef typename sprout::common_iterator_difference_type::type difference_type; + typedef typename sprout::common_iterator_pointer::type pointer; + typedef typename sprout::common_iterator_reference::type reference; + private: + static SPROUT_CONSTEXPR bool check_in_left( + iterator_type it1, iterator_type lst1, + iterator2_type it2, iterator2_type lst2, + Compare comp + ) + { + return it1 != lst1 ? (it2 != lst2 ? !comp(*it2, *it1) : true) + : !(it2 != lst2) + ; + } + protected: + iterator_type current1; + iterator_type lst1; + iterator2_type current2; + iterator2_type lst2; + Compare comp; + bool in_left; + public: + merge_iterator() + : current1(), lst1(), current2(), lst2(), comp(), in_left(true) + {} + merge_iterator(merge_iterator const&) = default; + SPROUT_CONSTEXPR merge_iterator( + iterator_type it1, iterator_type lst1, + iterator2_type it2, iterator2_type lst2, + Compare comp = Compare() + ) + : current1(it1), lst1(lst1) + , current2(it2), lst2(lst2) + , comp(comp) + , in_left(check_in_left(it1, lst1, it2, lst2, comp)) + {} + template + SPROUT_CONSTEXPR merge_iterator(merge_iterator const& it) + : current1(it.base()), lst1(it.last1()) + , current2(it.base2()), lst2(it.last2()) + , comp(it.compare()) + , in_left(it.is_in_left()) + {} + template + merge_iterator& operator=(merge_iterator const& it) { + merge_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current1; + } + SPROUT_CONSTEXPR iterator_type last1() const { + return lst1; + } + SPROUT_CONSTEXPR iterator2_type base2() const { + return current2; + } + SPROUT_CONSTEXPR iterator2_type last2() const { + return lst2; + } + SPROUT_CONSTEXPR Compare compare() const { + return comp; + } + SPROUT_CONSTEXPR bool is_in_left() const { + return in_left; + } + SPROUT_CONSTEXPR reference operator*() const { + return is_in_left() ? *current1 : *current2; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*(*this); + } + merge_iterator& operator++() { + if (current1 != lst1) { + if (current2 != lst2) { + if (comp(*current2, *current1)) { + ++current2; + } else { + ++current1; + } + } else { + ++current1; + } + } else if (current2 != lst2) { + ++current2; + } + in_left = check_in_left(current1, lst1, current2, lst2, comp); + return *this; + } + merge_iterator operator++(int) { + merge_iterator result(*this); + if (current1 != lst1) { + if (current2 != lst2) { + if (comp(*current2, *current1)) { + ++current2; + } else { + ++current1; + } + } else { + ++current1; + } + } else if (current2 != lst2) { + ++current2; + } + in_left = check_in_left(current1, lst1, current2, lst2, comp); + return result; + } + SPROUT_CONSTEXPR merge_iterator next() const { + return current1 != lst1 + ? current2 != lst2 + ? comp(*current2, *current1) + ? merge_iterator(current1, lst1, sprout::next(current2), lst2, comp) + : merge_iterator(sprout::next(current1), lst1, current2, lst2, comp) + : merge_iterator(sprout::next(current1), lst1, current2, lst2, comp) + : current2 != lst2 + ? merge_iterator(current1, lst1, sprout::next(current2), lst2, comp) + : *this + ; + } + void swap(merge_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(sprout::swap(current1, other.current1)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(lst1, other.lst1)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(current2, other.current2)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(lst2, other.lst2)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(comp, other.comp)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(in_left, other.in_left)) + ) + { + sprout::swap(current1, other.current1); + sprout::swap(lst1, other.lst1); + sprout::swap(current2, other.current2); + sprout::swap(lst2, other.lst2); + sprout::swap(comp, other.comp); + sprout::swap(in_left, other.in_left); + } + }; + + template< + typename LIterator1, typename RIterator1, typename Compare1, + typename LIterator2, typename RIterator2, typename Compare2 + > + inline SPROUT_CONSTEXPR bool operator==( + sprout::merge_iterator const& lhs, + sprout::merge_iterator const& rhs + ) + { + return lhs.base() == rhs.base() && lhs.base2() == rhs.base2(); + } + template< + typename LIterator1, typename RIterator1, typename Compare1, + typename LIterator2, typename RIterator2, typename Compare2 + > + inline SPROUT_CONSTEXPR bool operator!=( + sprout::merge_iterator const& lhs, + sprout::merge_iterator const& rhs + ) + { + return !(lhs == rhs); + } + + // + // make_merge_iterator + // + template + inline SPROUT_CONSTEXPR sprout::merge_iterator + make_merge_iterator(LIterator it1, LIterator lst1, RIterator it2, RIterator lst2, Compare comp) { + return sprout::merge_iterator(it1, lst1, it2, lst2, comp); + } + template + inline SPROUT_CONSTEXPR sprout::merge_iterator + make_merge_iterator(LIterator it1, LIterator lst1, RIterator it2, RIterator lst2) { + return sprout::merge_iterator(it1, lst1, it2, lst2); + } + + // + // swap + // + template + inline void + swap( + sprout::merge_iterator& lhs, + sprout::merge_iterator& rhs + ) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::merge_iterator + iterator_next(sprout::merge_iterator const& it) { + return it.next(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_MERGE_ITERATOR_HPP diff --git a/sprout/iterator/set_union_iterator.hpp b/sprout/iterator/set_union_iterator.hpp new file mode 100644 index 00000000..a8bc3967 --- /dev/null +++ b/sprout/iterator/set_union_iterator.hpp @@ -0,0 +1,249 @@ +#ifndef SPROUT_ITERATOR_SET_UNION_ITERATOR_HPP +#define SPROUT_ITERATOR_SET_UNION_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // set_union_iterator + // + template< + typename LIterator, typename RIterator, + typename Compare = sprout::less<> + > + class set_union_iterator + : public std::iterator< + typename sprout::min_iterator_category< + typename sprout::common_iterator_category::type, + std::forward_iterator_tag + >::type, + typename sprout::common_iterator_value_type::type, + typename sprout::common_iterator_difference_type::type, + typename sprout::common_iterator_pointer::type, + typename sprout::common_iterator_reference::type + > + { + public: + typedef LIterator iterator_type; + typedef RIterator iterator2_type; + typedef Compare compare_type; + typedef typename sprout::min_iterator_category< + typename sprout::common_iterator_category::type, + std::forward_iterator_tag + >::type iterator_category; + typedef typename sprout::common_iterator_value_type::type value_type; + typedef typename sprout::common_iterator_difference_type::type difference_type; + typedef typename sprout::common_iterator_pointer::type pointer; + typedef typename sprout::common_iterator_reference::type reference; + private: + static SPROUT_CONSTEXPR bool check_in_left( + iterator_type it1, iterator_type lst1, + iterator2_type it2, iterator2_type lst2, + Compare comp + ) + { + return it1 != lst1 ? (it2 != lst2 ? comp(*it1, *it2) || !comp(*it2, *it1) : true) + : !(it2 != lst2) + ; + } + protected: + iterator_type current1; + iterator_type lst1; + iterator2_type current2; + iterator2_type lst2; + Compare comp; + bool in_left; + public: + set_union_iterator() + : current1(), lst1(), current2(), lst2(), comp(), in_left(true) + {} + set_union_iterator(set_union_iterator const&) = default; + SPROUT_CONSTEXPR set_union_iterator( + iterator_type it1, iterator_type lst1, + iterator2_type it2, iterator2_type lst2, + Compare comp = Compare() + ) + : current1(it1), lst1(lst1) + , current2(it2), lst2(lst2) + , comp(comp) + , in_left(check_in_left(it1, lst1, it2, lst2, comp)) + {} + template + SPROUT_CONSTEXPR set_union_iterator(set_union_iterator const& it) + : current1(it.base()), lst1(it.last1()) + , current2(it.base2()), lst2(it.last2()) + , comp(it.compare()) + , in_left(it.is_in_left()) + {} + template + set_union_iterator& operator=(set_union_iterator const& it) { + set_union_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current1; + } + SPROUT_CONSTEXPR iterator_type last1() const { + return lst1; + } + SPROUT_CONSTEXPR iterator2_type base2() const { + return current2; + } + SPROUT_CONSTEXPR iterator2_type last2() const { + return lst2; + } + SPROUT_CONSTEXPR Compare compare() const { + return comp; + } + SPROUT_CONSTEXPR bool is_in_left() const { + return in_left; + } + SPROUT_CONSTEXPR reference operator*() const { + return is_in_left() ? *current1 : *current2; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*(*this); + } + set_union_iterator& operator++() { + if (current1 != lst1) { + if (current2 != lst2) { + if (comp(*current1, *current2)) { + ++current1; + } else if (comp(*current2, *current1)) { + ++current2; + } else { + ++current1; + ++current2; + } + } else { + ++current1; + } + } else if (current2 != lst2) { + ++current2; + } + in_left = check_in_left(current1, lst1, current2, lst2, comp); + return *this; + } + set_union_iterator operator++(int) { + set_union_iterator result(*this); + if (current1 != lst1) { + if (current2 != lst2) { + if (comp(*current1, *current2)) { + ++current1; + } else if (comp(*current2, *current1)) { + ++current2; + } else { + ++current1; + ++current2; + } + } else { + ++current1; + } + } else if (current2 != lst2) { + ++current2; + } + in_left = check_in_left(current1, lst1, current2, lst2, comp); + return result; + } + SPROUT_CONSTEXPR set_union_iterator next() const { + return current1 != lst1 + ? current2 != lst2 + ? comp(*current1, *current2) + ? set_union_iterator(sprout::next(current1), lst1, current2, lst2, comp) + : comp(*current2, *current1) + ? set_union_iterator(current1, lst1, sprout::next(current2), lst2, comp) + : set_union_iterator(sprout::next(current1), lst1, sprout::next(current2), lst2, comp) + : set_union_iterator(sprout::next(current1), lst1, current2, lst2, comp) + : current2 != lst2 + ? set_union_iterator(current1, lst1, sprout::next(current2), lst2, comp) + : *this + ; + } + void swap(set_union_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(sprout::swap(current1, other.current1)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(lst1, other.lst1)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(current2, other.current2)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(lst2, other.lst2)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(comp, other.comp)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(in_left, other.in_left)) + ) + { + sprout::swap(current1, other.current1); + sprout::swap(lst1, other.lst1); + sprout::swap(current2, other.current2); + sprout::swap(lst2, other.lst2); + sprout::swap(comp, other.comp); + sprout::swap(in_left, other.in_left); + } + }; + + template< + typename LIterator1, typename RIterator1, typename Compare1, + typename LIterator2, typename RIterator2, typename Compare2 + > + inline SPROUT_CONSTEXPR bool operator==( + sprout::set_union_iterator const& lhs, + sprout::set_union_iterator const& rhs + ) + { + return lhs.base() == rhs.base() && lhs.base2() == rhs.base2(); + } + template< + typename LIterator1, typename RIterator1, typename Compare1, + typename LIterator2, typename RIterator2, typename Compare2 + > + inline SPROUT_CONSTEXPR bool operator!=( + sprout::set_union_iterator const& lhs, + sprout::set_union_iterator const& rhs + ) + { + return !(lhs == rhs); + } + + // + // make_set_union_iterator + // + template + inline SPROUT_CONSTEXPR sprout::set_union_iterator + make_set_union_iterator(LIterator it1, LIterator lst1, RIterator it2, RIterator lst2, Compare comp) { + return sprout::set_union_iterator(it1, lst1, it2, lst2, comp); + } + template + inline SPROUT_CONSTEXPR sprout::set_union_iterator + make_set_union_iterator(LIterator it1, LIterator lst1, RIterator it2, RIterator lst2) { + return sprout::set_union_iterator(it1, lst1, it2, lst2); + } + + // + // swap + // + template + inline void + swap( + sprout::set_union_iterator& lhs, + sprout::set_union_iterator& rhs + ) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::set_union_iterator + iterator_next(sprout::set_union_iterator const& it) { + return it.next(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_SET_UNION_ITERATOR_HPP diff --git a/sprout/numeric/fixed/adjacent_difference.hpp b/sprout/numeric/fixed/adjacent_difference.hpp index c8e8cb56..81dcb373 100644 --- a/sprout/numeric/fixed/adjacent_difference.hpp +++ b/sprout/numeric/fixed/adjacent_difference.hpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include namespace sprout { namespace fixed { @@ -79,6 +81,12 @@ namespace sprout { return sprout::fixed::detail::adjacent_difference_impl(first, last, result, sprout::size(result)); } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + adjacent_difference(InputIterator first, InputIterator last) { + return sprout::fixed::adjacent_difference(first, last, sprout::pit()); + } + namespace detail { template inline SPROUT_CONSTEXPR typename std::enable_if< @@ -147,6 +155,12 @@ namespace sprout { adjacent_difference(InputIterator first, InputIterator last, Result const& result, BinaryOperation binary_op) { return sprout::fixed::detail::adjacent_difference_impl(first, last, result, binary_op, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + adjacent_difference(InputIterator first, InputIterator last, BinaryOperation binary_op) { + return sprout::fixed::adjacent_difference(first, last, sprout::pit(), binary_op); + } } // namespace fixed using sprout::fixed::adjacent_difference; diff --git a/sprout/numeric/fixed/iota.hpp b/sprout/numeric/fixed/iota.hpp index 992c81bf..c10f9acc 100644 --- a/sprout/numeric/fixed/iota.hpp +++ b/sprout/numeric/fixed/iota.hpp @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include namespace sprout { namespace fixed { @@ -29,6 +31,33 @@ namespace sprout { )... ); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + iota(Container const& cont, T value) { + return sprout::fixed::detail::iota_impl( + cont, sprout::index_range<0, sprout::container_traits::static_size>::make(), + value, + sprout::internal_begin_offset(cont), + sprout::size(cont) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + iota(Container const& cont, T value) { + return sprout::remake( + cont, sprout::size(cont), + sprout::make_counting_iterator(value), + sprout::next(sprout::make_counting_iterator(value), sprout::size(cont)) + ); + } } // namespace detail // // iota @@ -36,13 +65,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type iota(Container const& cont, T value) { - return sprout::fixed::detail::iota_impl( - cont, - sprout::index_range<0, sprout::container_traits::static_size>::make(), - value, - sprout::internal_begin_offset(cont), - sprout::size(cont) - ); + return sprout::fixed::detail::iota(cont, value); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + iota(T value) { + return sprout::fixed::detail::iota(sprout::pit(), value); } } // namespace fixed diff --git a/sprout/numeric/fixed/partial_sum.hpp b/sprout/numeric/fixed/partial_sum.hpp index b7396ee6..fe1680b0 100644 --- a/sprout/numeric/fixed/partial_sum.hpp +++ b/sprout/numeric/fixed/partial_sum.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -80,6 +81,12 @@ namespace sprout { return sprout::fixed::detail::partial_sum_impl(first, last, result, sprout::size(result)); } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + partial_sum(InputIterator first, InputIterator last) { + return sprout::fixed::partial_sum(first, last, sprout::pit()); + } + namespace detail { template inline SPROUT_CONSTEXPR typename std::enable_if< @@ -148,6 +155,12 @@ namespace sprout { partial_sum(InputIterator first, InputIterator last, Result const& result, BinaryOperation binary_op) { return sprout::fixed::detail::partial_sum_impl(first, last, result, binary_op, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + partial_sum(InputIterator first, InputIterator last, BinaryOperation binary_op) { + return sprout::fixed::partial_sum(first, last, sprout::pit(), binary_op); + } } // namespace fixed using sprout::fixed::partial_sum; diff --git a/sprout/range/algorithm/fixed/clamp_range_copy.hpp b/sprout/range/algorithm/fixed/clamp_range_copy.hpp index 302004a8..1b153e16 100644 --- a/sprout/range/algorithm/fixed/clamp_range_copy.hpp +++ b/sprout/range/algorithm/fixed/clamp_range_copy.hpp @@ -34,6 +34,28 @@ namespace sprout { { return sprout::fixed::clamp_range_copy(sprout::begin(input), sprout::end(input), result, low, high); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + clamp_range_copy( + Input const& input, + typename sprout::container_traits::value_type const& low, + typename sprout::container_traits::value_type const& high, + Compare comp + ) + { + return sprout::fixed::clamp_range_copy(sprout::begin(input), sprout::end(input), low, high, comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + clamp_range_copy( + Input const& input, + typename sprout::container_traits::value_type const& low, + typename sprout::container_traits::value_type const& high + ) + { + return sprout::fixed::clamp_range_copy(sprout::begin(input), sprout::end(input), low, high); + } } // namespace fixed using sprout::range::fixed::clamp_range_copy; diff --git a/sprout/range/algorithm/fixed/copy_until.hpp b/sprout/range/algorithm/fixed/copy_until.hpp index f7e59c27..0ef743a6 100644 --- a/sprout/range/algorithm/fixed/copy_until.hpp +++ b/sprout/range/algorithm/fixed/copy_until.hpp @@ -18,6 +18,12 @@ namespace sprout { copy_until(Input const& input, Result const& result, Predicate pred) { return sprout::fixed::copy_until(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_until(Input const& input, Predicate pred) { + return sprout::fixed::copy_until(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::copy_until; diff --git a/sprout/range/algorithm/fixed/copy_while.hpp b/sprout/range/algorithm/fixed/copy_while.hpp index 373d0eeb..648e0e25 100644 --- a/sprout/range/algorithm/fixed/copy_while.hpp +++ b/sprout/range/algorithm/fixed/copy_while.hpp @@ -18,6 +18,12 @@ namespace sprout { copy_while(Input const& input, Result const& result, Predicate pred) { return sprout::fixed::copy_while(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_while(Input const& input, Predicate pred) { + return sprout::fixed::copy_while(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::copy_while; diff --git a/sprout/range/algorithm/fixed/merge.hpp b/sprout/range/algorithm/fixed/merge.hpp index 7831bbcc..71324f6c 100644 --- a/sprout/range/algorithm/fixed/merge.hpp +++ b/sprout/range/algorithm/fixed/merge.hpp @@ -23,6 +23,17 @@ namespace sprout { merge(Input1 const& input1, Input2 const& input2, Result const& result) { return sprout::fixed::merge(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + merge(Input1 const& input1, Input2 const& input2, Compare comp) { + return sprout::fixed::merge(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + merge(Input1 const& input1, Input2 const& input2) { + return sprout::fixed::merge(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2)); + } } // namespace fixed using sprout::range::fixed::merge; diff --git a/sprout/range/algorithm/fixed/partition_copy.hpp b/sprout/range/algorithm/fixed/partition_copy.hpp index 8a72442d..32dcda75 100644 --- a/sprout/range/algorithm/fixed/partition_copy.hpp +++ b/sprout/range/algorithm/fixed/partition_copy.hpp @@ -18,6 +18,12 @@ namespace sprout { partition_copy(Input const& input, Result const& result, Predicate pred) { return sprout::fixed::partition_copy(sprout::begin(input), sprout::end(input), result, pred); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + partition_copy(Input const& input, Predicate pred) { + return sprout::fixed::partition_copy(sprout::begin(input), sprout::end(input), pred); + } } // namespace fixed using sprout::range::fixed::partition_copy; diff --git a/sprout/range/algorithm/fixed/remove_copy.hpp b/sprout/range/algorithm/fixed/remove_copy.hpp index 7bfce123..c8a526e2 100644 --- a/sprout/range/algorithm/fixed/remove_copy.hpp +++ b/sprout/range/algorithm/fixed/remove_copy.hpp @@ -18,6 +18,12 @@ namespace sprout { remove_copy(Input const& input, Result const& result, T const& value) { return sprout::fixed::remove_copy(sprout::begin(input), sprout::end(input), result, value); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + remove_copy(Input const& input, Result const& result, T const& value) { + return sprout::fixed::remove_copy(sprout::begin(input), sprout::end(input), value); + } } // namespace fixed using sprout::range::fixed::remove_copy; diff --git a/sprout/range/algorithm/fixed/remove_copy_if.hpp b/sprout/range/algorithm/fixed/remove_copy_if.hpp index eb6be178..babaf8d8 100644 --- a/sprout/range/algorithm/fixed/remove_copy_if.hpp +++ b/sprout/range/algorithm/fixed/remove_copy_if.hpp @@ -18,6 +18,12 @@ namespace sprout { remove_copy_if(Input const& input, Result const& result, Predicate pred) { return sprout::fixed::remove_copy_if(sprout::begin(input), sprout::end(input), result, pred); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + remove_copy_if(Input const& input, Predicate pred) { + return sprout::fixed::remove_copy_if(sprout::begin(input), sprout::end(input), pred); + } } // namespace fixed using sprout::range::fixed::remove_copy_if; diff --git a/sprout/range/algorithm/fixed/reverse_copy.hpp b/sprout/range/algorithm/fixed/reverse_copy.hpp index 7bd8e4e5..3c1f0326 100644 --- a/sprout/range/algorithm/fixed/reverse_copy.hpp +++ b/sprout/range/algorithm/fixed/reverse_copy.hpp @@ -18,6 +18,12 @@ namespace sprout { reverse_copy(Input const& input, Result const& result) { return sprout::fixed::reverse_copy(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + reverse_copy(Input const& input) { + return sprout::fixed::reverse_copy(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::reverse_copy; diff --git a/sprout/range/algorithm/fixed/rotate_copy.hpp b/sprout/range/algorithm/fixed/rotate_copy.hpp index e52e1055..3188c669 100644 --- a/sprout/range/algorithm/fixed/rotate_copy.hpp +++ b/sprout/range/algorithm/fixed/rotate_copy.hpp @@ -22,6 +22,15 @@ namespace sprout { { return sprout::fixed::rotate_copy(sprout::begin(input), middle, sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + rotate_copy( + Input const& input, typename sprout::container_traits::const_iterator middle + ) + { + return sprout::fixed::rotate_copy(sprout::begin(input), middle, sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::rotate_copy; diff --git a/sprout/range/algorithm/fixed/set_difference.hpp b/sprout/range/algorithm/fixed/set_difference.hpp index 1f832230..53d4784e 100644 --- a/sprout/range/algorithm/fixed/set_difference.hpp +++ b/sprout/range/algorithm/fixed/set_difference.hpp @@ -23,6 +23,17 @@ namespace sprout { set_difference(Input1 const& input1, Input2 const& input2, Result const& result) { return sprout::fixed::set_difference(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_difference(Input1 const& input1, Input2 const& input2, Compare comp) { + return sprout::fixed::set_difference(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_difference(Input1 const& input1, Input2 const& input2) { + return sprout::fixed::set_difference(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2)); + } } // namespace fixed using sprout::range::fixed::set_difference; diff --git a/sprout/range/algorithm/fixed/set_intersection.hpp b/sprout/range/algorithm/fixed/set_intersection.hpp index cd945756..bb39974d 100644 --- a/sprout/range/algorithm/fixed/set_intersection.hpp +++ b/sprout/range/algorithm/fixed/set_intersection.hpp @@ -23,6 +23,17 @@ namespace sprout { set_intersection(Input1 const& input1, Input2 const& input2, Result const& result) { return sprout::fixed::set_intersection(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_intersection(Input1 const& input1, Input2 const& input2, Compare comp) { + return sprout::fixed::set_intersection(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_intersection(Input1 const& input1, Input2 const& input2) { + return sprout::fixed::set_intersection(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2)); + } } // namespace fixed using sprout::range::fixed::set_intersection; diff --git a/sprout/range/algorithm/fixed/set_symmetric_difference.hpp b/sprout/range/algorithm/fixed/set_symmetric_difference.hpp index 5691e8c2..0b0854c3 100644 --- a/sprout/range/algorithm/fixed/set_symmetric_difference.hpp +++ b/sprout/range/algorithm/fixed/set_symmetric_difference.hpp @@ -23,6 +23,17 @@ namespace sprout { set_symmetric_difference(Input1 const& input1, Input2 const& input2, Result const& result) { return sprout::fixed::set_symmetric_difference(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_symmetric_difference(Input1 const& input1, Input2 const& input2, Compare comp) { + return sprout::fixed::set_symmetric_difference(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_symmetric_difference(Input1 const& input1, Input2 const& input2) { + return sprout::fixed::set_symmetric_difference(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2)); + } } // namespace fixed using sprout::range::fixed::set_symmetric_difference; diff --git a/sprout/range/algorithm/fixed/set_union.hpp b/sprout/range/algorithm/fixed/set_union.hpp index b9a42a00..934ea49c 100644 --- a/sprout/range/algorithm/fixed/set_union.hpp +++ b/sprout/range/algorithm/fixed/set_union.hpp @@ -23,6 +23,17 @@ namespace sprout { set_union(Input1 const& input1, Input2 const& input2, Result const& result) { return sprout::fixed::set_union(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_union(Input1 const& input1, Input2 const& input2, Compare comp) { + return sprout::fixed::set_union(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2), comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + set_union(Input1 const& input1, Input2 const& input2) { + return sprout::fixed::set_union(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), sprout::end(input2)); + } } // namespace fixed using sprout::range::fixed::set_union; diff --git a/sprout/range/algorithm/fixed/stable_partition_copy.hpp b/sprout/range/algorithm/fixed/stable_partition_copy.hpp index beaa5c46..9810838a 100644 --- a/sprout/range/algorithm/fixed/stable_partition_copy.hpp +++ b/sprout/range/algorithm/fixed/stable_partition_copy.hpp @@ -18,6 +18,12 @@ namespace sprout { stable_partition_copy(Input const& input, Result const& result, Predicate pred) { return sprout::fixed::stable_partition_copy(sprout::begin(input), sprout::end(input), result, pred); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + stable_partition_copy(Input const& input, Predicate pred) { + return sprout::fixed::stable_partition_copy(sprout::begin(input), sprout::end(input), pred); + } } // namespace fixed using sprout::range::fixed::stable_partition_copy; diff --git a/sprout/range/algorithm/fixed/swap_element_copy.hpp b/sprout/range/algorithm/fixed/swap_element_copy.hpp index 84e09d33..93a01fd1 100644 --- a/sprout/range/algorithm/fixed/swap_element_copy.hpp +++ b/sprout/range/algorithm/fixed/swap_element_copy.hpp @@ -23,6 +23,17 @@ namespace sprout { { return sprout::fixed::swap_element_copy(sprout::begin(input), sprout::end(input), result, pos1, pos2); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + swap_element_copy( + Input const& input, + typename sprout::container_traits::const_iterator pos1, + typename sprout::container_traits::const_iterator pos2 + ) + { + return sprout::fixed::swap_element_copy(sprout::begin(input), sprout::end(input), pos1, pos2); + } } // namespace fixed using sprout::range::fixed::swap_element_copy; diff --git a/sprout/range/algorithm/fixed/unique_copy.hpp b/sprout/range/algorithm/fixed/unique_copy.hpp index 240b42ba..72854457 100644 --- a/sprout/range/algorithm/fixed/unique_copy.hpp +++ b/sprout/range/algorithm/fixed/unique_copy.hpp @@ -23,6 +23,17 @@ namespace sprout { unique_copy(Input const& input, Result const& result) { return sprout::fixed::unique_copy(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unique_copy(Input const& input, BinaryPredicate pred) { + return sprout::fixed::unique_copy(sprout::begin(input), sprout::end(input), pred); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unique_copy(Input const& input) { + return sprout::fixed::unique_copy(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::unique_copy; diff --git a/sprout/string/tuple.hpp b/sprout/string/tuple.hpp index c0581e4f..10cf7e92 100644 --- a/sprout/string/tuple.hpp +++ b/sprout/string/tuple.hpp @@ -50,8 +50,8 @@ namespace std { // template struct tuple_element > { - public: static_assert(I < N, "tuple_element<>: index out of range"); + public: typedef T type; }; #if defined(__clang__) diff --git a/sprout/type/integral_array.hpp b/sprout/type/integral_array.hpp index 779d6824..5d78e797 100644 --- a/sprout/type/integral_array.hpp +++ b/sprout/type/integral_array.hpp @@ -18,6 +18,7 @@ namespace sprout { : public sprout::types::type_tuple...> { public: + typedef integral_array type; typedef T value_type; }; } // namespace types diff --git a/sprout/type/string/string.hpp b/sprout/type/string/string.hpp index fd7aea59..884263c6 100644 --- a/sprout/type/string/string.hpp +++ b/sprout/type/string/string.hpp @@ -15,7 +15,10 @@ namespace sprout { template struct basic_string : public sprout::types::integral_array - {}; + { + public: + typedef basic_string type; + }; } // namespace types } // namespace sprout diff --git a/sprout/type/type_tuple.hpp b/sprout/type/type_tuple.hpp index a065ccc4..24ce84c8 100644 --- a/sprout/type/type_tuple.hpp +++ b/sprout/type/type_tuple.hpp @@ -18,9 +18,14 @@ namespace sprout { template struct type_tuple { public: + typedef type_tuple type; typedef sprout::types::index_iterator begin; typedef sprout::types::index_iterator end; + public: + SPROUT_STATIC_CONSTEXPR std::size_t size = sizeof...(Types); }; + template + SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::types::type_tuple::size; // // rebind_types diff --git a/sprout/uuid/tuple.hpp b/sprout/uuid/tuple.hpp index 99301db3..cdc9d0f1 100644 --- a/sprout/uuid/tuple.hpp +++ b/sprout/uuid/tuple.hpp @@ -52,8 +52,8 @@ namespace std { // template struct tuple_element { - public: static_assert(I < 16, "tuple_element<>: index out of range"); + public: typedef sprout::uuids::uuid::value_type type; }; #if defined(__clang__)