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