]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/index/detail/varray_detail.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / geometry / index / detail / varray_detail.hpp
1 // Boost.Geometry
2 //
3 // varray details
4 //
5 // Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
6 // Copyright (c) 2011-2013 Andrew Hundt.
7 //
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11
12 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
13 #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
14
15 #include <cstddef>
16 #include <cstring>
17 #include <memory>
18 #include <limits>
19
20 #include <boost/mpl/if.hpp>
21 #include <boost/mpl/and.hpp>
22 #include <boost/mpl/or.hpp>
23 #include <boost/mpl/int.hpp>
24
25 #include <boost/type_traits/is_same.hpp>
26 #include <boost/type_traits/remove_const.hpp>
27 #include <boost/type_traits/remove_reference.hpp>
28 #include <boost/type_traits/has_trivial_assign.hpp>
29 #include <boost/type_traits/has_trivial_copy.hpp>
30 #include <boost/type_traits/has_trivial_constructor.hpp>
31 #include <boost/type_traits/has_trivial_destructor.hpp>
32 #include <boost/type_traits/has_trivial_move_constructor.hpp>
33 #include <boost/type_traits/has_trivial_move_assign.hpp>
34 //#include <boost/type_traits/has_nothrow_constructor.hpp>
35 //#include <boost/type_traits/has_nothrow_copy.hpp>
36 //#include <boost/type_traits/has_nothrow_assign.hpp>
37 //#include <boost/type_traits/has_nothrow_destructor.hpp>
38
39 #include <boost/detail/no_exceptions_support.hpp>
40 #include <boost/config.hpp>
41 #include <boost/move/move.hpp>
42 #include <boost/core/addressof.hpp>
43 #include <boost/iterator/iterator_traits.hpp>
44
45 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
46 #include <boost/move/detail/fwd_macros.hpp>
47 #endif
48
49 // TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
50
51 #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
52 #include <vector>
53 #include <boost/container/vector.hpp>
54 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
55
56 namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail {
57
58 template <typename I>
59 struct are_elements_contiguous : boost::is_pointer<I>
60 {};
61
62 // EXPERIMENTAL - not finished
63 // Conditional setup - mark vector iterators defined in known implementations
64 // as iterators pointing to contiguous ranges
65
66 #if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
67
68 template <typename Pointer>
69 struct are_elements_contiguous<
70 boost::container::container_detail::vector_const_iterator<Pointer>
71 > : boost::true_type
72 {};
73
74 template <typename Pointer>
75 struct are_elements_contiguous<
76 boost::container::container_detail::vector_iterator<Pointer>
77 > : boost::true_type
78 {};
79
80 #if defined(BOOST_DINKUMWARE_STDLIB)
81
82 template <typename T>
83 struct are_elements_contiguous<
84 std::_Vector_const_iterator<T>
85 > : boost::true_type
86 {};
87
88 template <typename T>
89 struct are_elements_contiguous<
90 std::_Vector_iterator<T>
91 > : boost::true_type
92 {};
93
94 #elif defined(BOOST_GNU_STDLIB)
95
96 template <typename P, typename T, typename A>
97 struct are_elements_contiguous<
98 __gnu_cxx::__normal_iterator<P, std::vector<T, A> >
99 > : boost::true_type
100 {};
101
102 #elif defined(_LIBCPP_VERSION)
103
104 // TODO - test it first
105 //template <typename P>
106 //struct are_elements_contiguous<
107 // __wrap_iter<P>
108 //> : boost::true_type
109 //{};
110
111 #else // OTHER_STDLIB
112
113 // TODO - add other iterators implementations
114
115 #endif // STDLIB
116
117 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
118
119 // True if iterator values are the same and both iterators points to the ranges of contiguous elements
120
121 template <typename I, typename O>
122 struct are_corresponding :
123 ::boost::mpl::and_<
124 ::boost::is_same<
125 ::boost::remove_const<
126 typename ::boost::iterator_value<I>::type
127 >,
128 ::boost::remove_const<
129 typename ::boost::iterator_value<O>::type
130 >
131 >,
132 are_elements_contiguous<I>,
133 are_elements_contiguous<O>
134 >
135 {};
136
137 template <typename I, typename V>
138 struct is_corresponding_value :
139 ::boost::is_same<
140 ::boost::remove_const<
141 typename ::boost::iterator_value<I>::type
142 >,
143 ::boost::remove_const<V>
144 >
145 {};
146
147 // destroy(I, I)
148
149 template <typename I>
150 void destroy_dispatch(I /*first*/, I /*last*/,
151 boost::true_type const& /*has_trivial_destructor*/)
152 {}
153
154 template <typename I>
155 void destroy_dispatch(I first, I last,
156 boost::false_type const& /*has_trivial_destructor*/)
157 {
158 typedef typename boost::iterator_value<I>::type value_type;
159 for ( ; first != last ; ++first )
160 first->~value_type();
161 }
162
163 template <typename I>
164 void destroy(I first, I last)
165 {
166 typedef typename boost::iterator_value<I>::type value_type;
167 destroy_dispatch(first, last, has_trivial_destructor<value_type>());
168 }
169
170 // destroy(I)
171
172 template <typename I>
173 void destroy_dispatch(I /*pos*/,
174 boost::true_type const& /*has_trivial_destructor*/)
175 {}
176
177 template <typename I>
178 void destroy_dispatch(I pos,
179 boost::false_type const& /*has_trivial_destructor*/)
180 {
181 typedef typename boost::iterator_value<I>::type value_type;
182 pos->~value_type();
183 }
184
185 template <typename I>
186 void destroy(I pos)
187 {
188 typedef typename boost::iterator_value<I>::type value_type;
189 destroy_dispatch(pos, has_trivial_destructor<value_type>());
190 }
191
192 // copy(I, I, O)
193
194 template <typename I, typename O>
195 inline O copy_dispatch(I first, I last, O dst,
196 boost::mpl::bool_<true> const& /*use_memmove*/)
197 {
198 typedef typename boost::iterator_value<I>::type value_type;
199 typename boost::iterator_difference<I>::type d = std::distance(first, last);
200
201 ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
202 return dst + d;
203 }
204
205 template <typename I, typename O>
206 inline O copy_dispatch(I first, I last, O dst,
207 boost::mpl::bool_<false> const& /*use_memmove*/)
208 {
209 return std::copy(first, last, dst); // may throw
210 }
211
212 template <typename I, typename O>
213 inline O copy(I first, I last, O dst)
214 {
215 typedef typename
216 ::boost::mpl::and_<
217 are_corresponding<I, O>,
218 ::boost::has_trivial_assign<
219 typename ::boost::iterator_value<O>::type
220 >
221 >::type
222 use_memmove;
223
224 return copy_dispatch(first, last, dst, use_memmove()); // may throw
225 }
226
227 // uninitialized_copy(I, I, O)
228
229 template <typename I, typename O>
230 inline
231 O uninitialized_copy_dispatch(I first, I last, O dst,
232 boost::mpl::bool_<true> const& /*use_memcpy*/)
233 {
234 typedef typename boost::iterator_value<I>::type value_type;
235 typename boost::iterator_difference<I>::type d = std::distance(first, last);
236
237 ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
238 return dst + d;
239 }
240
241 template <typename I, typename F>
242 inline
243 F uninitialized_copy_dispatch(I first, I last, F dst,
244 boost::mpl::bool_<false> const& /*use_memcpy*/)
245 {
246 return std::uninitialized_copy(first, last, dst); // may throw
247 }
248
249 template <typename I, typename F>
250 inline
251 F uninitialized_copy(I first, I last, F dst)
252 {
253 typedef typename
254 ::boost::mpl::and_<
255 are_corresponding<I, F>,
256 ::boost::has_trivial_copy<
257 typename ::boost::iterator_value<F>::type
258 >
259 >::type
260 use_memcpy;
261
262 return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
263 }
264
265 // uninitialized_move(I, I, O)
266
267 template <typename I, typename O>
268 inline
269 O uninitialized_move_dispatch(I first, I last, O dst,
270 boost::mpl::bool_<true> const& /*use_memcpy*/)
271 {
272 typedef typename boost::iterator_value<I>::type value_type;
273 typename boost::iterator_difference<I>::type d = std::distance(first, last);
274
275 ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
276 return dst + d;
277 }
278
279 template <typename I, typename O>
280 inline
281 O uninitialized_move_dispatch(I first, I last, O dst,
282 boost::mpl::bool_<false> const& /*use_memcpy*/)
283 {
284 //return boost::uninitialized_move(first, last, dst); // may throw
285
286 O o = dst;
287
288 BOOST_TRY
289 {
290 typedef typename std::iterator_traits<O>::value_type value_type;
291 for (; first != last; ++first, ++o )
292 new (boost::addressof(*o)) value_type(boost::move(*first));
293 }
294 BOOST_CATCH(...)
295 {
296 destroy(dst, o);
297 BOOST_RETHROW;
298 }
299 BOOST_CATCH_END
300
301 return dst;
302 }
303
304 template <typename I, typename O>
305 inline
306 O uninitialized_move(I first, I last, O dst)
307 {
308 typedef typename
309 ::boost::mpl::and_<
310 are_corresponding<I, O>,
311 ::boost::has_trivial_copy<
312 typename ::boost::iterator_value<O>::type
313 >
314 >::type
315 use_memcpy;
316
317 return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw
318 }
319
320 // TODO - move uses memmove - implement 2nd version using memcpy?
321
322 // move(I, I, O)
323
324 template <typename I, typename O>
325 inline
326 O move_dispatch(I first, I last, O dst,
327 boost::mpl::bool_<true> const& /*use_memmove*/)
328 {
329 typedef typename boost::iterator_value<I>::type value_type;
330 typename boost::iterator_difference<I>::type d = std::distance(first, last);
331
332 ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
333 return dst + d;
334 }
335
336 template <typename I, typename O>
337 inline
338 O move_dispatch(I first, I last, O dst,
339 boost::mpl::bool_<false> const& /*use_memmove*/)
340 {
341 return boost::move(first, last, dst); // may throw
342 }
343
344 template <typename I, typename O>
345 inline
346 O move(I first, I last, O dst)
347 {
348 typedef typename
349 ::boost::mpl::and_<
350 are_corresponding<I, O>,
351 ::boost::has_trivial_assign<
352 typename ::boost::iterator_value<O>::type
353 >
354 >::type
355 use_memmove;
356
357 return move_dispatch(first, last, dst, use_memmove()); // may throw
358 }
359
360 // move_backward(BDI, BDI, BDO)
361
362 template <typename BDI, typename BDO>
363 inline
364 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
365 boost::mpl::bool_<true> const& /*use_memmove*/)
366 {
367 typedef typename boost::iterator_value<BDI>::type value_type;
368 typename boost::iterator_difference<BDI>::type d = std::distance(first, last);
369
370 BDO foo(dst - d);
371 ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d);
372 return foo;
373 }
374
375 template <typename BDI, typename BDO>
376 inline
377 BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
378 boost::mpl::bool_<false> const& /*use_memmove*/)
379 {
380 return boost::move_backward(first, last, dst); // may throw
381 }
382
383 template <typename BDI, typename BDO>
384 inline
385 BDO move_backward(BDI first, BDI last, BDO dst)
386 {
387 typedef typename
388 ::boost::mpl::and_<
389 are_corresponding<BDI, BDO>,
390 ::boost::has_trivial_assign<
391 typename ::boost::iterator_value<BDO>::type
392 >
393 >::type
394 use_memmove;
395
396 return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
397 }
398
399 template <typename T>
400 struct has_nothrow_move : public
401 ::boost::mpl::or_<
402 boost::mpl::bool_<
403 ::boost::has_nothrow_move<
404 typename ::boost::remove_const<T>::type
405 >::value
406 >,
407 boost::mpl::bool_<
408 ::boost::has_nothrow_move<T>::value
409 >
410 >
411 {};
412
413 // uninitialized_move_if_noexcept(I, I, O)
414
415 template <typename I, typename O>
416 inline
417 O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
418 { return varray_detail::uninitialized_move(first, last, dst); }
419
420 template <typename I, typename O>
421 inline
422 O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
423 { return varray_detail::uninitialized_copy(first, last, dst); }
424
425 template <typename I, typename O>
426 inline
427 O uninitialized_move_if_noexcept(I first, I last, O dst)
428 {
429 typedef typename has_nothrow_move<
430 typename ::boost::iterator_value<O>::type
431 >::type use_move;
432
433 return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
434 }
435
436 // move_if_noexcept(I, I, O)
437
438 template <typename I, typename O>
439 inline
440 O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
441 { return move(first, last, dst); }
442
443 template <typename I, typename O>
444 inline
445 O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
446 { return copy(first, last, dst); }
447
448 template <typename I, typename O>
449 inline
450 O move_if_noexcept(I first, I last, O dst)
451 {
452 typedef typename has_nothrow_move<
453 typename ::boost::iterator_value<O>::type
454 >::type use_move;
455
456 return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
457 }
458
459 // uninitialized_fill(I, I)
460
461 template <typename I>
462 inline
463 void uninitialized_fill_dispatch(I /*first*/, I /*last*/,
464 boost::true_type const& /*has_trivial_constructor*/,
465 boost::true_type const& /*disable_trivial_init*/)
466 {}
467
468 template <typename I>
469 inline
470 void uninitialized_fill_dispatch(I first, I last,
471 boost::true_type const& /*has_trivial_constructor*/,
472 boost::false_type const& /*disable_trivial_init*/)
473 {
474 typedef typename boost::iterator_value<I>::type value_type;
475 for ( ; first != last ; ++first )
476 new (boost::addressof(*first)) value_type();
477 }
478
479 template <typename I, typename DisableTrivialInit>
480 inline
481 void uninitialized_fill_dispatch(I first, I last,
482 boost::false_type const& /*has_trivial_constructor*/,
483 DisableTrivialInit const& /*not_used*/)
484 {
485 typedef typename boost::iterator_value<I>::type value_type;
486 I it = first;
487
488 BOOST_TRY
489 {
490 for ( ; it != last ; ++it )
491 new (boost::addressof(*it)) value_type(); // may throw
492 }
493 BOOST_CATCH(...)
494 {
495 destroy(first, it);
496 BOOST_RETHROW;
497 }
498 BOOST_CATCH_END
499 }
500
501 template <typename I, typename DisableTrivialInit>
502 inline
503 void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
504 {
505 typedef typename boost::iterator_value<I>::type value_type;
506 uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
507 }
508
509 // construct(I)
510
511 template <typename I>
512 inline
513 void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I /*pos*/)
514 {}
515
516 template <typename I>
517 inline
518 void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
519 {
520 typedef typename ::boost::iterator_value<I>::type value_type;
521 new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
522 }
523
524 template <typename DisableTrivialInit, typename I>
525 inline
526 void construct(DisableTrivialInit const&, I pos)
527 {
528 typedef typename ::boost::iterator_value<I>::type value_type;
529 typedef typename ::boost::mpl::and_<
530 boost::has_trivial_constructor<value_type>,
531 DisableTrivialInit
532 >::type dont_init;
533
534 construct_dispatch(dont_init(), pos); // may throw
535 }
536
537 // construct(I, V)
538
539 template <typename I, typename V>
540 inline
541 void construct_copy_dispatch(I pos, V const& v,
542 boost::mpl::bool_<true> const& /*use_memcpy*/)
543 {
544 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
545 }
546
547 template <typename I, typename P>
548 inline
549 void construct_copy_dispatch(I pos, P const& p,
550 boost::mpl::bool_<false> const& /*use_memcpy*/)
551 {
552 typedef typename boost::iterator_value<I>::type V;
553 new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
554 }
555
556 template <typename DisableTrivialInit, typename I, typename P>
557 inline
558 void construct(DisableTrivialInit const&,
559 I pos, P const& p)
560 {
561 typedef typename
562 ::boost::mpl::and_<
563 is_corresponding_value<I, P>,
564 ::boost::has_trivial_copy<P>
565 >::type
566 use_memcpy;
567
568 construct_copy_dispatch(pos, p, use_memcpy()); // may throw
569 }
570
571 // Needed by push_back(V &&)
572
573 template <typename I, typename V>
574 inline
575 void construct_move_dispatch(I pos, V const& v,
576 boost::mpl::bool_<true> const& /*use_memcpy*/)
577 {
578 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
579 }
580
581 template <typename I, typename P>
582 inline
583 void construct_move_dispatch(I pos, BOOST_RV_REF(P) p,
584 boost::mpl::bool_<false> const& /*use_memcpy*/)
585 {
586 typedef typename boost::iterator_value<I>::type V;
587 new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
588 }
589
590 template <typename DisableTrivialInit, typename I, typename P>
591 inline
592 void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
593 {
594 typedef typename
595 ::boost::mpl::and_<
596 is_corresponding_value<I, P>,
597 ::boost::has_trivial_move_constructor<P>
598 >::type
599 use_memcpy;
600
601 construct_move_dispatch(pos, ::boost::move(p), use_memcpy()); // may throw
602 }
603
604 // Needed by emplace_back() and emplace()
605
606 #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
607 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
608
609 template <typename DisableTrivialInit, typename I, class ...Args>
610 inline
611 void construct(DisableTrivialInit const&,
612 I pos,
613 BOOST_FWD_REF(Args) ...args)
614 {
615 typedef typename boost::iterator_value<I>::type V;
616 new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
617 }
618
619 #else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
620
621 // BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 const& p0
622 // !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0
623 // which means that version with one parameter may take V const& v
624
625 #define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT(N) \
626 template <typename DisableTrivialInit, typename I, typename P BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
627 inline \
628 void construct(DisableTrivialInit const&, \
629 I pos, \
630 BOOST_FWD_REF(P) p \
631 BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
632 { \
633 typedef typename boost::iterator_value<I>::type V; \
634 new \
635 (static_cast<void*>(boost::addressof(*pos))) \
636 V(boost::forward<P>(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/ \
637 } \
638
639 BOOST_MOVE_ITERATE_1TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT)
640 #undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT
641
642 #endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
643 #endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
644
645 // assign(I, V)
646
647 template <typename I, typename V>
648 inline
649 void assign_copy_dispatch(I pos, V const& v,
650 boost::mpl::bool_<true> const& /*use_memcpy*/)
651 {
652 // TODO - use memmove here?
653 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
654 }
655
656 template <typename I, typename V>
657 inline
658 void assign_copy_dispatch(I pos, V const& v,
659 boost::mpl::bool_<false> const& /*use_memcpy*/)
660 {
661 *pos = v; // may throw
662 }
663
664 template <typename I, typename V>
665 inline
666 void assign(I pos, V const& v)
667 {
668 typedef typename
669 ::boost::mpl::and_<
670 is_corresponding_value<I, V>,
671 ::boost::has_trivial_assign<V>
672 >::type
673 use_memcpy;
674
675 assign_copy_dispatch(pos, v, use_memcpy()); // may throw
676 }
677
678 template <typename I, typename V>
679 inline
680 void assign_move_dispatch(I pos, V const& v,
681 boost::mpl::bool_<true> const& /*use_memcpy*/)
682 {
683 // TODO - use memmove here?
684 ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
685 }
686
687 template <typename I, typename V>
688 inline
689 void assign_move_dispatch(I pos, BOOST_RV_REF(V) v,
690 boost::mpl::bool_<false> const& /*use_memcpy*/)
691 {
692 *pos = boost::move(v); // may throw
693 }
694
695 template <typename I, typename V>
696 inline
697 void assign(I pos, BOOST_RV_REF(V) v)
698 {
699 typedef typename
700 ::boost::mpl::and_<
701 is_corresponding_value<I, V>,
702 ::boost::has_trivial_move_assign<V>
703 >::type
704 use_memcpy;
705
706 assign_move_dispatch(pos, ::boost::move(v), use_memcpy());
707 }
708
709 // uninitialized_copy_s
710
711 template <typename I, typename F>
712 inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count)
713 {
714 std::size_t count = 0;
715 F it = dest;
716
717 BOOST_TRY
718 {
719 for ( ; first != last ; ++it, ++first, ++count )
720 {
721 if ( max_count <= count )
722 return (std::numeric_limits<std::size_t>::max)();
723
724 // dummy 0 as DisableTrivialInit
725 construct(0, it, *first); // may throw
726 }
727 }
728 BOOST_CATCH(...)
729 {
730 destroy(dest, it);
731 BOOST_RETHROW;
732 }
733 BOOST_CATCH_END
734
735 return count;
736 }
737
738 // scoped_destructor
739
740 template<class T>
741 class scoped_destructor
742 {
743 public:
744 scoped_destructor(T * ptr) : m_ptr(ptr) {}
745
746 ~scoped_destructor()
747 {
748 if(m_ptr)
749 destroy(m_ptr);
750 }
751
752 void release() { m_ptr = 0; }
753
754 private:
755 T * m_ptr;
756 };
757
758 }}}}} // namespace boost::geometry::index::detail::varray_detail
759
760 #endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP