1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2008.
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 // See http://www.boost.org/libs/container for documentation.
11 //////////////////////////////////////////////////////////////////////////////
13 #ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
14 #define BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP
16 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
20 #include <boost/interprocess/containers/container/detail/config_begin.hpp>
21 #include <boost/interprocess/containers/container/detail/workaround.hpp>
23 #include <boost/type_traits/has_trivial_copy.hpp>
24 #include <boost/type_traits/has_trivial_assign.hpp>
25 #include <boost/detail/no_exceptions_support.hpp>
26 #include <boost/get_pointer.hpp>
28 #include <boost/interprocess/containers/container/detail/type_traits.hpp>
29 #include <boost/interprocess/containers/container/detail/mpl.hpp>
30 #include <boost/interprocess/containers/container/detail/iterators.hpp>
36 namespace interprocess_container
{
38 #if !defined(BOOST_HAS_RVALUE_REFS)
40 struct has_own_construct_from_it
42 static const bool value
= false;
45 namespace containers_detail
{
47 template<class T
, class InpIt
>
48 inline void construct_in_place_impl(T
* dest
, const InpIt
&source
, containers_detail::true_
)
50 T::construct(dest
, *source
);
53 template<class T
, class InpIt
>
54 inline void construct_in_place_impl(T
* dest
, const InpIt
&source
, containers_detail::false_
)
56 new((void*)dest
)T(*source
);
59 } //namespace containers_detail {
61 template<class T
, class InpIt
>
62 inline void construct_in_place(T
* dest
, InpIt source
)
64 typedef containers_detail::bool_
<has_own_construct_from_it
<T
>::value
> boolean_t
;
65 containers_detail::construct_in_place_impl(dest
, source
, boolean_t());
69 template<class T
, class InpIt
>
70 inline void construct_in_place(T
* dest
, InpIt source
)
71 { ::new((void*)dest
)T(*source
); }
74 template<class T
, class U
, class D
>
75 inline void construct_in_place(T
*dest
, default_construct_iterator
<U
, D
>)
77 ::new((void*)dest
)T();
80 template<class T
, class U
, class E
>
81 inline void construct_in_place(T
*dest
, emplace_iterator
<U
, E
> ei
)
83 ei
.construct_in_place(dest
);
86 template<class InIt
, class OutIt
>
87 struct optimize_assign
89 static const bool value
= false;
93 struct optimize_assign
<const T
*, T
*>
95 static const bool value
= boost::has_trivial_assign
<T
>::value
;
99 struct optimize_assign
<T
*, T
*>
100 : public optimize_assign
<const T
*, T
*>
103 template<class InIt
, class OutIt
>
106 static const bool value
= false;
110 struct optimize_copy
<const T
*, T
*>
112 static const bool value
= boost::has_trivial_copy
<T
>::value
;
116 struct optimize_copy
<T
*, T
*>
117 : public optimize_copy
<const T
*, T
*>
120 template<class InIt
, class OutIt
> inline
121 OutIt
copy_n_dispatch(InIt first
, typename
std::iterator_traits
<InIt
>::difference_type length
, OutIt dest
, containers_detail::bool_
<false>)
123 for (; length
--; ++dest
, ++first
)
128 template<class T
> inline
129 T
*copy_n_dispatch(const T
*first
, typename
std::iterator_traits
<const T
*>::difference_type length
, T
*dest
, containers_detail::bool_
<true>)
131 std::size_t size
= length
*sizeof(T
);
132 return (static_cast<T
*>(std::memmove(dest
, first
, size
))) + size
;
135 template<class InIt
, class OutIt
> inline
136 OutIt
copy_n(InIt first
, typename
std::iterator_traits
<InIt
>::difference_type length
, OutIt dest
)
138 const bool do_optimized_assign
= optimize_assign
<InIt
, OutIt
>::value
;
139 return copy_n_dispatch(first
, length
, dest
, containers_detail::bool_
<do_optimized_assign
>());
142 template<class InIt
, class FwdIt
> inline
143 FwdIt uninitialized_copy_n_dispatch
145 typename
std::iterator_traits
<InIt
>::difference_type count
,
146 FwdIt dest
, containers_detail::bool_
<false>)
148 typedef typename
std::iterator_traits
<FwdIt
>::value_type value_type
;
149 //Save initial destination position
150 FwdIt dest_init
= dest
;
151 typename
std::iterator_traits
<InIt
>::difference_type new_count
= count
+1;
154 //Try to build objects
155 for (; --new_count
; ++dest
, ++first
){
156 construct_in_place(containers_detail::get_pointer(&*dest
), first
);
161 new_count
= count
- new_count
;
162 for (; new_count
--; ++dest_init
){
163 containers_detail::get_pointer(&*dest_init
)->~value_type();
170 template<class T
> inline
171 T
*uninitialized_copy_n_dispatch(const T
*first
, typename
std::iterator_traits
<const T
*>::difference_type length
, T
*dest
, containers_detail::bool_
<true>)
173 std::size_t size
= length
*sizeof(T
);
174 return (static_cast<T
*>(std::memmove(dest
, first
, size
))) + size
;
177 template<class InIt
, class FwdIt
> inline
178 FwdIt uninitialized_copy_n
180 typename
std::iterator_traits
<InIt
>::difference_type count
,
183 const bool do_optimized_copy
= optimize_copy
<InIt
, FwdIt
>::value
;
184 return uninitialized_copy_n_dispatch(first
, count
, dest
, containers_detail::bool_
<do_optimized_copy
>());
187 // uninitialized_copy_copy
188 // Copies [first1, last1) into [result, result + (last1 - first1)), and
189 // copies [first2, last2) into
190 // [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)).
191 template <class InpIt1
, class InpIt2
, class FwdIt
>
192 FwdIt uninitialized_copy_copy
193 (InpIt1 first1
, InpIt1 last1
, InpIt2 first2
, InpIt2 last2
, FwdIt result
)
195 typedef typename
std::iterator_traits
<FwdIt
>::value_type value_type
;
196 FwdIt mid
= std::uninitialized_copy(first1
, last1
, result
);
198 return std::uninitialized_copy(first2
, last2
, mid
);
201 for(;result
!= mid
; ++result
){
202 containers_detail::get_pointer(&*result
)->~value_type();
209 } //namespace interprocess_container {
210 } //namespace boost {
212 #include <boost/interprocess/containers/container/detail/config_end.hpp>
214 #endif //#ifndef BOOST_CONTAINERS_DETAIL_ALGORITHMS_HPP