add sprout/range/adaptor/deep_copied.hpp

fix sprout/range/adaptor/sized.hpp
This commit is contained in:
bolero-MURAKAMI 2012-06-16 15:35:10 +09:00
parent bcd7674cc0
commit 955561e36c
10 changed files with 178 additions and 15 deletions

View file

@ -2,6 +2,7 @@
#define SPROUT_CONTAINER_CONTAINER_TRANSFORM_TRAITS_HPP #define SPROUT_CONTAINER_CONTAINER_TRANSFORM_TRAITS_HPP
#include <cstddef> #include <cstddef>
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/container/container_traits.hpp> #include <sprout/container/container_traits.hpp>
@ -13,9 +14,33 @@ namespace sprout {
struct container_transform_traits; struct container_transform_traits;
namespace detail { namespace detail {
template<typename Container>
struct is_like_array_class
: public std::false_type
{};
template<
template<typename, std::size_t> class Array,
typename T,
std::size_t N
>
struct is_like_array_class<Array<T, N> >
: public std::true_type
{};
template<typename Container>
struct is_like_array_class<Container const>
: public sprout::detail::is_like_array_class<Container>
{};
template<typename Container>
struct is_like_array_class<Container volatile>
: public sprout::detail::is_like_array_class<Container>
{};
template<typename Container>
struct is_like_array_class<Container const volatile>
: public sprout::detail::is_like_array_class<Container>
{};
template<typename Container, typename sprout::container_traits<Container>::size_type Size> template<typename Container, typename sprout::container_traits<Container>::size_type Size>
struct default_array_rebind_size; struct default_array_rebind_size;
template< template<
template<typename, std::size_t> class Array, template<typename, std::size_t> class Array,
typename T, typename T,
@ -26,16 +51,26 @@ namespace sprout {
public: public:
typedef Array<T, Size> type; typedef Array<T, Size> type;
}; };
template<typename Container, typename = void>
struct inherit_default_rebind_size {};
template<typename Container>
struct inherit_default_rebind_size<
Container,
typename std::enable_if<sprout::detail::is_like_array_class<Container>::value>::type
> {
public:
template<typename sprout::container_traits<Container>::size_type Size>
struct rebind_size
: public sprout::detail::default_array_rebind_size<Container, Size>
{};
};
} // namespace detail } // namespace detail
template<typename Container> template<typename Container>
struct container_transform_traits { struct container_transform_traits
public: : public sprout::detail::inherit_default_rebind_size<Container>
template<typename sprout::container_traits<Container>::size_type Size> {};
struct rebind_size
: public sprout::detail::default_array_rebind_size<Container, Size>
{};
};
template<typename Container> template<typename Container>
struct container_transform_traits<Container const> { struct container_transform_traits<Container const> {
public: public:

View file

@ -14,6 +14,7 @@
#include <sprout/container/static_size.hpp> #include <sprout/container/static_size.hpp>
#include <sprout/container/copied_type.hpp> #include <sprout/container/copied_type.hpp>
#include <sprout/container/rebind_size.hpp> #include <sprout/container/rebind_size.hpp>
#include <sprout/container/weak_rebind_size.hpp>
#include <sprout/container/internal.hpp> #include <sprout/container/internal.hpp>
#include <sprout/container/indexes.hpp> #include <sprout/container/indexes.hpp>

View file

@ -10,10 +10,9 @@ namespace sprout {
// rebind_size // rebind_size
// //
template<typename Container, typename sprout::container_traits<Container>::size_type Size> template<typename Container, typename sprout::container_traits<Container>::size_type Size>
struct rebind_size { struct rebind_size
public: : public sprout::container_transform_traits<Container>::template rebind_size<Size>
typedef typename sprout::container_transform_traits<Container>::template rebind_size<Size>::type type; {};
};
} // namespace containers } // namespace containers
} // namespace sprout } // namespace sprout

View file

@ -0,0 +1,74 @@
#ifndef SPROUT_CONTAINER_WEAK_REBIND_SIZE_HPP
#define SPROUT_CONTAINER_WEAK_REBIND_SIZE_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/container/container_transform_traits.hpp>
namespace sprout {
namespace containers {
namespace detail {
template<
typename T,
template<typename sprout::container_traits<T>::size_type> class = T::template rebind_size
>
std::true_type sprout_has_xxx_impl_check_template_rebind_size(int);
template<typename T>
std::false_type sprout_has_xxx_impl_check_template_rebind_size(long);
template<typename T>
struct has_rebind_size
: decltype(sprout::containers::detail::sprout_has_xxx_impl_check_template_rebind_size<T>(0))
{};
} // namespace detail
//
// is_rebindable_size
//
template<typename Container>
struct is_rebindable_size
: public sprout::containers::detail::has_rebind_size<
sprout::container_transform_traits<Container>
>
{};
template<typename Container>
struct is_rebindable_size<Container const>
: public sprout::containers::is_rebindable_size<Container>
{};
template<typename Container>
struct is_rebindable_size<Container volatile>
: public sprout::containers::is_rebindable_size<Container>
{};
template<typename Container>
struct is_rebindable_size<Container const volatile>
: public sprout::containers::is_rebindable_size<Container>
{};
namespace detail {
template<typename Container, typename sprout::container_traits<Container>::size_type Size, typename = void>
struct weak_rebind_size_impl;
template<typename Container, typename sprout::container_traits<Container>::size_type Size>
struct weak_rebind_size_impl<
Container, Size,
typename std::enable_if<sprout::containers::is_rebindable_size<Container>::value>::type
>
: public sprout::container_transform_traits<Container>::template rebind_size<Size>
{};
template<typename Container, typename sprout::container_traits<Container>::size_type Size>
struct weak_rebind_size_impl<
Container, Size,
typename std::enable_if<!sprout::containers::is_rebindable_size<Container>::value>::type
> {
public:
typedef Container type;
};
} // namespace detail
//
// weak_rebind_size
//
template<typename Container, typename sprout::container_traits<Container>::size_type Size>
struct weak_rebind_size
: public sprout::containers::detail::weak_rebind_size_impl<Container, Size>
{};
} // namespace containers
} // namespace sprout
#endif // #ifndef SPROUT_CONTAINER_WEAK_REBIND_SIZE_HPP

View file

@ -6,6 +6,7 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/next.hpp> #include <sprout/iterator/next.hpp>
#include <sprout/iterator/prev.hpp> #include <sprout/iterator/prev.hpp>
#include <sprout/iterator/distance.hpp>
#include <sprout/endian_traits.hpp> #include <sprout/endian_traits.hpp>
namespace sprout { namespace sprout {

View file

@ -5,6 +5,7 @@
#include <sprout/range/adaptor/copied.hpp> #include <sprout/range/adaptor/copied.hpp>
#include <sprout/range/adaptor/transformed.hpp> #include <sprout/range/adaptor/transformed.hpp>
#include <sprout/range/adaptor/counting.hpp> #include <sprout/range/adaptor/counting.hpp>
#include <sprout/range/adaptor/deep_copied.hpp>
#include <sprout/range/adaptor/sized.hpp> #include <sprout/range/adaptor/sized.hpp>
#include <sprout/range/adaptor/size_enumed.hpp> #include <sprout/range/adaptor/size_enumed.hpp>
#include <sprout/range/adaptor/sinusoidal.hpp> #include <sprout/range/adaptor/sinusoidal.hpp>

View file

@ -0,0 +1,36 @@
#ifndef SPROUT_RANGE_ADAPTOR_DEEP_COPIED_HPP
#define SPROUT_RANGE_ADAPTOR_DEEP_COPIED_HPP
#include <sprout/config.hpp>
#include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp>
#include <sprout/utility/forward.hpp>
namespace sprout {
namespace adaptors {
//
// deep_copied_forwarder
//
class deep_copied_forwarder {};
//
// deep_copied
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::adaptors::deep_copied_forwarder deep_copied{};
} // anonymous-namespace
//
// operator|
//
template<typename Range>
inline SPROUT_CONSTEXPR typename sprout::container_construct_traits<
typename std::remove_reference<Range>::type
>::copied_type
operator|(Range&& lhs, sprout::adaptors::deep_copied_forwarder const& rhs) {
return sprout::deep_copy(sprout::forward<Range>(lhs));
}
} // namespace adaptors
} // namespace sprout
#endif // #ifndef SPROUT_RANGE_ADAPTOR_DEEP_COPIED_HPP

View file

@ -7,6 +7,7 @@
#include <sprout/pit.hpp> #include <sprout/pit.hpp>
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/container/metafunctions.hpp>
#include <sprout/range/range_container.hpp> #include <sprout/range/range_container.hpp>
#include <sprout/range/algorithm/copy.hpp> #include <sprout/range/algorithm/copy.hpp>
#include <sprout/type_traits/lvalue_reference.hpp> #include <sprout/type_traits/lvalue_reference.hpp>
@ -80,7 +81,8 @@ namespace sprout {
explicit SPROUT_CONSTEXPR sized_range(range_type& range) explicit SPROUT_CONSTEXPR sized_range(range_type& range)
: base_type( : base_type(
sprout::begin(range), sprout::begin(range),
sized_impl_type::static_size < sprout::size(range) sized_impl_type::static_size
< static_cast<typename sprout::container_traits<Range>::size_type>(sprout::size(range))
? sprout::next(sprout::begin(range), sized_impl_type::static_size) ? sprout::next(sprout::begin(range), sized_impl_type::static_size)
: sprout::end(range) : sprout::end(range)
) )
@ -126,8 +128,13 @@ namespace sprout {
// //
template<typename Range, typename sprout::container_traits<Range>::size_type Size> template<typename Range, typename sprout::container_traits<Range>::size_type Size>
struct container_construct_traits<sprout::adaptors::sized_range<Range, Size> > { struct container_construct_traits<sprout::adaptors::sized_range<Range, Size> > {
private:
typedef typename sprout::container_construct_traits<Range>::copied_type range_copied_type;
public: public:
typedef typename sprout::container_construct_traits<Range>::copied_type copied_type; typedef typename sprout::containers::weak_rebind_size<
range_copied_type,
sprout::adaptors::sized_range<Range, Size>::static_size
>::type copied_type;
public: public:
template<typename Cont> template<typename Cont>
static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) {

View file

@ -9,7 +9,7 @@
// SPROUT_HAS_XXX_TYPE_DEF // SPROUT_HAS_XXX_TYPE_DEF
// //
#define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \ #define SPROUT_HAS_XXX_TYPE_DEF(NAME, TYPE) \
template<typename T, typename Enable = typename T::TYPE> \ template<typename T, typename = typename T::TYPE> \
std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(int); \ std::true_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(int); \
template<typename T> \ template<typename T> \
std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(long); \ std::false_type SPROUT_PP_CAT(SPROUT_PP_CAT(sprout_has_xxx_impl_check_type_, TYPE), __LINE__)(long); \

View file

@ -6,6 +6,7 @@
#include <bitset> #include <bitset>
#include <iostream> #include <iostream>
#include <sprout/container.hpp> #include <sprout/container.hpp>
#include <testspr/typeinfo.hpp>
namespace testspr { namespace testspr {
// //
@ -37,6 +38,14 @@ namespace testspr {
testspr::print_ln(std::bitset<sizeof(T) * 8>(t).template to_string<char>()); testspr::print_ln(std::bitset<sizeof(T) * 8>(t).template to_string<char>());
} }
//
// print_typename
//
template<typename T>
void print_typename() {
testspr::print_ln(testspr::typename_of<T>());
}
// //
// print_hl // print_hl
// //