fix: copy - support STL container

This commit is contained in:
bolero-MURAKAMI 2013-01-14 01:13:48 +09:00
parent 1ed18456b3
commit d99a7d1436
7 changed files with 189 additions and 90 deletions

View file

@ -3,57 +3,8 @@
#include <sscrisk/cel/array.hpp> #include <sscrisk/cel/array.hpp>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION #include <sprout/container/sscrisk/cel/array.hpp>
# include <cstddef> #include <sprout/functional/hash/sscrisk/cel/array.hpp>
# include <type_traits> #include <sprout/tuple/sscrisk/cel/array.hpp>
# include <sprout/container/traits.hpp>
# include <sprout/iterator/index_iterator.hpp>
#endif
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
namespace sprout {
//
// container_traits
//
template<typename T, std::size_t N>
struct container_traits<sscrisk::cel::array<T, N> >
: public sprout::detail::container_traits_default<sscrisk::cel::array<T, N> >
{
public:
typedef sprout::index_iterator<sscrisk::cel::array<T, N>&> iterator;
typedef sprout::index_iterator<sscrisk::cel::array<T, N> const&> const_iterator;
};
} // namespace sprout
namespace sprout {
//
// range_begin
//
template<typename T, std::size_t N>
inline typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator
range_begin(sscrisk::cel::array<T, N>& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator(cont, 0);
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator
range_begin(sscrisk::cel::array<T, N> const& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator(cont, 0);
}
//
// range_end
//
template<typename T, std::size_t N>
inline typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator
range_end(sscrisk::cel::array<T, N>& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator(cont, cont.size());
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator
range_end(sscrisk::cel::array<T, N> const& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator(cont, cont.size());
}
} // namespace sprout
#endif
#endif // #ifndef SPROUT_ADAPT_SSCRISK_CEL_ARRAY_HPP #endif // #ifndef SPROUT_ADAPT_SSCRISK_CEL_ARRAY_HPP

View file

@ -0,0 +1,9 @@
#ifndef SPROUT_ADAPT_SSCRISK_CEL_UTILITY_HPP
#define SPROUT_ADAPT_SSCRISK_CEL_UTILITY_HPP
#include <sscrisk/cel/utility.hpp>
#include <sprout/config.hpp>
#include <sprout/functional/hash/sscrisk/cel/utility.hpp>
#include <sprout/tuple/sscrisk/cel/utility.hpp>
#endif // #ifndef SPROUT_ADAPT_SSCRISK_CEL_UTILITY_HPP

View file

@ -49,6 +49,7 @@ namespace sprout {
sprout::distance(first, last) sprout::distance(first, last)
); );
} }
template<typename InputIterator, typename Result, typename... Args> template<typename InputIterator, typename Result, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::static_size == sizeof...(Args),
@ -87,6 +88,30 @@ namespace sprout {
{ {
return sprout::fixed::detail::copy_impl(first, last, result, sprout::size(result)); return sprout::fixed::detail::copy_impl(first, last, result, sprout::size(result));
} }
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy(InputIterator first, InputIterator last, Result const& result)
{
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
return sprout::fixed::detail::copy(first, last, result, category());
}
template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy(InputIterator first, InputIterator last, Result const& result)
{
return sprout::remake<Result>(
result,
sprout::size(result),
first, last
);
}
} // namespace detail } // namespace detail
// //
// copy // copy
@ -94,8 +119,7 @@ namespace sprout {
template<typename InputIterator, typename Result> template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
copy(InputIterator first, InputIterator last, Result const& result) { copy(InputIterator first, InputIterator last, Result const& result) {
typedef typename std::iterator_traits<InputIterator>::iterator_category* category; return sprout::fixed::detail::copy(first, last, result);
return sprout::fixed::detail::copy(first, last, result, category());
} }
} // namespace fixed } // namespace fixed

View file

@ -1,6 +1,7 @@
#ifndef SPROUT_CONTAINER_CONTAINER_TRAITS_CONSTRUCT_TRAITS_HPP #ifndef SPROUT_CONTAINER_CONTAINER_TRAITS_CONSTRUCT_TRAITS_HPP
#define SPROUT_CONTAINER_CONTAINER_TRAITS_CONSTRUCT_TRAITS_HPP #define SPROUT_CONTAINER_CONTAINER_TRAITS_CONSTRUCT_TRAITS_HPP
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/container/container_traits.hpp> #include <sprout/container/container_traits.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/forward.hpp>
@ -14,34 +15,51 @@ namespace sprout {
namespace detail { namespace detail {
template<typename Container, typename... Args> template<typename Container, typename... Args>
inline SPROUT_CONSTEXPR typename sprout::container_construct_traits<Container>::copied_type inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Container>::value,
typename sprout::container_construct_traits<Container>::copied_type
>::type
default_make_container(Args&&... args) { default_make_container(Args&&... args) {
typedef typename sprout::container_construct_traits<Container>::copied_type copied_type; typedef typename sprout::container_construct_traits<Container>::copied_type copied_type;
return copied_type{{sprout::forward<Args>(args)...}}; return copied_type{{sprout::forward<Args>(args)...}};
} }
template<typename Container, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Container>::value,
typename sprout::container_construct_traits<Container>::copied_type
>::type
default_make_container(Args&&... args) {
typedef typename sprout::container_construct_traits<Container>::copied_type copied_type;
return copied_type{sprout::forward<Args>(args)...};
}
template<typename Container>
struct container_construct_traits_impl {
public:
typedef Container copied_type;
public:
template<typename Cont>
static SPROUT_CONSTEXPR copied_type
deep_copy(Cont&& cont) {
return sprout::forward<Cont>(cont);
}
template<typename... Args>
static SPROUT_CONSTEXPR copied_type
make(Args&&... args) {
return sprout::detail::default_make_container<Container>(sprout::forward<Args>(args)...);
}
template<typename Cont, typename... Args>
static SPROUT_CONSTEXPR copied_type
remake(Cont&& cont, typename sprout::container_traits<Container>::difference_type size, Args&&... args) {
return make(sprout::forward<Args>(args)...);
}
};
} // namespace detail } // namespace detail
template<typename Container> template<typename Container>
struct container_construct_traits { struct container_construct_traits
public: : public sprout::detail::container_construct_traits_impl<Container>
typedef Container copied_type; {};
public:
template<typename Cont>
static SPROUT_CONSTEXPR copied_type
deep_copy(Cont&& cont) {
return sprout::forward<Cont>(cont);
}
template<typename... Args>
static SPROUT_CONSTEXPR copied_type
make(Args&&... args) {
return sprout::detail::default_make_container<Container>(sprout::forward<Args>(args)...);
}
template<typename Cont, typename... Args>
static SPROUT_CONSTEXPR copied_type
remake(Cont&& cont, typename sprout::container_traits<Container>::difference_type size, Args&&... args) {
return make(sprout::forward<Args>(args)...);
}
};
template<typename Container> template<typename Container>
struct container_construct_traits<Container const> struct container_construct_traits<Container const>
: public sprout::container_construct_traits<Container> : public sprout::container_construct_traits<Container>

View file

@ -513,6 +513,42 @@ namespace sprout {
, public sprout::detail::inherit_if_static_size<sprout::container_traits<Container> > , public sprout::detail::inherit_if_static_size<sprout::container_traits<Container> >
, public sprout::detail::container_nosy_fixed_size<sprout::container_traits<Container> > , public sprout::detail::container_nosy_fixed_size<sprout::container_traits<Container> >
{}; {};
//
// is_fixed_container
//
template<typename Container>
struct is_fixed_container
: public sprout::detail::has_static_size<sprout::container_traits<Container> >
{};
namespace detail {
//
// static_size_or_zero
//
template<typename Container, typename = void>
struct static_size_or_zero;
template<typename Container>
struct static_size_or_zero<
Container,
typename std::enable_if<sprout::is_fixed_container<sprout::container_traits<Container> >::value>::type
>
: public std::integral_constant<
typename sprout::container_traits<Container>::size_type,
sprout::container_traits<Container>::static_size
>
{};
template<typename Container>
struct static_size_or_zero<
Container,
typename std::enable_if<!sprout::is_fixed_container<sprout::container_traits<Container> >::value>::type
>
: public std::integral_constant<
typename sprout::container_traits<Container>::size_type,
0
>
{};
} // namespace sprout
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_CONTAINER_CONTAINER_TRAITS_HPP #endif // #ifndef SPROUT_CONTAINER_CONTAINER_TRAITS_HPP

View file

@ -0,0 +1,59 @@
#ifndef SPROUT_CONTAINER_SSCRISK_CEL_ARRAY_HPP
#define SPROUT_CONTAINER_SSCRISK_CEL_ARRAY_HPP
#include <sscrisk/cel/array.hpp>
#include <sprout/config.hpp>
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
# include <cstddef>
# include <type_traits>
# include <sprout/container/traits.hpp>
# include <sprout/iterator/index_iterator.hpp>
#endif
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
namespace sprout {
//
// container_traits
//
template<typename T, std::size_t N>
struct container_traits<sscrisk::cel::array<T, N> >
: public sprout::detail::container_traits_default<sscrisk::cel::array<T, N> >
{
public:
typedef sprout::index_iterator<sscrisk::cel::array<T, N>&> iterator;
typedef sprout::index_iterator<sscrisk::cel::array<T, N> const&> const_iterator;
};
} // namespace sprout
namespace sprout {
//
// range_begin
//
template<typename T, std::size_t N>
inline typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator
range_begin(sscrisk::cel::array<T, N>& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator(cont, 0);
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator
range_begin(sscrisk::cel::array<T, N> const& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator(cont, 0);
}
//
// range_end
//
template<typename T, std::size_t N>
inline typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator
range_end(sscrisk::cel::array<T, N>& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::iterator(cont, cont.size());
}
template<typename T, std::size_t N>
inline SPROUT_CONSTEXPR typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator
range_end(sscrisk::cel::array<T, N> const& cont) {
return typename sprout::container_traits<sscrisk::cel::array<T, N> >::const_iterator(cont, cont.size());
}
} // namespace sprout
#endif
#endif // #ifndef SPROUT_CONTAINER_SSCRISK_CEL_ARRAY_HPP

View file

@ -16,22 +16,24 @@ namespace sprout {
// pit // pit
// //
template<typename Container> template<typename Container>
class pit { class pit
: public sprout::container_traits_facade<Container>
{
public: public:
typedef Container container_type; typedef Container container_type;
typedef typename sprout::container_traits<container_type>::value_type value_type; typedef typename sprout::container_traits_facade<Container>::value_type value_type;
typedef typename sprout::container_traits<container_type>::reference reference; typedef typename sprout::container_traits_facade<Container>::reference reference;
typedef typename sprout::container_traits<container_type>::const_reference const_reference; typedef typename sprout::container_traits_facade<Container>::const_reference const_reference;
typedef typename sprout::value_iterator<reference> iterator; typedef typename sprout::value_iterator<reference> iterator;
typedef typename sprout::value_iterator<const_reference> const_iterator; typedef typename sprout::value_iterator<const_reference> const_iterator;
typedef typename sprout::container_traits<container_type>::size_type size_type; typedef typename sprout::container_traits_facade<Container>::size_type size_type;
typedef typename sprout::container_traits<container_type>::difference_type difference_type; typedef typename sprout::container_traits_facade<Container>::difference_type difference_type;
typedef typename sprout::container_traits<container_type>::pointer pointer; typedef typename sprout::container_traits_facade<Container>::pointer pointer;
typedef typename sprout::container_traits<container_type>::const_pointer const_pointer; typedef typename sprout::container_traits_facade<Container>::const_pointer const_pointer;
typedef typename sprout::reverse_iterator<iterator> reverse_iterator; typedef typename sprout::reverse_iterator<iterator> reverse_iterator;
typedef typename sprout::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename sprout::reverse_iterator<const_iterator> const_reverse_iterator;
public: public:
SPROUT_STATIC_CONSTEXPR size_type static_size = sprout::container_traits<container_type>::static_size; SPROUT_STATIC_CONSTEXPR size_type enumerable_size = sprout::detail::static_size_or_zero<sprout::container_traits_facade<Container> >::value;
public: public:
value_type elem; value_type elem;
public: public:
@ -43,10 +45,10 @@ namespace sprout {
} }
// iterators: // iterators:
iterator begin() { iterator begin() {
return iterator(elem, static_size); return iterator(elem, enumerable_size);
} }
SPROUT_CONSTEXPR const_iterator begin() const { SPROUT_CONSTEXPR const_iterator begin() const {
return const_iterator(elem, static_size); return const_iterator(elem, enumerable_size);
} }
iterator end() SPROUT_NOEXCEPT { iterator end() SPROUT_NOEXCEPT {
return iterator(elem, 0); return iterator(elem, 0);
@ -67,7 +69,7 @@ namespace sprout {
return const_reverse_iterator(begin()); return const_reverse_iterator(begin());
} }
SPROUT_CONSTEXPR const_iterator cbegin() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR const_iterator cbegin() const SPROUT_NOEXCEPT {
return const_iterator(elem, static_size); return const_iterator(elem, enumerable_size);
} }
SPROUT_CONSTEXPR const_iterator cend() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR const_iterator cend() const SPROUT_NOEXCEPT {
return const_iterator(elem, 0); return const_iterator(elem, 0);
@ -80,13 +82,13 @@ namespace sprout {
} }
// capacity: // capacity:
SPROUT_CONSTEXPR size_type size() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR size_type size() const SPROUT_NOEXCEPT {
return static_size; return enumerable_size;
} }
SPROUT_CONSTEXPR size_type max_size() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR size_type max_size() const SPROUT_NOEXCEPT {
return size(); return size();
} }
SPROUT_CONSTEXPR bool empty() const SPROUT_NOEXCEPT { SPROUT_CONSTEXPR bool empty() const SPROUT_NOEXCEPT {
return static_size == 0; return enumerable_size == 0;
} }
// element access: // element access:
reference operator[](size_type i) { reference operator[](size_type i) {
@ -127,7 +129,7 @@ namespace sprout {
} }
}; };
template<typename Container> template<typename Container>
SPROUT_CONSTEXPR_OR_CONST typename sprout::pit<Container>::size_type sprout::pit<Container>::static_size; SPROUT_CONSTEXPR_OR_CONST typename sprout::pit<Container>::size_type sprout::pit<Container>::enumerable_size;
// //
// swap // swap