diff --git a/sprout/functional/bind/bind.hpp b/sprout/functional/bind/bind.hpp index cf449a5a..08d98e44 100644 --- a/sprout/functional/bind/bind.hpp +++ b/sprout/functional/bind/bind.hpp @@ -58,36 +58,38 @@ namespace sprout { struct placeholder {}; namespace placeholders { - SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29; - SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30; + namespace { + SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29{}; + SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30{}; + } // anonymous-namespace } // namespace placeholders using sprout::placeholders::_1; using sprout::placeholders::_2; diff --git a/sprout/iterator/reverse_iterator.hpp b/sprout/iterator/reverse_iterator.hpp index 34c414d6..02b042b7 100644 --- a/sprout/iterator/reverse_iterator.hpp +++ b/sprout/iterator/reverse_iterator.hpp @@ -162,10 +162,10 @@ namespace sprout { return !(lhs < rhs); } template - SPROUT_CONSTEXPR auto operator-( + SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) operator-( sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs - ) -> decltype(lhs.base() - rhs.base()) + ) { return lhs.base() - rhs.base(); } diff --git a/sprout/iterator/transform_iterator.hpp b/sprout/iterator/transform_iterator.hpp new file mode 100644 index 00000000..4576d621 --- /dev/null +++ b/sprout/iterator/transform_iterator.hpp @@ -0,0 +1,441 @@ +#ifndef SPROUT_ITERATOR_TRANSFORM_ITERATOR_HPP +#define SPROUT_ITERATOR_TRANSFORM_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // transform_iterator + // + template + class transform_iterator + : public std::iterator< + typename std::iterator_traits::iterator_category, + typename std::remove_reference< + typename std::result_of< + BinaryFunction ( + typename std::iterator_traits::reference, + typename std::iterator_traits::reference + ) + >::type + >::type, + typename std::iterator_traits::difference_type, + typename std::remove_reference< + typename std::result_of< + BinaryFunction ( + typename std::iterator_traits::reference, + typename std::iterator_traits::reference + ) + >::type + >::type*, + typename std::result_of< + BinaryFunction ( + typename std::iterator_traits::reference, + typename std::iterator_traits::reference + ) + >::type + > + { + public: + typedef BinaryFunction functor_type; + typedef LIterator iterator_type; + typedef RIterator iterator2_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::result_of< + BinaryFunction ( + typename std::iterator_traits::reference, + typename std::iterator_traits::reference + ) + >::type reference; + typedef typename std::remove_reference::type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef value_type* pointer; + protected: + iterator_type current; + iterator2_type current2; + functor_type func; + public: + transform_iterator() = default; + transform_iterator(transform_iterator const&) = default; + SPROUT_CONSTEXPR transform_iterator(iterator_type it, iterator2_type it2) + : current(it) + , current2(it2) + {} + SPROUT_CONSTEXPR transform_iterator(iterator_type it, iterator2_type it2, functor_type func) + : current(it) + , current2(it2) + , func(func) + {} + template + SPROUT_CONSTEXPR transform_iterator(transform_iterator const& it) + : current(it.current) + , current2(it.current2) + , func(it.func) + {} + template + transform_iterator& operator=(transform_iterator const& it) { + transform_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR iterator_type base2() const { + return current2; + } + SPROUT_CONSTEXPR functor_type functor() const { + return func; + } + SPROUT_CONSTEXPR reference operator*() const { + return func(*current, *current2); + } + SPROUT_CONSTEXPR pointer operator->() const { + return &func(*current, *current2); + } + transform_iterator& operator++() { + ++current; + ++current2; + return *this; + } + transform_iterator operator++(int) { + transform_iterator result(*this); + ++current; + ++current2; + return result; + } + transform_iterator& operator--() { + --current; + --current2; + return *this; + } + transform_iterator operator--(int) { + transform_iterator temp(*this); + --current; + --current2; + return temp; + } + SPROUT_CONSTEXPR transform_iterator operator+(difference_type n) const { + return transform_iterator(current + n, current2 + n, func); + } + SPROUT_CONSTEXPR transform_iterator operator-(difference_type n) const { + return transform_iterator(current - n, current2 - n, func); + } + transform_iterator& operator+=(difference_type n) { + transform_iterator temp(current + n, current2 + n, func); + temp.swap(*this); + return *this; + } + transform_iterator& operator-=(difference_type n) { + transform_iterator temp(current - n, current2 - n, func); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return func(current[n], current2[n]); + } + SPROUT_CONSTEXPR transform_iterator next() const { + return transform_iterator(sprout::next(current), sprout::next(current2), func); + } + SPROUT_CONSTEXPR transform_iterator prev() const { + return transform_iterator(sprout::prev(current), sprout::prev(current2), func); + } + void swap(transform_iterator& other) { + using std::swap; + swap(current, other.current); + swap(current2, other.current2); + swap(func, other.func); + } + }; + + // + // transform_iterator + // + template + class transform_iterator + : public std::iterator< + typename std::iterator_traits::iterator_category, + typename std::remove_reference< + typename std::result_of< + UnaryFunction (typename std::iterator_traits::reference) + >::type + >::type, + typename std::iterator_traits::difference_type, + typename std::remove_reference< + typename std::result_of< + UnaryFunction (typename std::iterator_traits::reference) + >::type + >::type*, + typename std::result_of< + UnaryFunction (typename std::iterator_traits::reference) + >::type + > + { + public: + typedef UnaryFunction functor_type; + typedef Iterator iterator_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::result_of< + UnaryFunction (typename std::iterator_traits::reference) + >::type reference; + typedef typename std::remove_reference::type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef value_type* pointer; + protected: + iterator_type current; + functor_type func; + public: + transform_iterator() = default; + transform_iterator(transform_iterator const&) = default; + explicit SPROUT_CONSTEXPR transform_iterator(iterator_type it) + : current(it) + {} + SPROUT_CONSTEXPR transform_iterator(iterator_type it, functor_type func) + : current(it) + , func(func) + {} + template + SPROUT_CONSTEXPR transform_iterator(transform_iterator const& it) + : current(it.current) + , func(it.func) + {} + template + transform_iterator& operator=(transform_iterator const& it) { + transform_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR functor_type functor() const { + return func; + } + SPROUT_CONSTEXPR reference operator*() const { + return func(*current); + } + SPROUT_CONSTEXPR pointer operator->() const { + return &func(*current); + } + transform_iterator& operator++() { + ++current; + return *this; + } + transform_iterator operator++(int) { + transform_iterator result(*this); + ++current; + return result; + } + transform_iterator& operator--() { + --current; + return *this; + } + transform_iterator operator--(int) { + transform_iterator temp(*this); + --current; + return temp; + } + SPROUT_CONSTEXPR transform_iterator operator+(difference_type n) const { + return transform_iterator(current + n, func); + } + SPROUT_CONSTEXPR transform_iterator operator-(difference_type n) const { + return transform_iterator(current - n, func); + } + transform_iterator& operator+=(difference_type n) { + transform_iterator temp(current + n, func); + temp.swap(*this); + return *this; + } + transform_iterator& operator-=(difference_type n) { + transform_iterator temp(current - n, func); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return func(current[n]); + } + SPROUT_CONSTEXPR transform_iterator next() const { + return transform_iterator(sprout::next(current), func); + } + SPROUT_CONSTEXPR transform_iterator prev() const { + return transform_iterator(sprout::prev(current), func); + } + void swap(transform_iterator& other) { + using std::swap; + swap(current, other.current); + swap(func, other.func); + } + }; + + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR bool operator==( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return lhs.base() == rhs.base(); + } + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR bool operator!=( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return !(lhs == rhs); + } + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR bool operator<( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return lhs.base() < rhs.base(); + } + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR bool operator>( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return rhs < lhs; + } + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR bool operator<=( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return !(rhs < lhs); + } + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR bool operator>=( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return !(lhs < rhs); + } + template< + typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1, + typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2 + > + SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) operator-( + sprout::transform_iterator const& lhs, + sprout::transform_iterator const& rhs + ) + { + return lhs.base() - rhs.base(); + } + template + SPROUT_CONSTEXPR sprout::transform_iterator operator+( + typename sprout::transform_iterator::difference_type n, + sprout::transform_iterator const& it + ) + { + return it + n; + } + + // + // make_transform_iterator + // + template + SPROUT_CONSTEXPR sprout::transform_iterator + make_transform_iterator(LIterator it1, RIterator it2, BinaryFunction func) { + return sprout::transform_iterator(it1, it2, func); + } + template + SPROUT_CONSTEXPR sprout::transform_iterator + make_transform_iterator(Iterator it, UnaryFunction func) { + return sprout::transform_iterator(it, func); + } + + // + // swap + // + template + void swap( + sprout::transform_iterator& lhs, + sprout::transform_iterator& rhs + ) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // next + // + template + SPROUT_CONSTEXPR sprout::transform_iterator next( + sprout::transform_iterator const& it + ) + { + return it.next(); + } + template + SPROUT_CONSTEXPR sprout::transform_iterator next( + sprout::transform_iterator const& it, + typename sprout::transform_iterator::difference_type n + ) + { + return it + n; + } + + // + // prev + // + template + SPROUT_CONSTEXPR sprout::transform_iterator prev( + sprout::transform_iterator const& it + ) + { + return it.prev(); + } + template + SPROUT_CONSTEXPR sprout::transform_iterator prev( + sprout::transform_iterator const& it, + typename sprout::transform_iterator::difference_type n + ) + { + return it - n; + } + + // + // distance + // + template + SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type + distance( + sprout::transform_iterator first, + sprout::transform_iterator last + ) + { + return last - first; + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_TRANSFORM_ITERATOR_HPP diff --git a/sprout/pit.hpp b/sprout/pit.hpp index 53ba3d14..f21914c9 100644 --- a/sprout/pit.hpp +++ b/sprout/pit.hpp @@ -192,7 +192,7 @@ namespace sprout { Args&&... args ) { - return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); } }; diff --git a/sprout/range/adaptor.hpp b/sprout/range/adaptor.hpp new file mode 100644 index 00000000..ee511955 --- /dev/null +++ b/sprout/range/adaptor.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_RANGE_ADAPTOR_HPP +#define SPROUT_RANGE_ADAPTOR_HPP + +#include +#include + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_HPP diff --git a/sprout/range/adaptor/transformed.hpp b/sprout/range/adaptor/transformed.hpp new file mode 100644 index 00000000..42ea8abd --- /dev/null +++ b/sprout/range/adaptor/transformed.hpp @@ -0,0 +1,226 @@ +#ifndef SPROUT_RANGE_ADAPTOR_TRANSFORMD_HPP +#define SPROUT_RANGE_ADAPTOR_TRANSFORMD_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace range { + // + // transformed_range + // + template + class transformed_range + : public sprout::range::range_container< + sprout::transform_iterator< + BinaryFunction, + typename sprout::container_traits::iterator, + typename sprout::container_traits::iterator + > + > + , public sprout::detail::inherit_if_fixed_size + { + public: + typedef BinaryFunction functor_type; + typedef LRange range_type; + typedef RRange range2_type; + typedef sprout::range::range_container< + sprout::transform_iterator< + BinaryFunction, + typename sprout::container_traits::iterator, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::size_type size_type; + public: + transformed_range() = default; + transformed_range(transformed_range const&) = default; + SPROUT_CONSTEXPR transformed_range(functor_type func, range_type& range1, range2_type& range2) + : base_type( + iterator(sprout::begin(range1), sprout::begin(range2), func), + iterator(sprout::end(range1), sprout::end(range2), func) + ) + {} + }; + + template + class transformed_range + : public sprout::range::range_container< + sprout::transform_iterator< + UnaryFunction, + typename sprout::container_traits::iterator + > + > + , public sprout::detail::inherit_if_fixed_size + { + public: + typedef UnaryFunction functor_type; + typedef Range range_type; + typedef sprout::range::range_container< + sprout::transform_iterator< + UnaryFunction, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + public: + transformed_range() = default; + transformed_range(transformed_range const&) = default; + SPROUT_CONSTEXPR transformed_range(functor_type func, range_type& range) + : base_type( + iterator(sprout::begin(range), func), + iterator(sprout::end(range), func) + ) + {} + }; + + // + // transform_holder + // + template + class transform_holder { + public: + typedef BinaryFunction functor_type; + typedef RRange range2_type; + private: + functor_type func_; + sprout::value_holder range_; + public: + transform_holder() = default; + transform_holder(transform_holder const&) = default; + SPROUT_CONSTEXPR transform_holder(functor_type func, range2_type& range) + : func_(func) + , range_(range) + {} + SPROUT_CONSTEXPR functor_type functor() const { + return func_; + } + SPROUT_CONSTEXPR range2_type& range() const { + return range_; + } + }; + template + class transform_holder { + public: + typedef UnaryFunction functor_type; + private: + functor_type func_; + public: + transform_holder() = default; + transform_holder(transform_holder const&) = default; + explicit SPROUT_CONSTEXPR transform_holder(functor_type func) + : func_(func) + {} + SPROUT_CONSTEXPR functor_type functor() const { + return func_; + } + }; + + // + // transformed_forwarder + // + class transformed_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::range::transform_holder< + BinaryFunction, + typename std::remove_reference::type>::type + > + operator()(RRange&& range, BinaryFunction func) { + return sprout::range::transform_holder< + BinaryFunction, + typename std::remove_reference::type>::type + > ( + func, + sprout::lvalue_forward(range) + ); + } + template + SPROUT_CONSTEXPR sprout::range::transform_holder + operator()(UnaryFunction func) { + return sprout::range::transform_holder(func); + } + }; + + // + // transformed + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::range::transformed_forwarder transformed{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::range::transformed_range< + BinaryFunction, + typename std::remove_reference::type>::type, + RRange + > + operator|(LRange&& lhs, sprout::range::transform_holder const& rhs) { + return sprout::range::transformed_range< + BinaryFunction, + typename std::remove_reference::type>::type, + RRange + >( + rhs.functor(), + sprout::lvalue_forward(lhs), + rhs.range() + ); + } + template + inline SPROUT_CONSTEXPR sprout::range::transformed_range< + UnaryFunction, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::range::transform_holder const& rhs) { + return sprout::range::transformed_range< + UnaryFunction, + typename std::remove_reference::type>::type + >( + rhs.functor(), + sprout::lvalue_forward(lhs) + ); + } + } // namespace range + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_TRANSFORMD_HPP diff --git a/sprout/range/range_container.hpp b/sprout/range/range_container.hpp index 7ffb8b4e..e15d594f 100644 --- a/sprout/range/range_container.hpp +++ b/sprout/range/range_container.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace sprout { namespace range { diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index 9dfd0c34..f31f8385 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -13,27 +13,52 @@ namespace sprout { namespace detail { template class head_base; + //!!! + // EBO disabled +// template +// class head_base +// : public Head +// { +// public: +// static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { +// return t; +// } +// static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { +// return t; +// } +// public: +// SPROUT_CONSTEXPR head_base() +// : Head() +// {} +// SPROUT_CONSTEXPR head_base(Head const& v) +// : Head(v) +// {} +// template +// SPROUT_CONSTEXPR head_base(UHead&& v) +// : Head(sprout::forward(v)) +// {} +// }; template - class head_base - : public Head - { + class head_base { public: static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { - return t; + return t.head_; } static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { - return t; + return t.head_; } + private: + Head head_; public: SPROUT_CONSTEXPR head_base() - : Head() + : head_() {} SPROUT_CONSTEXPR head_base(Head const& v) - : Head(v) + : head_(v) {} template SPROUT_CONSTEXPR head_base(UHead&& v) - : Head(sprout::forward(v)) + : head_(sprout::forward(v)) {} }; template