|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84889 - in branches/release: boost/geometry boost/geometry/algorithms boost/geometry/arithmetic boost/geometry/core boost/geometry/geometries boost/geometry/index boost/geometry/index/detail boost/geometry/index/detail/algorithms boost/geometry/index/detail/rtree boost/geometry/index/detail/rtree/linear boost/geometry/index/detail/rtree/node boost/geometry/index/detail/rtree/quadratic boost/geometry/index/detail/rtree/rstar boost/geometry/index/detail/rtree/utilities boost/geometry/index/detail/rtree/visitors boost/geometry/io boost/geometry/io/dsv boost/geometry/iterators boost/geometry/multi boost/geometry/policies boost/geometry/strategies boost/geometry/util boost/geometry/views libs/geometry/doc libs/geometry/doc/concept libs/geometry/doc/doxy libs/geometry/doc/doxy/doxygen_input/groups libs/geometry/doc/generated libs/geometry/doc/html libs/geometry/doc/html/img/index/rtree libs/geometry/doc/index libs/geometry/doc/index/rtree libs/geometry/doc/refer ence libs/geometry/doc/src libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk libs/geometry/example libs/geometry/index libs/geometry/index/example libs/geometry/index/test libs/geometry/index/test/rtree libs/geometry/index/test/rtree/exceptions libs/geometry/test
From: barend.gehrels_at_[hidden]
Date: 2013-06-23 16:59:55
Author: barendgehrels
Date: 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013)
New Revision: 84889
URL: http://svn.boost.org/trac/boost/changeset/84889
Log:
[geometry] merged for 1.54 release
Added:
branches/release/boost/geometry/index/detail/algorithms/bounds.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/algorithms/bounds.hpp
branches/release/boost/geometry/index/detail/rtree/pack_create.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/pack_create.hpp
branches/release/boost/geometry/index/detail/rtree/utilities/
- copied from r84886, trunk/boost/geometry/index/detail/rtree/utilities/
branches/release/boost/geometry/index/detail/varray_detail.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/varray_detail.hpp
branches/release/libs/geometry/doc/html/img/index/rtree/build_non_ovl.png
- copied unchanged from r84886, trunk/libs/geometry/doc/html/img/index/rtree/build_non_ovl.png
branches/release/libs/geometry/doc/html/img/index/rtree/build_ovl.png
- copied unchanged from r84886, trunk/libs/geometry/doc/html/img/index/rtree/build_ovl.png
branches/release/libs/geometry/doc/html/img/index/rtree/bulk.png
- copied unchanged from r84886, trunk/libs/geometry/doc/html/img/index/rtree/bulk.png
branches/release/libs/geometry/doc/html/img/index/rtree/query_non_ovl.png
- copied unchanged from r84886, trunk/libs/geometry/doc/html/img/index/rtree/query_non_ovl.png
branches/release/libs/geometry/doc/html/img/index/rtree/query_ovl.png
- copied unchanged from r84886, trunk/libs/geometry/doc/html/img/index/rtree/query_ovl.png
branches/release/libs/geometry/index/example/Jamfile.v2
- copied unchanged from r84886, trunk/libs/geometry/index/example/Jamfile.v2
branches/release/libs/geometry/index/test/movable.hpp
- copied unchanged from r84886, trunk/libs/geometry/index/test/movable.hpp
branches/release/libs/geometry/index/test/varray_old.cpp
- copied unchanged from r84886, trunk/libs/geometry/index/test/varray_old.cpp
branches/release/libs/geometry/index/test/varray_test.hpp
- copied unchanged from r84886, trunk/libs/geometry/index/test/varray_test.hpp
Replaced:
branches/release/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp
branches/release/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp
branches/release/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp
branches/release/boost/geometry/index/detail/rtree/utilities/print.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/utilities/print.hpp
branches/release/boost/geometry/index/detail/rtree/utilities/statistics.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/utilities/statistics.hpp
branches/release/boost/geometry/index/detail/rtree/utilities/view.hpp
- copied unchanged from r84886, trunk/boost/geometry/index/detail/rtree/utilities/view.hpp
Deleted:
branches/release/boost/geometry/index/detail/indexable.hpp
branches/release/boost/geometry/index/detail/rtree/visitors/are_boxes_ok.hpp
branches/release/boost/geometry/index/detail/rtree/visitors/are_levels_ok.hpp
branches/release/boost/geometry/index/detail/rtree/visitors/gl_draw.hpp
branches/release/boost/geometry/index/detail/rtree/visitors/print.hpp
Properties modified:
branches/release/boost/geometry/algorithms/ (props changed)
branches/release/boost/geometry/arithmetic/ (props changed)
branches/release/boost/geometry/core/ (props changed)
branches/release/boost/geometry/geometries/ (props changed)
branches/release/boost/geometry/geometry.hpp (props changed)
branches/release/boost/geometry/index/ (props changed)
branches/release/boost/geometry/io/ (props changed)
branches/release/boost/geometry/io/dsv/ (props changed)
branches/release/boost/geometry/iterators/ (props changed)
branches/release/boost/geometry/multi/ (props changed)
branches/release/boost/geometry/policies/ (props changed)
branches/release/boost/geometry/strategies/ (props changed)
branches/release/boost/geometry/util/ (props changed)
branches/release/boost/geometry/views/ (props changed)
branches/release/libs/geometry/doc/ (props changed)
branches/release/libs/geometry/doc/Jamfile.v2 (props changed)
branches/release/libs/geometry/doc/about_documentation.qbk (props changed)
branches/release/libs/geometry/doc/acknowledgments.qbk (props changed)
branches/release/libs/geometry/doc/compiling.qbk (props changed)
branches/release/libs/geometry/doc/concept/ (props changed)
branches/release/libs/geometry/doc/copyright_note_policy.txt (props changed)
branches/release/libs/geometry/doc/design_rationale.qbk (props changed)
branches/release/libs/geometry/doc/doxy/ (props changed)
branches/release/libs/geometry/doc/generated/ (props changed)
branches/release/libs/geometry/doc/geometry.qbk (contents, props changed)
branches/release/libs/geometry/doc/html/ (props changed)
branches/release/libs/geometry/doc/imports.qbk (props changed)
branches/release/libs/geometry/doc/index/ (props changed)
branches/release/libs/geometry/doc/introduction.qbk (props changed)
branches/release/libs/geometry/doc/make_qbk.py (props changed)
branches/release/libs/geometry/doc/matrix.qbk (props changed)
branches/release/libs/geometry/doc/quickref.xml (props changed)
branches/release/libs/geometry/doc/quickstart.qbk (props changed)
branches/release/libs/geometry/doc/readme.txt (props changed)
branches/release/libs/geometry/doc/reference/ (props changed)
branches/release/libs/geometry/doc/reference.qbk (props changed)
branches/release/libs/geometry/doc/release_notes.qbk (contents, props changed)
branches/release/libs/geometry/doc/src/ (props changed)
branches/release/libs/geometry/example/ (props changed)
branches/release/libs/geometry/index/ (props changed)
branches/release/libs/geometry/index/example/ (props changed)
branches/release/libs/geometry/index/test/ (props changed)
branches/release/libs/geometry/test/ (props changed)
Text files modified:
branches/release/boost/geometry/algorithms/buffer.hpp | 7
branches/release/boost/geometry/algorithms/convex_hull.hpp | 4
branches/release/boost/geometry/algorithms/covered_by.hpp | 2
branches/release/boost/geometry/core/exterior_ring.hpp | 2
branches/release/boost/geometry/index/detail/algorithms/bounds.hpp | 41
branches/release/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp | 8
branches/release/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp | 8
branches/release/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp | 8
branches/release/boost/geometry/index/detail/algorithms/content.hpp | 24
branches/release/boost/geometry/index/detail/algorithms/diff_abs.hpp | 17
branches/release/boost/geometry/index/detail/algorithms/is_valid.hpp | 12
branches/release/boost/geometry/index/detail/algorithms/margin.hpp | 49
branches/release/boost/geometry/index/detail/algorithms/minmaxdist.hpp | 8
branches/release/boost/geometry/index/detail/algorithms/path_intersection.hpp | 12
branches/release/boost/geometry/index/detail/algorithms/segment_intersection.hpp | 20
branches/release/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp | 2
branches/release/boost/geometry/index/detail/assert.hpp | 3
branches/release/boost/geometry/index/detail/config_begin.hpp | 6
/dev/null | 139 --
branches/release/boost/geometry/index/detail/predicates.hpp | 555 +++------
branches/release/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp | 200 ++
branches/release/boost/geometry/index/detail/rtree/node/node.hpp | 4
branches/release/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp | 10
branches/release/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp | 6
branches/release/boost/geometry/index/detail/rtree/pack_create.hpp | 376 ++++++
branches/release/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp | 20
branches/release/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp | 284 ++++
branches/release/boost/geometry/index/detail/rtree/rstar/insert.hpp | 2
branches/release/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp | 59
branches/release/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp | 140 ++
branches/release/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp | 109 +
branches/release/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp | 223 ++++
branches/release/boost/geometry/index/detail/rtree/utilities/print.hpp | 203 +++
branches/release/boost/geometry/index/detail/rtree/utilities/statistics.hpp | 105 +
branches/release/boost/geometry/index/detail/rtree/utilities/view.hpp | 61 +
/dev/null | 144 --
/dev/null | 114 --
/dev/null | 221 ---
/dev/null | 197 ---
branches/release/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp | 2
branches/release/boost/geometry/index/detail/varray.hpp | 2211 +++++++++++++++++++++++++++++++--------
branches/release/boost/geometry/index/detail/varray_detail.hpp | 714 ++++++++++++
branches/release/boost/geometry/index/parameters.hpp | 2
branches/release/boost/geometry/index/predicates.hpp | 244 ++--
branches/release/boost/geometry/index/rtree.hpp | 70
branches/release/boost/geometry/strategies/side_info.hpp | 10
branches/release/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp | 2
branches/release/libs/geometry/doc/geometry.qbk | 2
branches/release/libs/geometry/doc/html/index.html | 22
branches/release/libs/geometry/doc/index/introduction.qbk | 69
branches/release/libs/geometry/doc/index/rtree/creation.qbk | 2
branches/release/libs/geometry/doc/index/rtree/experimental.qbk | 14
branches/release/libs/geometry/doc/index/rtree/introduction.qbk | 4
branches/release/libs/geometry/doc/index/rtree/query.qbk | 2
branches/release/libs/geometry/doc/index/rtree/quickstart.qbk | 2
branches/release/libs/geometry/doc/release_notes.qbk | 1
branches/release/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp | 12
branches/release/libs/geometry/index/example/Jamfile.v2 | 54
branches/release/libs/geometry/index/example/benchmark2.cpp | 3
branches/release/libs/geometry/index/example/benchmark_experimental.cpp | 102 +
branches/release/libs/geometry/index/example/glut_vis.cpp | 142 +
branches/release/libs/geometry/index/test/Jamfile.v2 | 3
branches/release/libs/geometry/index/test/movable.hpp | 92 +
branches/release/libs/geometry/index/test/rtree/exceptions/test_exceptions.hpp | 27
branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing.hpp | 6
branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing_node.hpp | 24
branches/release/libs/geometry/index/test/rtree/test_rtree.hpp | 128 ++
branches/release/libs/geometry/index/test/varray.cpp | 606 ++++++++--
branches/release/libs/geometry/index/test/varray_old.cpp | 490 ++++++++
branches/release/libs/geometry/index/test/varray_test.hpp | 97 +
70 files changed, 6262 insertions(+), 2302 deletions(-)
Modified: branches/release/boost/geometry/algorithms/buffer.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/buffer.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/algorithms/buffer.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -145,11 +145,12 @@
\tparam Distance \tparam_numeric
\param geometry \param_geometry
\param distance The distance to be used for the buffer
-\param chord_length (optional) The length of the chord's in the generated arcs around points or bends
+\param chord_length (optional) The length of the chord's in the generated arcs
+ around points or bends
\return \return_calc{buffer}
*/
-template <typename Output, typename Input, typename T>
-Output return_buffer(Input const& geometry, T const& distance, T const& chord_length = -1)
+template <typename Output, typename Input, typename Distance>
+Output return_buffer(Input const& geometry, Distance const& distance, Distance const& chord_length = -1)
{
concept::check<Input const>();
concept::check<Output>();
Modified: branches/release/boost/geometry/algorithms/convex_hull.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/convex_hull.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/algorithms/convex_hull.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -168,8 +168,8 @@
\brief \brief_calc{convex hull}
\ingroup convex_hull
\details \details_calc{convex_hull,convex hull}.
-\tparam Geometry1 \tparam_geometry
-\tparam Geometry2 \tparam_geometry
+\tparam Geometry the input geometry type
+\tparam OutputGeometry the output geometry type
\param geometry \param_geometry, input geometry
\param hull \param_geometry \param_set{convex hull}
Modified: branches/release/boost/geometry/algorithms/covered_by.hpp
==============================================================================
--- branches/release/boost/geometry/algorithms/covered_by.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/algorithms/covered_by.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -47,6 +47,7 @@
template <typename Strategy>
static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
{
+ ::boost::ignore_unused_variable_warning(strategy);
return strategy.apply(point, box);
}
};
@@ -58,6 +59,7 @@
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
{
assert_dimension_equal<Box1, Box2>();
+ ::boost::ignore_unused_variable_warning(strategy);
return strategy.apply(box1, box2);
}
};
Modified: branches/release/boost/geometry/core/exterior_ring.hpp
==============================================================================
--- branches/release/boost/geometry/core/exterior_ring.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/core/exterior_ring.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -101,7 +101,7 @@
\brief Function to get the exterior_ring ring of a polygon
\ingroup exterior_ring
\note OGC compliance: instead of ExteriorRing
- \tparam P polygon type
+ \tparam Polygon polygon type
\param polygon the polygon to get the exterior ring from
\return a reference to the exterior ring
*/
Copied: branches/release/boost/geometry/index/detail/algorithms/bounds.hpp (from r84886, trunk/boost/geometry/index/detail/algorithms/bounds.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/algorithms/bounds.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/algorithms/bounds.hpp)
@@ -0,0 +1,41 @@
+// Boost.Geometry Index
+//
+// n-dimensional bounds
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace dispatch {
+
+template <typename Geometry,
+ typename Bounds,
+ typename TagGeometry = typename geometry::tag<Geometry>::type,
+ typename TagBounds = typename geometry::tag<Bounds>::type>
+struct bounds
+{
+ static inline void apply(Geometry const& g, Bounds & b)
+ {
+ geometry::convert(g, b);
+ }
+};
+
+} // namespace dispatch
+
+template <typename Geometry, typename Bounds>
+inline void bounds(Geometry const& g, Bounds & b)
+{
+ concept::check_concepts_and_equal_dimensions<Geometry const, Bounds>();
+ dispatch::bounds<Geometry, Bounds>::apply(g, b);
+}
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
Modified: branches/release/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -42,8 +42,8 @@
inline static result_type apply(Point const& pt, BoxIndexable const& i)
{
- typedef typename index::detail::traits::coordinate_type<Point>::type point_coord_t;
- typedef typename index::detail::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
+ typedef typename coordinate_type<Point>::type point_coord_t;
+ typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -65,9 +65,9 @@
return detail::sum_for_indexable<
Point,
Indexable,
- typename index::detail::traits::tag<Indexable>::type,
+ typename tag<Indexable>::type,
detail::comparable_distance_centroid_tag,
- index::detail::traits::dimension<Indexable>::value
+ dimension<Indexable>::value
>::apply(pt, i);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -30,8 +30,8 @@
inline static result_type apply(Point const& pt, BoxIndexable const& i)
{
- typedef typename index::detail::traits::coordinate_type<Point>::type point_coord_t;
- typedef typename index::detail::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
+ typedef typename coordinate_type<Point>::type point_coord_t;
+ typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -55,9 +55,9 @@
return detail::sum_for_indexable<
Point,
Indexable,
- typename index::detail::traits::tag<Indexable>::type,
+ typename tag<Indexable>::type,
detail::comparable_distance_far_tag,
- index::detail::traits::dimension<Indexable>::value
+ dimension<Indexable>::value
>::apply(pt, i);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -41,8 +41,8 @@
inline static result_type apply(Point const& pt, BoxIndexable const& i)
{
- typedef typename index::detail::traits::coordinate_type<Point>::type point_coord_t;
- typedef typename index::detail::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
+ typedef typename coordinate_type<Point>::type point_coord_t;
+ typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -66,9 +66,9 @@
return detail::sum_for_indexable<
Point,
Indexable,
- typename index::detail::traits::tag<Indexable>::type,
+ typename tag<Indexable>::type,
detail::comparable_distance_near_tag,
- index::detail::traits::dimension<Indexable>::value
+ dimension<Indexable>::value
>::apply(pt, i);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/content.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/content.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/content.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
-// n-dimensional box's content (hypervolume) - 2d area, 3d volume, ...
+// n-dimensional content (hypervolume) - 2d area, 3d volume, ...
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
@@ -11,15 +11,13 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
-#include <boost/geometry/index/detail/indexable.hpp>
-
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Indexable>
struct default_content_result
{
typedef typename select_most_precise<
- typename detail::traits::coordinate_type<Indexable>::type,
+ typename coordinate_type<Indexable>::type,
long double
>::type type;
};
@@ -27,31 +25,31 @@
namespace dispatch {
template <typename Box, size_t CurrentDimension>
-struct content_for_each_dimension
+struct content_box
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
- BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
+ //BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
- return content_for_each_dimension<Box, CurrentDimension - 1>::apply(b) *
- ( detail::get<max_corner, CurrentDimension - 1>(b) - detail::get<min_corner, CurrentDimension - 1>(b) );
+ return content_box<Box, CurrentDimension - 1>::apply(b) *
+ ( get<max_corner, CurrentDimension - 1>(b) - get<min_corner, CurrentDimension - 1>(b) );
}
};
template <typename Box>
-struct content_for_each_dimension<Box, 1>
+struct content_box<Box, 1>
{
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
- return detail::get<max_corner, 0>(b) - detail::get<min_corner, 0>(b);
+ return get<max_corner, 0>(b) - get<min_corner, 0>(b);
}
};
template <typename Indexable, typename Tag>
struct content
{
- // TODO: awulkiew - static assert?
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_INDEXABLE_AND_TAG, (Indexable, Tag));
};
template <typename Indexable>
@@ -68,7 +66,7 @@
{
static typename default_content_result<Indexable>::type apply(Indexable const& b)
{
- return dispatch::content_for_each_dimension<Indexable, detail::traits::dimension<Indexable>::value>::apply(b);
+ return dispatch::content_box<Indexable, dimension<Indexable>::value>::apply(b);
}
};
@@ -78,7 +76,7 @@
typename default_content_result<Indexable>::type content(Indexable const& b)
{
return dispatch::content<Indexable,
- typename detail::traits::tag<Indexable>::type
+ typename tag<Indexable>::type
>::apply(b);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/diff_abs.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/diff_abs.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/diff_abs.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -14,11 +14,26 @@
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename T>
-inline T diff_abs(T const& v1, T const& v2)
+inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_<true> const& /*is_integral*/)
{
return v1 < v2 ? v2 - v1 : v1 - v2;
}
+template <typename T>
+inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_<false> const& /*is_integral*/)
+{
+ return ::fabs(v1 - v2);
+}
+
+template <typename T>
+inline T diff_abs(T const& v1, T const& v2)
+{
+ typedef boost::mpl::bool_<
+ boost::is_integral<T>::value
+ > is_integral;
+ return diff_abs_dispatch(v1, v2, is_integral());
+}
+
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_DIFF_ABS_HPP
Modified: branches/release/boost/geometry/index/detail/algorithms/is_valid.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/is_valid.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/is_valid.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
-#include <boost/geometry/index/detail/indexable.hpp>
-
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
@@ -21,14 +19,14 @@
struct is_valid_box
{
BOOST_MPL_ASSERT_MSG(
- (0 < Dimension && Dimension <= detail::traits::dimension<Box>::value),
+ (0 < Dimension && Dimension <= dimension<Box>::value),
INVALID_DIMENSION_PARAMETER,
(is_valid_box));
static inline bool apply(Box const& b)
{
return is_valid_box<Box, Dimension - 1>::apply(b) &&
- ( detail::get<min_corner, Dimension - 1>(b) <= detail::get<max_corner, Dimension - 1>(b) );
+ ( get<min_corner, Dimension - 1>(b) <= get<max_corner, Dimension - 1>(b) );
}
};
@@ -37,7 +35,7 @@
{
static inline bool apply(Box const& b)
{
- return detail::get<min_corner, 0>(b) <= detail::get<max_corner, 0>(b);
+ return get<min_corner, 0>(b) <= get<max_corner, 0>(b);
}
};
@@ -64,7 +62,7 @@
{
static inline bool apply(Indexable const& b)
{
- return dispatch::is_valid_box<Indexable, detail::traits::dimension<Indexable>::value>::apply(b);
+ return dispatch::is_valid_box<Indexable, dimension<Indexable>::value>::apply(b);
}
};
@@ -73,7 +71,7 @@
template <typename Indexable>
inline bool is_valid(Indexable const& b)
{
- return dispatch::is_valid<Indexable, typename detail::traits::tag<Indexable>::type>::apply(b);
+ return dispatch::is_valid<Indexable, typename tag<Indexable>::type>::apply(b);
}
}}}} // namespace boost::geometry::index::detail
Modified: branches/release/boost/geometry/index/detail/algorithms/margin.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/margin.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/margin.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -11,7 +11,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
-#include <boost/geometry/index/detail/indexable.hpp>
+// WARNING! comparable_margin() will work only if the same Geometries are compared
+// so it shouldn't be used in the case of Variants!
namespace boost { namespace geometry { namespace index { namespace detail {
@@ -90,11 +91,15 @@
// }
//};
+// TODO - test if this definition of margin is ok for Dimension > 2
+// Now it's sum of edges lengths
+// maybe margin_for_each_dimension should be used to get more or less hypersurface?
+
template <typename Box, size_t CurrentDimension>
struct simple_margin_for_each_dimension
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
- BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
+ //BOOST_STATIC_ASSERT(CurrentDimension <= dimension<Box>::value);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
@@ -112,17 +117,49 @@
}
};
+namespace dispatch {
+
+template <typename Geometry, typename Tag>
+struct comparable_margin
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
+};
+
+template <typename Geometry>
+struct comparable_margin<Geometry, point_tag>
+{
+ typedef typename default_margin_result<Geometry>::type result_type;
+
+ static inline result_type apply(Geometry const& ) { return 0; }
+};
+
template <typename Box>
-typename default_margin_result<Box>::type comparable_margin(Box const& b)
+struct comparable_margin<Box, box_tag>
+{
+ typedef typename default_margin_result<Box>::type result_type;
+
+ static inline result_type apply(Box const& g)
+ {
+ //return detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
+ return detail::simple_margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
+ }
+};
+
+} // namespace dispatch
+
+template <typename Geometry>
+typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
{
- //return detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
- return detail::simple_margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
+ return dispatch::comparable_margin<
+ Geometry,
+ typename tag<Geometry>::type
+ >::apply(g);
}
//template <typename Box>
//typename default_margin_result<Box>::type margin(Box const& b)
//{
-// return 2 * detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
+// return 2 * detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(b);
//}
}}}} // namespace boost::geometry::index::detail
Modified: branches/release/boost/geometry/index/detail/algorithms/minmaxdist.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/minmaxdist.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/minmaxdist.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -32,8 +32,8 @@
inline static result_type apply(Point const& pt, BoxIndexable const& i, result_type const& maxd)
{
- typedef typename index::traits::coordinate_type<Point>::type point_coord_t;
- typedef typename index::traits::coordinate_type<BoxIndexable>::type indexable_coord_t;
+ typedef typename coordinate_type<Point>::type point_coord_t;
+ typedef typename coordinate_type<BoxIndexable>::type indexable_coord_t;
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
@@ -95,7 +95,7 @@
Indexable,
box_tag,
minmaxdist_tag,
- index::traits::dimension<Indexable>::value
+ dimension<Indexable>::value
>::apply(pt, i, maxd);
}
};
@@ -110,7 +110,7 @@
return detail::minmaxdist_impl<
Point,
Indexable,
- typename index::traits::tag<Indexable>::type
+ typename tag<Indexable>::type
>::apply(pt, i);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/path_intersection.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/path_intersection.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/path_intersection.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -26,11 +26,11 @@
template <typename Indexable, typename Segment>
struct path_intersection<Indexable, Segment, box_tag, segment_tag>
{
- typedef typename default_distance_result<typename ::boost::geometry::traits::point_type<Segment>::type>::type comparable_distance_type;
+ typedef typename default_distance_result<typename point_type<Segment>::type>::type comparable_distance_type;
static inline bool apply(Indexable const& b, Segment const& segment, comparable_distance_type & comparable_distance)
{
- typedef typename ::boost::geometry::traits::point_type<Segment>::type point_type;
+ typedef typename point_type<Segment>::type point_type;
point_type p1, p2;
geometry::detail::assign_point_from_index<0>(segment, p1);
geometry::detail::assign_point_from_index<1>(segment, p2);
@@ -90,8 +90,8 @@
{
typedef typename dispatch::path_intersection<
Indexable, SegmentOrLinestring,
- typename detail::traits::tag<Indexable>::type,
- typename detail::traits::tag<SegmentOrLinestring>::type
+ typename tag<Indexable>::type,
+ typename tag<SegmentOrLinestring>::type
>::comparable_distance_type type;
};
@@ -104,8 +104,8 @@
return dispatch::path_intersection<
Indexable, SegmentOrLinestring,
- typename detail::traits::tag<Indexable>::type,
- typename detail::traits::tag<SegmentOrLinestring>::type
+ typename tag<Indexable>::type,
+ typename tag<SegmentOrLinestring>::type
>::apply(b, path, comparable_distance);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/segment_intersection.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/segment_intersection.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/segment_intersection.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP
-#include <boost/geometry/index/detail/indexable.hpp>
-
namespace boost { namespace geometry { namespace index { namespace detail {
//template <typename Indexable, typename Point>
@@ -20,8 +18,8 @@
//{
// typedef typename select_most_precise<
// typename select_most_precise<
-// typename traits::coordinate_type<Indexable>::type,
-// typename traits::coordinate_type<Point>::type
+// typename coordinate_type<Indexable>::type,
+// typename coordinate_type<Point>::type
// >::type,
// float // TODO - use bigger type, calculated from the size of coordinate types
// >::type type;
@@ -36,9 +34,9 @@
template <typename Box, typename Point, size_t I>
struct box_segment_intersection_dim
{
- BOOST_STATIC_ASSERT(I < traits::dimension<Box>::value);
- BOOST_STATIC_ASSERT(I < traits::dimension<Point>::value);
- BOOST_STATIC_ASSERT(traits::dimension<Point>::value == traits::dimension<Box>::value);
+ BOOST_STATIC_ASSERT(I < dimension<Box>::value);
+ BOOST_STATIC_ASSERT(I < dimension<Point>::value);
+ BOOST_STATIC_ASSERT(dimension<Point>::value == dimension<Box>::value);
// WARNING! - RelativeDistance must be IEEE float for this to work
@@ -47,8 +45,8 @@
RelativeDistance & t_near, RelativeDistance & t_far)
{
RelativeDistance ray_d = geometry::get<I>(p1) - geometry::get<I>(p0);
- RelativeDistance tn = ( detail::get<min_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
- RelativeDistance tf = ( detail::get<max_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
+ RelativeDistance tn = ( geometry::get<min_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
+ RelativeDistance tf = ( geometry::get<max_corner, I>(b) - geometry::get<I>(p0) ) / ray_d;
if ( tf < tn )
::std::swap(tn, tf);
@@ -105,7 +103,7 @@
template <typename Indexable, typename Point>
struct segment_intersection<Indexable, Point, box_tag>
{
- typedef dispatch::box_segment_intersection<Indexable, Point, detail::traits::dimension<Indexable>::value> impl;
+ typedef dispatch::box_segment_intersection<Indexable, Point, dimension<Indexable>::value> impl;
template <typename RelativeDistance>
static inline bool apply(Indexable const& b, Point const& p0, Point const& p1, RelativeDistance & relative_distance)
@@ -134,7 +132,7 @@
return dispatch::segment_intersection<
Indexable, Point,
- typename detail::traits::tag<Indexable>::type
+ typename tag<Indexable>::type
>::apply(b, p0, p1, relative_distance);
}
Modified: branches/release/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP
-#include <boost/geometry/index/detail/indexable.hpp>
-
namespace boost { namespace geometry { namespace index { namespace detail {
template <
Modified: branches/release/boost/geometry/index/detail/assert.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/assert.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/assert.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -14,6 +14,9 @@
#define BOOST_GEOMETRY_INDEX_ASSERT(CONDITION, TEXT_MSG) \
BOOST_ASSERT_MSG(CONDITION, TEXT_MSG)
+// TODO - change it to something like:
+// BOOST_ASSERT((CONDITION) && (TEXT_MSG))
+
#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
#define BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(PARAM)
Modified: branches/release/boost/geometry/index/detail/config_begin.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/config_begin.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/config_begin.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -10,8 +10,6 @@
#ifdef BOOST_MSVC
- #define BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(A) (void)A;
-
#pragma warning (push)
#pragma warning (disable : 4512) // assignment operator could not be generated
#pragma warning (disable : 4127) // conditional expression is constant
@@ -19,9 +17,5 @@
// temporary?
#pragma warning (disable : 4180) // qualifier applied to function type has no meaning
-#else //BOOST_MSVC
-
- #define BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(A)
-
#endif //BOOST_MSVC
Deleted: branches/release/boost/geometry/index/detail/indexable.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/indexable.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84888)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,139 +0,0 @@
-// Boost.Geometry Index
-//
-// Indexable's traits and related functions
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP
-
-namespace boost { namespace geometry { namespace index { namespace detail {
-
-namespace dispatch {
-
-template <typename Indexable, typename IndexableTag>
-struct point_type
-{
- typedef void type;
-};
-
-template <typename Indexable>
-struct point_type<Indexable, geometry::box_tag>
-{
- typedef typename geometry::traits::point_type<Indexable>::type type;
-};
-
-template <typename Indexable>
-struct point_type<Indexable, geometry::point_tag>
-{
- typedef Indexable type;
-};
-
-} // namespace dispatch
-
-namespace traits {
-
-template <typename Indexable>
-struct point_type
-{
- typedef typename dispatch::point_type<
- Indexable,
- typename geometry::traits::tag<Indexable>::type
- >::type type;
-};
-
-template <typename Indexable>
-struct coordinate_system
-{
- typedef typename geometry::traits::coordinate_system<
- typename point_type<Indexable>::type
- >::type type;
-};
-
-template <typename Indexable>
-struct coordinate_type
-{
- typedef typename geometry::traits::coordinate_type<
- typename point_type<Indexable>::type
- >::type type;
-};
-
-template <typename Indexable>
-struct dimension
-{
- static const size_t value =
- geometry::traits::dimension<
- typename point_type<Indexable>::type
- >::value;
-};
-
-template <typename Indexable>
-struct tag
-{
- typedef typename geometry::traits::tag<
- Indexable
- >::type type;
-};
-
-} // namespace traits
-
-namespace dispatch {
-
-template <size_t Corner, size_t DimensionIndex, typename Indexable, typename IndexableTag>
-struct indexable_indexed_access {};
-
-template <size_t Corner, size_t DimensionIndex, typename Indexable>
-struct indexable_indexed_access<Corner, DimensionIndex, Indexable, box_tag>
-{
- typedef typename traits::point_type<Indexable>::type point_type;
- typedef typename traits::coordinate_type<point_type>::type coordinate_type;
-
- static inline coordinate_type get(Indexable const& i)
- {
- return geometry::get<Corner, DimensionIndex>(i);
- }
-};
-
-template <size_t Corner, size_t DimensionIndex, typename Indexable>
-struct indexable_indexed_access<Corner, DimensionIndex, Indexable, point_tag>
-{
- typedef typename traits::coordinate_type<Indexable>::type coordinate_type;
-
- static inline coordinate_type get(Indexable const& i)
- {
- return geometry::get<DimensionIndex>(i);
- }
-};
-
-} // namespace dispatch
-
-template <size_t Corner, size_t DimensionIndex, typename Indexable>
-typename traits::coordinate_type<Indexable>::type get(Indexable const& i)
-{
- return dispatch::indexable_indexed_access<
- Corner,
- DimensionIndex,
- Indexable,
- typename geometry::traits::tag<Indexable>::type
- >::get(i);
-}
-
-template <typename Indexable>
-struct default_box_type
-{
- typedef geometry::model::box<
- geometry::model::point<
- typename traits::coordinate_type<Indexable>::type,
- traits::dimension<Indexable>::value,
- typename traits::coordinate_system<Indexable>::type
- >
- > type;
-};
-
-}}}} // namespace boost::geometry::index::detail
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP
Modified: branches/release/boost/geometry/index/detail/predicates.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/predicates.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/predicates.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -20,8 +20,6 @@
// predicates
// ------------------------------------------------------------------ //
-//struct empty {};
-
template <typename Fun, bool IsFunction>
struct satisfies_impl
{
@@ -36,7 +34,7 @@
Fun fun;
};
-template <typename Fun>
+template <typename Fun, bool Negated>
struct satisfies
: satisfies_impl<Fun, ::boost::is_function<Fun>::value>
{
@@ -46,99 +44,32 @@
satisfies(base const& b) : base(b) {}
};
-template <typename Fun>
-struct not_satisfies
- : satisfies_impl<Fun, ::boost::is_function<Fun>::value>
-{
- typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
-
- not_satisfies(Fun const& f) : base(f) {}
- not_satisfies(base const& b) : base(b) {}
-};
-
-template <typename Geometry>
-struct covered_by
-{
- covered_by(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
-
-template <typename Geometry>
-struct disjoint
-{
- disjoint(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
-
-template <typename Geometry>
-struct intersects
-{
- intersects(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
-
-template <typename Geometry>
-struct overlaps
-{
- overlaps(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
-
-//template <typename Geometry>
-//struct touches
-//{
-// touches(Geometry const& g) : geometry(g) {}
-// Geometry geometry;
-//};
-
-template <typename Geometry>
-struct within
-{
- within(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
-
-template <typename Geometry>
-struct not_covered_by
-{
- not_covered_by(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
+// ------------------------------------------------------------------ //
-template <typename Geometry>
-struct not_disjoint
-{
- not_disjoint(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
+struct contains_tag {};
+struct covered_by_tag {};
+struct covers_tag {};
+struct disjoint_tag {};
+struct intersects_tag {};
+struct overlaps_tag {};
+struct touches_tag {};
+struct within_tag {};
-template <typename Geometry>
-struct not_intersects
+template <typename Geometry, typename Tag, bool Negated>
+struct spatial_predicate
{
- not_intersects(Geometry const& g) : geometry(g) {}
+ spatial_predicate(Geometry const& g) : geometry(g) {}
Geometry geometry;
};
-template <typename Geometry>
-struct not_overlaps
-{
- not_overlaps(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
-
-//template <typename Geometry>
-//struct not_touches
-//{
-// not_touches(Geometry const& g) : geometry(g) {}
-// Geometry geometry;
-//};
+// ------------------------------------------------------------------ //
-template <typename Geometry>
-struct not_within
-{
- not_within(Geometry const& g) : geometry(g) {}
- Geometry geometry;
-};
+// TODO
+// may be replaced by
+// nearest_predicate<Geometry>
+// Geometry geometry
+// unsigned count
+// + point_tag, path_tag
template <typename PointOrRelation>
struct nearest
@@ -163,40 +94,6 @@
};
// ------------------------------------------------------------------ //
-// is_predicate
-// ------------------------------------------------------------------ //
-
-//template <typename P> struct is_predicate { static const bool value = false; };
-////template <> struct is_predicate< empty > { static const bool value = true; };
-//template <typename UP> struct is_predicate< satisfies<UP> > { static const bool value = true; };
-//template <typename G> struct is_predicate< covered_by<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< disjoint<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< intersects<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< overlaps<G> > { static const bool value = true; };
-////template <typename G> struct is_predicate< touches<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< within<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< not_covered_by<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< not_disjoint<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< not_intersects<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< not_overlaps<G> > { static const bool value = true; };
-////template <typename G> struct is_predicate< not_touches<G> > { static const bool value = true; };
-//template <typename G> struct is_predicate< not_within<G> > { static const bool value = true; };
-//template <typename P> struct is_predicate< nearest<P> > { static const bool value = true; };
-
-// ------------------------------------------------------------------ //
-// predicate_check_default
-// ------------------------------------------------------------------ //
-
-//template <typename GeometryOrUnary, typename GeometryTag, typename Tag>
-//struct predicate_check_default
-//{
-// BOOST_MPL_ASSERT_MSG(
-// (false),
-// NOT_IMPLEMENTED_FOR_THESE_TAGS,
-// (predicate_check_default));
-//};
-
-// ------------------------------------------------------------------ //
// predicate_check
// ------------------------------------------------------------------ //
@@ -210,195 +107,145 @@
};
// ------------------------------------------------------------------ //
-// predicate_check_default for value
-// ------------------------------------------------------------------ //
-
-//template <typename Geometry, typename GeometryTag>
-//struct predicate_check_default<Geometry, GeometryTag, value_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(Geometry const& g, Value const&, Indexable const& i)
-// {
-// return geometry::intersects(i, g);
-// }
-//};
-//
-//template <typename Unary>
-//struct predicate_check_default<Unary, void, value_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(Unary const& u, Value const& v, Indexable const&)
-// {
-// return u(v);
-// }
-//};
-
-// ------------------------------------------------------------------ //
-// predicate_check for value
-// ------------------------------------------------------------------ //
-
-//template <typename GeometryOrUnary>
-//struct predicate_check<GeometryOrUnary, value_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(GeometryOrUnary const& g, Value const& v, Indexable const& i)
-// {
-// return predicate_check_default<
-// GeometryOrUnary, typename geometry::traits::tag<GeometryOrUnary>::type, bounds_tag
-// >::apply(g, v, i);
-// }
-//};
-
-//template <>
-//struct predicate_check<empty, value_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(empty const&, Value const&, Indexable const&)
-// {
-// return true;
-// }
-//};
template <typename Fun>
-struct predicate_check<satisfies<Fun>, value_tag>
+struct predicate_check<satisfies<Fun, false>, value_tag>
{
template <typename Value, typename Indexable>
- static inline bool apply(satisfies<Fun> const& p, Value const& v, Indexable const&)
+ static inline bool apply(satisfies<Fun, false> const& p, Value const& v, Indexable const&)
{
return p.fun(v);
}
};
template <typename Fun>
-struct predicate_check<not_satisfies<Fun>, value_tag>
+struct predicate_check<satisfies<Fun, true>, value_tag>
{
template <typename Value, typename Indexable>
- static inline bool apply(not_satisfies<Fun> const& p, Value const& v, Indexable const&)
+ static inline bool apply(satisfies<Fun, true> const& p, Value const& v, Indexable const&)
{
return !p.fun(v);
}
};
-template <typename Geometry>
-struct predicate_check<covered_by<Geometry>, value_tag>
+// ------------------------------------------------------------------ //
+
+template <typename Tag>
+struct spatial_predicate_call
{
- template <typename Value, typename Indexable>
- static inline bool apply(covered_by<Geometry> const& p, Value const&, Indexable const& i)
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
+};
+
+template <>
+struct spatial_predicate_call<contains_tag>
+{
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return geometry::covered_by(i, p.geometry);
+ return geometry::within(g2, g1);
}
};
-template <typename Geometry>
-struct predicate_check<disjoint<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<covered_by_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(disjoint<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return geometry::disjoint(i, p.geometry);
+ return geometry::covered_by(g1, g2);
}
};
-template <typename Geometry>
-struct predicate_check<intersects<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<covers_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(intersects<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return geometry::intersects(i, p.geometry);
+ return geometry::covered_by(g2, g1);
}
};
-template <typename Geometry>
-struct predicate_check<overlaps<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<disjoint_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(overlaps<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return geometry::overlaps(i, p.geometry);
+ return geometry::disjoint(g1, g2);
}
};
-//template <typename Geometry>
-//struct predicate_check<touches<Geometry>, value_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(touches<Geometry> const& p, Value const&, Indexable const& i)
-// {
-// return geometry::touches(i, p.geometry);
-// }
-//};
-
-template <typename Geometry>
-struct predicate_check<within<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<intersects_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(within<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return geometry::within(i, p.geometry);
+ return geometry::intersects(g1, g2);
}
};
-template <typename Geometry>
-struct predicate_check<not_covered_by<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<overlaps_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(not_covered_by<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return !geometry::covered_by(i, p.geometry);
+ return geometry::overlaps(g1, g2);
}
};
-template <typename Geometry>
-struct predicate_check<not_disjoint<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<touches_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(not_disjoint<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return !geometry::disjoint(i, p.geometry);
+ return geometry::touches(g1, g2);
}
};
-template <typename Geometry>
-struct predicate_check<not_intersects<Geometry>, value_tag>
+template <>
+struct spatial_predicate_call<within_tag>
{
- template <typename Value, typename Indexable>
- static inline bool apply(not_intersects<Geometry> const& p, Value const&, Indexable const& i)
+ template <typename G1, typename G2>
+ static inline bool apply(G1 const& g1, G2 const& g2)
{
- return !geometry::intersects(i, p.geometry);
+ return geometry::within(g1, g2);
}
};
-template <typename Geometry>
-struct predicate_check<not_overlaps<Geometry>, value_tag>
+// ------------------------------------------------------------------ //
+
+// spatial predicate
+template <typename Geometry, typename Tag>
+struct predicate_check<spatial_predicate<Geometry, Tag, false>, value_tag>
{
+ typedef spatial_predicate<Geometry, Tag, false> Pred;
+
template <typename Value, typename Indexable>
- static inline bool apply(not_overlaps<Geometry> const& p, Value const&, Indexable const& i)
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !geometry::overlaps(i, p.geometry);
+ return spatial_predicate_call<Tag>::apply(i, p.geometry);
}
};
-//template <typename Geometry>
-//struct predicate_check<not_touches<Geometry>, value_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(not_touches<Geometry> const& p, Value const&, Indexable const& i)
-// {
-// return !geometry::touches(i, p.geometry);
-// }
-//};
-
-template <typename Geometry>
-struct predicate_check<not_within<Geometry>, value_tag>
+// negated spatial predicate
+template <typename Geometry, typename Tag>
+struct predicate_check<spatial_predicate<Geometry, Tag, true>, value_tag>
{
+ typedef spatial_predicate<Geometry, Tag, true> Pred;
+
template <typename Value, typename Indexable>
- static inline bool apply(not_within<Geometry> const& p, Value const&, Indexable const& i)
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !geometry::within(i, p.geometry);
+ return !spatial_predicate_call<Tag>::apply(i, p.geometry);
}
};
+// ------------------------------------------------------------------ //
+
template <typename DistancePredicates>
struct predicate_check<nearest<DistancePredicates>, value_tag>
{
@@ -420,199 +267,177 @@
};
// ------------------------------------------------------------------ //
-// predicate_check_default for bounds
-// ------------------------------------------------------------------ //
-
-//template <typename Geometry, typename GeometryTag>
-//struct predicate_check_default<Geometry, GeometryTag, bounds_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(Geometry const& g, Value const&, Indexable const& i)
-// {
-// return geometry::intersects(i, g);
-// }
-//};
-//
-//template <typename Unary>
-//struct predicate_check_default<Unary, void, bounds_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(Unary const&, Value const&, Indexable const&)
-// {
-// return true;
-// }
-//};
-
-// ------------------------------------------------------------------ //
-// predicates_chec for bounds
+// predicates_check for bounds
// ------------------------------------------------------------------ //
-//template <typename GeometryOrUnary>
-//struct predicate_check<GeometryOrUnary, bounds_tag>
-//{
-// template <typename Value, typename Indexable>
-// static inline bool apply(GeometryOrUnary const& g, Value const& v, Indexable const& i)
-// {
-// return predicate_check_default<
-// GeometryOrUnary, typename geometry::traits::tag<GeometryOrUnary>::type, bounds_tag
-// >::apply(g, v, i);
-// }
-//};
-
-//template <>
-//struct predicate_check<empty, bounds_tag>
-//{
-// template <typename Geometry, typename Value, typename Indexable>
-// static inline bool apply(Geometry const&, Value const&, Indexable const&)
-// {
-// return true;
-// }
-//};
-
-template <typename Fun>
-struct predicate_check<satisfies<Fun>, bounds_tag>
+template <typename Fun, bool Negated>
+struct predicate_check<satisfies<Fun, Negated>, bounds_tag>
{
template <typename Value, typename Box>
- static bool apply(satisfies<Fun> const&, Value const&, Box const&)
+ static bool apply(satisfies<Fun, Negated> const&, Value const&, Box const&)
{
return true;
}
};
-template <typename Fun>
-struct predicate_check<not_satisfies<Fun>, bounds_tag>
-{
- template <typename Value, typename Box>
- static bool apply(not_satisfies<Fun> const&, Value const&, Box const&)
- {
- return true;
- }
-};
+// ------------------------------------------------------------------ //
-template <typename Geometry>
-struct predicate_check<covered_by<Geometry>, bounds_tag>
+// NOT NEGATED
+// value_tag bounds_tag
+// ---------------------------
+// contains(I,G) contains(I,G)
+// covered_by(I,G) intersects(I,G)
+// covers(I,G) covers(I,G)
+// disjoint(I,G) !covered_by(I,G)
+// intersects(I,G) intersects(I,G)
+// overlaps(I,G) intersects(I,G) - possibly change to the version without border case, e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false
+// touches(I,G) intersects(I,G)
+// within(I,G) intersects(I,G) - possibly change to the version without border case, e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false
+
+// spatial predicate - default
+template <typename Geometry, typename Tag>
+struct predicate_check<spatial_predicate<Geometry, Tag, false>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(covered_by<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, Tag, false> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return geometry::intersects(i, p.geometry);
+ return spatial_predicate_call<intersects_tag>::apply(i, p.geometry);
}
};
+// spatial predicate - contains
template <typename Geometry>
-struct predicate_check<disjoint<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, contains_tag, false>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(disjoint<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, contains_tag, false> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !geometry::covered_by(i, p.geometry);
+ return spatial_predicate_call<contains_tag>::apply(i, p.geometry);
}
};
+// spatial predicate - covers
template <typename Geometry>
-struct predicate_check<intersects<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, covers_tag, false>, bounds_tag>
{
+ typedef spatial_predicate<Geometry, covers_tag, false> Pred;
+
template <typename Value, typename Indexable>
- static inline bool apply(intersects<Geometry> const& p, Value const&, Indexable const& i)
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return geometry::intersects(i, p.geometry);
+ return spatial_predicate_call<covers_tag>::apply(i, p.geometry);
}
};
+// spatial predicate - disjoint
template <typename Geometry>
-struct predicate_check<overlaps<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, disjoint_tag, false>, bounds_tag>
{
- template <typename Value, typename Box>
- static inline bool apply(overlaps<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, disjoint_tag, false> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- // TODO: awulkiew - possibly change to the version without border case
- // e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false
- return geometry::intersects(i, p.geometry);
+ return !spatial_predicate_call<covered_by_tag>::apply(i, p.geometry);
}
};
-//template <typename Geometry>
-//struct predicate_check<touches<Geometry>, bounds_tag>
-//{
-// template <typename Value, typename Box>
-// static bool apply(touches<Geometry> const& p, Value const&, Box const& i)
-// {
-// return geometry::intersects(i, p.geometry);
-// }
-//};
+// NEGATED
+// value_tag bounds_tag
+// ---------------------------
+// !contains(I,G) TRUE
+// !covered_by(I,G) !covered_by(I,G)
+// !covers(I,G) TRUE
+// !disjoint(I,G) !disjoint(I,G)
+// !intersects(I,G) !covered_by(I,G)
+// !overlaps(I,G) TRUE
+// !touches(I,G) !intersects(I,G)
+// !within(I,G) !within(I,G)
-template <typename Geometry>
-struct predicate_check<within<Geometry>, bounds_tag>
+// negated spatial predicate - default
+template <typename Geometry, typename Tag>
+struct predicate_check<spatial_predicate<Geometry, Tag, true>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(within<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, Tag, true> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- // TODO: awulkiew - possibly change to the version without border case
- // e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false
- return geometry::intersects(i, p.geometry);
+ return !spatial_predicate_call<Tag>::apply(i, p.geometry);
}
};
+// negated spatial predicate - contains
template <typename Geometry>
-struct predicate_check<not_covered_by<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, contains_tag, true>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(not_covered_by<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, contains_tag, true> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& , Value const&, Indexable const& )
{
- return !geometry::covered_by(i, p.geometry);
+ return true;
}
};
+// negated spatial predicate - covers
template <typename Geometry>
-struct predicate_check<not_disjoint<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, covers_tag, true>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(not_disjoint<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, covers_tag, true> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& , Value const&, Indexable const& )
{
- return !geometry::disjoint(i, p.geometry);
+ return true;
}
};
+// negated spatial predicate - intersects
template <typename Geometry>
-struct predicate_check<not_intersects<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, intersects_tag, true>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(not_intersects<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, intersects_tag, true> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !geometry::covered_by(i, p.geometry);
+ return !spatial_predicate_call<covered_by_tag>::apply(i, p.geometry);
}
};
+// negated spatial predicate - overlaps
template <typename Geometry>
-struct predicate_check<not_overlaps<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, overlaps_tag, true>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(not_overlaps<Geometry> const& , Value const&, Box const& )
+ typedef spatial_predicate<Geometry, overlaps_tag, true> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& , Value const&, Indexable const& )
{
return true;
}
};
-//template <typename Geometry>
-//struct predicate_check<not_touches<Geometry>, bounds_tag>
-//{
-// template <typename Value, typename Box>
-// static bool apply(not_touches<Geometry> const& p, Value const&, Box const& i)
-// {
-// return !geometry::intersects(i, p.geometry);
-// }
-//};
-
+// negated spatial predicate - touches
template <typename Geometry>
-struct predicate_check<not_within<Geometry>, bounds_tag>
+struct predicate_check<spatial_predicate<Geometry, touches_tag, true>, bounds_tag>
{
- template <typename Value, typename Box>
- static bool apply(not_within<Geometry> const& p, Value const&, Box const& i)
+ typedef spatial_predicate<Geometry, touches_tag, true> Pred;
+
+ template <typename Value, typename Indexable>
+ static inline bool apply(Pred const& p, Value const&, Indexable const& i)
{
- return !geometry::within(i, p.geometry);
+ return !spatial_predicate_call<intersects_tag>::apply(i, p.geometry);
}
};
+// ------------------------------------------------------------------ //
+
template <typename DistancePredicates>
struct predicate_check<nearest<DistancePredicates>, bounds_tag>
{
Modified: branches/release/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -26,28 +26,76 @@
namespace linear {
-// TODO: awulkiew - there are loops inside find_greatest_normalized_separation::apply()
+template <typename R, typename T>
+inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<false> const& /*is_unsigned*/)
+{
+ return to - from;
+}
+
+template <typename R, typename T>
+inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<true> const& /*is_unsigned*/)
+{
+ return from <= to ? R(to - from) : -R(from - to);
+}
+
+template <typename R, typename T>
+inline R difference(T const& from, T const& to)
+{
+ BOOST_MPL_ASSERT_MSG(!boost::is_unsigned<R>::value, RESULT_CANT_BE_UNSIGNED, (R));
+
+ typedef ::boost::mpl::bool_<
+ boost::is_unsigned<T>::value
+ > is_unsigned;
+
+ return difference_dispatch<R>(from, to, is_unsigned());
+}
+
+// TODO: awulkiew
+// In general, all aerial Indexables in the tree with box-like nodes will be analyzed as boxes
+// because they must fit into larger box. Therefore the algorithm could be the same for Bounds type.
+// E.g. if Bounds type is sphere, Indexables probably should be analyzed as spheres.
+// 1. View could be provided to 'see' all Indexables as Bounds type.
+// Not ok in the case of big types like Ring, however it's possible that Rings won't be supported,
+// only simple types. Even then if we consider storing Box inside the Sphere we must calculate
+// the bounding sphere 2x for each box because there are 2 loops. For each calculation this means
+// 4-2d or 8-3d expansions or -, / and sqrt().
+// 2. Additional container could be used and reused if the Indexable type is other than the Bounds type.
+
+// IMPORTANT!
+// Still probably the best way would be providing specialized algorithms for each Indexable-Bounds pair!
+// Probably on pick_seeds algorithm level - For Bounds=Sphere seeds would be choosen differently
+
+// TODO: awulkiew
+// there are loops inside find_greatest_normalized_separation::apply()
// iteration is done for each DimensionIndex.
// Separations and seeds for all DimensionIndex(es) could be calculated at once, stored, then the greatest would be choosen.
-// TODO: Implement separate version for Points
+// The following struct/method was adapted for the preliminary version of the R-tree. Then it was called:
+// void find_normalized_separations(std::vector<Box> const& boxes, T& separation, unsigned int& first, unsigned int& second) const
-// What if width calculated inside find_greatest_normalized_separation::apply() is near 0?
-// What epsilon should be taken to calculation and what would be the value of resulting separation?
-
-// from void find_normalized_separations(std::vector<Box> const& boxes, T& separation, unsigned int& first, unsigned int& second) const
+template <typename Elements, typename Parameters, typename Translator, typename Tag, size_t DimensionIndex>
+struct find_greatest_normalized_separation
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
+};
template <typename Elements, typename Parameters, typename Translator, size_t DimensionIndex>
-struct find_greatest_normalized_separation
+struct find_greatest_normalized_separation<Elements, Parameters, Translator, box_tag, DimensionIndex>
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
+
+ typedef typename boost::mpl::if_c<
+ boost::is_integral<coordinate_type>::value,
+ double,
+ coordinate_type
+ >::type separation_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
Translator const& translator,
- coordinate_type & separation,
+ separation_type & separation,
size_t & seed1,
size_t & seed2)
{
@@ -56,15 +104,15 @@
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
// find the lowest low, highest high
- coordinate_type lowest_low = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
- coordinate_type highest_high = index::detail::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
+ coordinate_type lowest_low = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
+ coordinate_type highest_high = geometry::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[0], translator));
// and the lowest high
coordinate_type lowest_high = highest_high;
size_t lowest_high_index = 0;
for ( size_t i = 1 ; i < elements_count ; ++i )
{
- coordinate_type min_coord = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
- coordinate_type max_coord = index::detail::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
+ coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
+ coordinate_type max_coord = geometry::get<max_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
if ( max_coord < lowest_high )
{
@@ -81,10 +129,10 @@
// find the highest low
size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
- coordinate_type highest_low = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[highest_low_index], translator));
+ coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[highest_low_index], translator));
for ( size_t i = highest_low_index ; i < elements_count ; ++i )
{
- coordinate_type min_coord = index::detail::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
+ coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(rtree::element_indexable(elements[i], translator));
if ( highest_low < min_coord &&
i != lowest_high_index )
{
@@ -94,25 +142,72 @@
}
coordinate_type const width = highest_high - lowest_low;
-
- // TODO: awulkiew - following separation calculation has two flaws:
- // 1. for floating point numbers width should be compared witn some EPS
- // 2. separation calculation won't work for unsigned numbers
- // but there should be possible to calculate negative value (cast to some floating point type?)
-
- // Temporary workaround
- BOOST_STATIC_ASSERT(!boost::is_unsigned<coordinate_type>::value);
-
- if ( width == 0 )
- separation = 0;
- // (highest_low - lowest_high) == 0
- else
- separation = (highest_low - lowest_high) / width;
+
+ // highest_low - lowest_high
+ separation = difference<separation_type>(lowest_high, highest_low);
+ // BOOST_ASSERT(0 <= width);
+ if ( std::numeric_limits<coordinate_type>::epsilon() < width )
+ separation /= width;
seed1 = highest_low_index;
seed2 = lowest_high_index;
- BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
+ ::boost::ignore_unused_variable_warning(parameters);
+ }
+};
+
+// Version for points doesn't calculate normalized separation since it would always be equal to 1
+// It returns two seeds most distant to each other, separation is equal to distance
+template <typename Elements, typename Parameters, typename Translator, size_t DimensionIndex>
+struct find_greatest_normalized_separation<Elements, Parameters, Translator, point_tag, DimensionIndex>
+{
+ typedef typename Elements::value_type element_type;
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
+
+ typedef coordinate_type separation_type;
+
+ static inline void apply(Elements const& elements,
+ Parameters const& parameters,
+ Translator const& translator,
+ separation_type & separation,
+ size_t & seed1,
+ size_t & seed2)
+ {
+ const size_t elements_count = parameters.get_max_elements() + 1;
+ BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements");
+ BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
+
+ // find the lowest low, highest high
+ coordinate_type lowest = geometry::get<DimensionIndex>(rtree::element_indexable(elements[0], translator));
+ coordinate_type highest = geometry::get<DimensionIndex>(rtree::element_indexable(elements[0], translator));
+ size_t lowest_index = 0;
+ size_t highest_index = 0;
+ for ( size_t i = 1 ; i < elements_count ; ++i )
+ {
+ coordinate_type coord = geometry::get<DimensionIndex>(rtree::element_indexable(elements[i], translator));
+
+ if ( coord < lowest )
+ {
+ lowest = coord;
+ lowest_index = i;
+ }
+
+ if ( highest < coord )
+ {
+ highest = coord;
+ highest_index = i;
+ }
+ }
+
+ separation = highest - lowest;
+ seed1 = lowest_index;
+ seed2 = highest_index;
+
+ if ( lowest_index == highest_index )
+ seed2 = (lowest_index + 1) % elements_count; // % is just in case since if this is true lowest_index is 0
+
+ ::boost::ignore_unused_variable_warning(parameters);
}
};
@@ -123,20 +218,27 @@
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
+
+ typedef find_greatest_normalized_separation<
+ Elements, Parameters, Translator,
+ typename tag<indexable_type>::type, Dimension - 1
+ > find_norm_sep;
+
+ typedef typename find_norm_sep::separation_type separation_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
Translator const& tr,
- coordinate_type & separation,
+ separation_type & separation,
size_t & seed1,
size_t & seed2)
{
pick_seeds_impl<Elements, Parameters, Translator, Dimension - 1>::apply(elements, parameters, tr, separation, seed1, seed2);
- coordinate_type current_separation;
+ separation_type current_separation;
size_t s1, s2;
- find_greatest_normalized_separation<Elements, Parameters, Translator, Dimension - 1>::apply(elements, parameters, tr, current_separation, s1, s2);
+ find_norm_sep::apply(elements, parameters, tr, current_separation, s1, s2);
// in the old implementation different operator was used: <= (y axis prefered)
if ( separation < current_separation )
@@ -153,16 +255,23 @@
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
+
+ typedef find_greatest_normalized_separation<
+ Elements, Parameters, Translator,
+ typename tag<indexable_type>::type, 0
+ > find_norm_sep;
+
+ typedef typename find_norm_sep::separation_type separation_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
Translator const& tr,
- coordinate_type & separation,
+ separation_type & separation,
size_t & seed1,
size_t & seed2)
{
- find_greatest_normalized_separation<Elements, Parameters, Translator, 0>::apply(elements, parameters, tr, separation, seed1, seed2);
+ find_norm_sep::apply(elements, parameters, tr, separation, seed1, seed2);
}
};
@@ -173,9 +282,12 @@
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
+
+ static const size_t dimension = geometry::dimension<indexable_type>::value;
- static const size_t dimension = index::detail::traits::dimension<indexable_type>::value;
+ typedef pick_seeds_impl<Elements, Parameters, Translator, dimension> impl;
+ typedef typename impl::separation_type separation_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
@@ -183,7 +295,7 @@
size_t & seed1,
size_t & seed2)
{
- coordinate_type separation = 0;
+ separation_type separation = 0;
pick_seeds_impl<Elements, Parameters, Translator, dimension>::apply(elements, parameters, tr, separation, seed1, seed2);
}
};
@@ -213,7 +325,7 @@
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
elements_type & elements1 = rtree::elements(n);
@@ -245,8 +357,8 @@
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
- geometry::convert(rtree::element_indexable(elements_copy[seed1], translator), box1);
- geometry::convert(rtree::element_indexable(elements_copy[seed2], translator), box2);
+ detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
+ detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
// initialize areas
content_type content1 = index::detail::content(box1);
@@ -328,7 +440,7 @@
}
};
-}} // namespace detail::rtree::visitors
+}} // namespace detail::rtree
}}} // namespace boost::geometry::index
Modified: branches/release/boost/geometry/index/detail/rtree/node/node.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/node/node.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/node/node.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -32,6 +32,8 @@
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
+#include <boost/geometry/index/detail/algorithms/bounds.hpp>
+
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -49,7 +51,7 @@
return result;
}
- geometry::convert(element_indexable(*first, tr), result);
+ detail::bounds(element_indexable(*first, tr), result);
++first;
for ( ; first != last ; ++first )
Modified: branches/release/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -25,8 +25,7 @@
typedef detail::varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
- Parameters::max_elements + 1,
- elements_allocator_type
+ Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
@@ -48,8 +47,7 @@
typedef detail::varray<
Value,
- Parameters::max_elements + 1,
- elements_allocator_type
+ Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
@@ -88,8 +86,8 @@
};
// elements derived type
-template <typename OldValue, size_t N, typename A, typename NewValue>
-struct container_from_elements_type<detail::varray<OldValue, N, A>, NewValue>
+template <typename OldValue, size_t N, typename NewValue>
+struct container_from_elements_type<detail::varray<OldValue, N>, NewValue>
{
typedef detail::varray<NewValue, N> type;
};
Modified: branches/release/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -26,8 +26,7 @@
typedef detail::varray<
rtree::ptr_pair<Box, typename Allocators::node_pointer>,
- Parameters::max_elements + 1,
- elements_allocator_type
+ Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
@@ -45,8 +44,7 @@
typedef detail::varray<
Value,
- Parameters::max_elements + 1,
- elements_allocator_type
+ Parameters::max_elements + 1
> elements_type;
template <typename Alloc>
Copied: branches/release/boost/geometry/index/detail/rtree/pack_create.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/pack_create.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/pack_create.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/pack_create.hpp)
@@ -0,0 +1,376 @@
+// Boost.Geometry Index
+//
+// R-tree initial packing
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
+
+namespace pack_utils {
+
+template <std::size_t Dimension>
+struct biggest_edge
+{
+ BOOST_STATIC_ASSERT(0 < Dimension);
+ template <typename Box>
+ static inline void apply(Box const& box, typename coordinate_type<Box>::type & length, std::size_t & dim_index)
+ {
+ biggest_edge<Dimension-1>::apply(box, length, dim_index);
+ typename coordinate_type<Box>::type curr
+ = geometry::get<max_corner, Dimension-1>(box) - geometry::get<min_corner, Dimension-1>(box);
+ if ( length < curr )
+ {
+ dim_index = Dimension - 1;
+ length = curr;
+ }
+ }
+};
+
+template <>
+struct biggest_edge<1>
+{
+ template <typename Box>
+ static inline void apply(Box const& box, typename coordinate_type<Box>::type & length, std::size_t & dim_index)
+ {
+ dim_index = 0;
+ length = geometry::get<max_corner, 0>(box) - geometry::get<min_corner, 0>(box);
+ }
+};
+
+template <std::size_t I>
+struct point_entries_comparer
+{
+ template <typename PointEntry>
+ bool operator()(PointEntry const& e1, PointEntry const& e2) const
+ {
+ return geometry::get<I>(e1.first) < geometry::get<I>(e2.first);
+ }
+};
+
+template <std::size_t I, std::size_t Dimension>
+struct partial_sort_and_half_boxes
+{
+ template <typename EIt, typename Box>
+ static inline void apply(EIt first, EIt median, EIt last, Box const& box, Box & left, Box & right, std::size_t dim_index)
+ {
+ if ( I == dim_index )
+ {
+ std::partial_sort(first, median, last, point_entries_comparer<I>());
+
+ geometry::convert(box, left);
+ geometry::convert(box, right);
+ typename coordinate_type<Box>::type edge_len
+ = geometry::get<max_corner, I>(box) - geometry::get<min_corner, I>(box);
+ typename coordinate_type<Box>::type median
+ = geometry::get<min_corner, I>(box) + edge_len / 2;
+ geometry::set<max_corner, I>(left, median);
+ geometry::set<min_corner, I>(right, median);
+ }
+ else
+ partial_sort_and_half_boxes<I+1, Dimension>::apply(first, median, last, box, left, right, dim_index);
+ }
+};
+
+template <std::size_t Dimension>
+struct partial_sort_and_half_boxes<Dimension, Dimension>
+{
+ template <typename EIt, typename Box>
+ static inline void apply(EIt , EIt , EIt , Box const& , Box & , Box & , std::size_t ) {}
+};
+
+} // namespace pack_utils
+
+// STR leafs number are calculated as rcount/max
+// and the number of splitting planes for each dimension as (count/max)^(1/dimension)
+// <-> for dimension==2 -> sqrt(count/max)
+//
+// The main flaw of this algorithm is that the resulting tree will have bad structure for:
+// 1. non-uniformly distributed elements
+// Statistic check could be performed, e.g. based on variance of lengths of elements edges for each dimension
+// 2. elements distributed mainly along one axis
+// Calculate bounding box of all elements and then number of dividing planes for a dimension
+// from the length of BB edge for this dimension (more or less assuming that elements are uniformly-distributed squares)
+//
+// Another thing is that the last node may have less elements than Max or even Min.
+// The number of splitting planes must be chosen more carefully than count/max
+//
+// This algorithm is something between STR and TGS
+// it is more similar to the top-down recursive kd-tree creation algorithm
+// using object median split and split axis of greatest BB edge
+// BB is only used as a hint (assuming objects are distributed uniformly)
+//
+// Implemented algorithm guarantees that the number of elements in nodes will be between Min and Max
+// and that nodes are packed as tightly as possible
+// e.g. for 177 values Max = 5 and Min = 2 it will construct the following tree:
+// ROOT 177
+// L1 125 52
+// L2 25 25 25 25 25 25 17 10
+// L3 5x5 5x5 5x5 5x5 5x5 5x5 3x5+2 2x5
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class pack
+{
+ typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+ typedef typename Allocators::node_pointer node_pointer;
+ typedef rtree::node_auto_ptr<Value, Options, Translator, Box, Allocators> node_auto_ptr;
+ typedef typename Allocators::size_type size_type;
+
+ typedef typename traits::point_type<Box>::type point_type;
+ typedef typename traits::coordinate_type<point_type>::type coordinate_type;
+ typedef typename detail::default_content_result<Box>::type content_type;
+ typedef typename Options::parameters_type parameters_type;
+ static const std::size_t dimension = traits::dimension<point_type>::value;
+
+ typedef typename rtree::container_from_elements_type<
+ typename rtree::elements_type<leaf>::type,
+ std::size_t
+ >::type values_counts_container;
+
+ typedef typename rtree::elements_type<internal_node>::type internal_elements;
+ typedef typename internal_elements::value_type internal_element;
+
+public:
+ // Arbitrary iterators
+ template <typename InIt> inline static
+ node_pointer apply(InIt first, InIt last, size_type & values_count, size_type & leafs_level,
+ parameters_type const& parameters, Translator const& translator, Allocators & allocators)
+ {
+ typedef typename std::iterator_traits<InIt>::difference_type diff_type;
+
+ diff_type diff = std::distance(first, last);
+ if ( diff <= 0 )
+ return node_pointer(0);
+
+ typedef std::pair<point_type, InIt> entry_type;
+ std::vector<entry_type> entries;
+
+ values_count = static_cast<size_type>(diff);
+ entries.reserve(values_count);
+
+ Box hint_box;
+ geometry::assign_inverse(hint_box);
+ for ( ; first != last ; ++first )
+ {
+ geometry::expand(hint_box, translator(*first));
+
+ point_type pt;
+ geometry::centroid(translator(*first), pt);
+ entries.push_back(std::make_pair(pt, first));
+ }
+
+ subtree_elements_counts subtree_counts = calculate_subtree_elements_counts(values_count, parameters, leafs_level);
+ internal_element el = per_level(entries.begin(), entries.end(), hint_box, values_count, subtree_counts,
+ parameters, translator, allocators);
+
+ return el.second;
+ }
+
+private:
+ struct subtree_elements_counts
+ {
+ subtree_elements_counts(std::size_t ma, std::size_t mi) : maxc(ma), minc(mi) {}
+ std::size_t maxc;
+ std::size_t minc;
+ };
+
+ template <typename EIt> inline static
+ internal_element per_level(EIt first, EIt last, Box const& hint_box, std::size_t values_count, subtree_elements_counts const& subtree_counts,
+ parameters_type const& parameters, Translator const& translator, Allocators & allocators)
+ {
+ BOOST_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count);
+
+ if ( subtree_counts.maxc <= 1 )
+ {
+ // ROOT or LEAF
+ BOOST_ASSERT(values_count <= parameters.get_max_elements());
+ // if !root check m_parameters.get_min_elements() <= count
+
+ // create new leaf node
+ node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
+ node_auto_ptr auto_remover(n, allocators);
+ leaf & l = rtree::get<leaf>(*n);
+
+ // reserve space for values
+ rtree::elements(l).reserve(values_count); // MAY THROW (A)
+ // calculate values box and copy values
+ Box elements_box;
+ geometry::assign_inverse(elements_box);
+ for ( ; first != last ; ++first )
+ {
+ rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
+ geometry::expand(elements_box, translator(*(first->second)));
+ }
+
+ auto_remover.release();
+ return internal_element(elements_box, n);
+ }
+
+ // calculate next max and min subtree counts
+ subtree_elements_counts next_subtree_counts = subtree_counts;
+ next_subtree_counts.maxc /= parameters.get_max_elements();
+ next_subtree_counts.minc /= parameters.get_max_elements();
+
+ // create new internal node
+ node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
+ node_auto_ptr auto_remover(n, allocators);
+ internal_node & in = rtree::get<internal_node>(*n);
+
+ // reserve space for values
+ std::size_t nodes_count = calculate_nodes_count(values_count, subtree_counts);
+ rtree::elements(in).reserve(nodes_count); // MAY THROW (A)
+ // calculate values box and copy values
+ Box elements_box;
+ geometry::assign_inverse(elements_box);
+
+ per_level_packets(first, last, hint_box, values_count, subtree_counts, next_subtree_counts,
+ rtree::elements(in), elements_box,
+ parameters, translator, allocators);
+
+ auto_remover.release();
+ return internal_element(elements_box, n);
+ }
+
+ template <typename EIt> inline static
+ void per_level_packets(EIt first, EIt last, Box const& hint_box,
+ std::size_t values_count,
+ subtree_elements_counts const& subtree_counts,
+ subtree_elements_counts const& next_subtree_counts,
+ internal_elements & elements, Box & elements_box,
+ parameters_type const& parameters, Translator const& translator, Allocators & allocators)
+ {
+ BOOST_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count);
+
+ BOOST_ASSERT_MSG( subtree_counts.minc <= values_count, "too small number of elements");
+
+ // only one packet
+ if ( values_count <= subtree_counts.maxc )
+ {
+ // the end, move to the next level
+ internal_element el = per_level(first, last, hint_box, values_count, next_subtree_counts,
+ parameters, translator, allocators);
+
+ // in case if push_back() do throw here
+ // and even if this is not probable (previously reserved memory, nonthrowing pairs copy)
+ // this case is also tested by exceptions test.
+ node_auto_ptr auto_remover(el.second, allocators);
+ // this container should have memory allocated, reserve() called outside
+ elements.push_back(el); // MAY THROW (A?,C) - however in normal conditions shouldn't
+ auto_remover.release();
+
+ geometry::expand(elements_box, el.first);
+ return;
+ }
+
+ std::size_t median_count = calculate_median_count(values_count, subtree_counts);
+ EIt median = first + median_count;
+
+ coordinate_type greatest_length;
+ std::size_t greatest_dim_index = 0;
+ pack_utils::biggest_edge<dimension>::apply(hint_box, greatest_length, greatest_dim_index);
+ Box left, right;
+ pack_utils::partial_sort_and_half_boxes<0, dimension>
+ ::apply(first, median, last, hint_box, left, right, greatest_dim_index);
+
+ per_level_packets(first, median, left,
+ median_count, subtree_counts, next_subtree_counts,
+ elements, elements_box,
+ parameters, translator, allocators);
+ per_level_packets(median, last, right,
+ values_count - median_count, subtree_counts, next_subtree_counts,
+ elements, elements_box,
+ parameters, translator, allocators);
+ }
+
+ inline static
+ subtree_elements_counts calculate_subtree_elements_counts(std::size_t elements_count, parameters_type const& parameters, size_type & leafs_level)
+ {
+ (void)parameters;
+
+ subtree_elements_counts res(1, 1);
+ leafs_level = 0;
+
+ std::size_t smax = parameters.get_max_elements();
+ for ( ; smax < elements_count ; smax *= parameters.get_max_elements(), ++leafs_level )
+ res.maxc = smax;
+
+ res.minc = parameters.get_min_elements() * (res.maxc / parameters.get_max_elements());
+
+ return res;
+ }
+
+ inline static
+ std::size_t calculate_nodes_count(std::size_t count,
+ subtree_elements_counts const& subtree_counts)
+ {
+ std::size_t n = count / subtree_counts.maxc;
+ std::size_t r = count % subtree_counts.maxc;
+
+ if ( 0 < r && r < subtree_counts.minc )
+ {
+ std::size_t count_minus_min = count - subtree_counts.minc;
+ n = count_minus_min / subtree_counts.maxc;
+ r = count_minus_min % subtree_counts.maxc;
+ ++n;
+ }
+
+ if ( 0 < r )
+ ++n;
+
+ return n;
+ }
+
+ inline static
+ std::size_t calculate_median_count(std::size_t count,
+ subtree_elements_counts const& subtree_counts)
+ {
+ // e.g. for max = 5, min = 2, count = 52, subtree_max = 25, subtree_min = 10
+
+ std::size_t n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2
+ std::size_t r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2
+ std::size_t median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25
+
+ if ( 0 != r ) // e.g. 0 != 2
+ {
+ if ( subtree_counts.minc <= r ) // e.g. 10 <= 2 == false
+ {
+ //BOOST_ASSERT_MSG(0 < n, "unexpected value");
+ median_count = ((n+1)/2) * subtree_counts.maxc; // if calculated ((2+1)/2) * 25 which would be ok, but not in all cases
+ }
+ else // r < subtree_counts.second // e.g. 2 < 10 == true
+ {
+ std::size_t count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42
+ n = count_minus_min / subtree_counts.maxc; // e.g. 42 / 25 = 1
+ r = count_minus_min % subtree_counts.maxc; // e.g. 42 % 25 = 17
+ if ( r == 0 ) // e.g. false
+ {
+ // n can't be equal to 0 because then there wouldn't be any element in the other node
+ //BOOST_ASSERT_MSG(0 < n, "unexpected value");
+ median_count = ((n+1)/2) * subtree_counts.maxc; // if calculated ((1+1)/2) * 25 which would be ok, but not in all cases
+ }
+ else
+ {
+ if ( n == 0 ) // e.g. false
+ median_count = r; // if calculated -> 17 which is wrong!
+ else
+ median_count = ((n+2)/2) * subtree_counts.maxc; // e.g. ((1+2)/2) * 25 = 25
+ }
+ }
+ }
+
+ return median_count;
+ }
+};
+
+}}}}} // namespace boost::geometry::index::detail::rtree
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_PACK_CREATE_HPP
Modified: branches/release/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -31,7 +31,7 @@
{
typedef typename Elements::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef Box box_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
@@ -57,7 +57,8 @@
indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
box_type enlarged_box;
- geometry::convert(ind1, enlarged_box);
+ //geometry::convert(ind1, enlarged_box);
+ detail::bounds(ind1, enlarged_box);
geometry::expand(enlarged_box, ind2);
content_type free_content = (index::detail::content(enlarged_box) - index::detail::content(ind1)) - index::detail::content(ind2);
@@ -71,7 +72,7 @@
}
}
- BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
+ ::boost::ignore_unused_variable_warning(parameters);
}
};
@@ -100,7 +101,7 @@
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
- typedef typename index::detail::traits::coordinate_type<indexable_type>::type coordinate_type;
+ typedef typename coordinate_type<indexable_type>::type coordinate_type;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
@@ -132,8 +133,10 @@
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
- geometry::convert(rtree::element_indexable(elements_copy[seed1], translator), box1);
- geometry::convert(rtree::element_indexable(elements_copy[seed2], translator), box2);
+ //geometry::convert(rtree::element_indexable(elements_copy[seed1], translator), box1);
+ detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
+ //geometry::convert(rtree::element_indexable(elements_copy[seed2], translator), box2);
+ detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
// remove seeds
if (seed1 < seed2)
@@ -187,8 +190,9 @@
content_increase1, content_increase2);
if ( content_increase1 < content_increase2 ||
- ( content_increase1 == content_increase2 && content1 < content2 ) ||
- ( content1 == content2 && elements1_count <= elements2_count ) )
+ ( content_increase1 == content_increase2 && ( content1 < content2 ||
+ ( content1 == content2 && elements1_count <= elements2_count ) )
+ ) )
{
insert_into_group1 = true;
}
Modified: branches/release/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -47,30 +47,97 @@
parameters_type const& parameters,
size_t node_relative_level)
{
+ ::boost::ignore_unused_variable_warning(parameters);
+
children_type & children = rtree::elements(n);
// children are leafs
if ( node_relative_level <= 1 )
{
- if ( 0 < parameters.get_overlap_cost_threshold() &&
+ /*if ( 0 < parameters.get_overlap_cost_threshold() &&
parameters.get_overlap_cost_threshold() < children.size() )
return choose_by_nearly_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
else
- return choose_by_minimum_overlap_cost(children, indexable);
+ return choose_by_minimum_overlap_cost(children, indexable);*/
+
+ return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
}
// children are internal nodes
else
return choose_by_minimum_content_cost(children, indexable);
-
- BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
}
private:
template <typename Indexable>
static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
- Indexable const& indexable)
+ Indexable const& indexable,
+ size_t overlap_cost_threshold)
{
- size_t children_count = children.size();
+ const size_t children_count = children.size();
+
+ content_type min_content_diff = (std::numeric_limits<content_type>::max)();
+ content_type min_content = (std::numeric_limits<content_type>::max)();
+ size_t choosen_index = 0;
+
+ // create container of children sorted by content enlargement needed to include the new value
+ typedef boost::tuple<size_t, content_type, content_type> child_contents;
+
+ typename rtree::container_from_elements_type<children_type, child_contents>::type children_contents;
+ children_contents.resize(children_count);
+
+ for ( size_t i = 0 ; i < children_count ; ++i )
+ {
+ child_type const& ch_i = children[i];
+
+ // expanded child node's box
+ Box box_exp(ch_i.first);
+ geometry::expand(box_exp, indexable);
+
+ // areas difference
+ content_type content = index::detail::content(box_exp);
+ content_type content_diff = content - index::detail::content(ch_i.first);
+
+ children_contents[i] = boost::make_tuple(i, content_diff, content);
+
+ if ( content_diff < min_content_diff ||
+ (content_diff == min_content_diff && content < min_content) )
+ {
+ min_content_diff = content_diff;
+ min_content = content;
+ choosen_index = i;
+ }
+ }
+
+ // is this assumption ok? if min_content_diff == 0 there is no overlap increase?
+
+ if ( min_content_diff < -std::numeric_limits<double>::epsilon() || std::numeric_limits<double>::epsilon() < min_content_diff )
+ {
+ if ( 0 < overlap_cost_threshold && overlap_cost_threshold < children.size() )
+ {
+ // calculate nearly minimum overlap cost
+
+ // sort by content_diff
+ std::partial_sort(children_contents.begin(), children_contents.begin() + overlap_cost_threshold, children_contents.end(), content_diff_less);
+ choosen_index = choose_by_minimum_overlap_cost_sorted_by_content(children, indexable, children_count, overlap_cost_threshold, children_contents);
+ }
+ else
+ {
+ // calculate minimum overlap cost
+
+ choosen_index = choose_by_minimum_overlap_cost_unsorted_by_content(children, indexable, children_count, children_contents);
+ }
+ }
+
+ return choosen_index;
+ }
+
+ template <typename Indexable, typename ChildrenContents>
+ static inline size_t choose_by_minimum_overlap_cost_unsorted_by_content(children_type const& children,
+ Indexable const& indexable,
+ size_t children_count,
+ ChildrenContents const& children_contents)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements");
// choose index with smallest overlap change value, or content change or smallest content
size_t choosen_index = 0;
@@ -87,12 +154,7 @@
// calculate expanded box of child node ch_i
geometry::expand(box_exp, indexable);
- // calculate content and content diff
- content_type content = index::detail::content(ch_i.first);
- content_type content_diff = index::detail::content(box_exp) - content;
-
- content_type overlap = 0;
- content_type overlap_exp = 0;
+ content_type overlap_diff = 0;
// calculate overlap
for ( size_t j = 0 ; j < children_count ; ++j )
@@ -101,17 +163,22 @@
{
child_type const& ch_j = children[j];
- overlap += index::detail::intersection_content(ch_i.first, ch_j.first);
- overlap_exp += index::detail::intersection_content(box_exp, ch_j.first);
+ content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
+ if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
+ {
+ overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
+ }
}
}
- content_type overlap_diff = overlap_exp - overlap;
+ content_type content = boost::get<2>(children_contents[i]);
+ content_type content_diff = boost::get<1>(children_contents[i]);
// update result
if ( overlap_diff < smallest_overlap_diff ||
- ( overlap_diff == smallest_overlap_diff && content_diff < smallest_content_diff ) ||
- ( content_diff == smallest_content_diff && content < smallest_content ) )
+ ( overlap_diff == smallest_overlap_diff && ( content_diff < smallest_content_diff ||
+ ( content_diff == smallest_content_diff && content < smallest_content ) )
+ ) )
{
smallest_overlap_diff = overlap_diff;
smallest_content_diff = content_diff;
@@ -122,35 +189,16 @@
return choosen_index;
}
-
- template <typename Indexable>
- static inline size_t choose_by_nearly_minimum_overlap_cost(children_type const& children,
- Indexable const& indexable,
- size_t overlap_cost_threshold)
+
+ template <typename Indexable, typename ChildrenContents>
+ static inline size_t choose_by_minimum_overlap_cost_sorted_by_content(children_type const& children,
+ Indexable const& indexable,
+ size_t children_count,
+ size_t overlap_cost_threshold,
+ ChildrenContents const& children_contents)
{
- const size_t children_count = children.size();
-
- // create container of children sorted by content enlargement needed to include the new value
- std::vector< boost::tuple<size_t, content_type, content_type> > sorted_children(children_count);
- for ( size_t i = 0 ; i < children_count ; ++i )
- {
- child_type const& ch_i = children[i];
-
- // expanded child node's box
- Box box_exp(ch_i.first);
- geometry::expand(box_exp, indexable);
-
- // areas difference
- content_type content = index::detail::content(box_exp);
- content_type content_diff = content - index::detail::content(ch_i.first);
-
- sorted_children[i] = boost::make_tuple(i, content_diff, content);
- }
-
- // sort by content_diff
- std::sort(sorted_children.begin(), sorted_children.end(), content_diff_less);
-
- BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold <= children_count, "there are not enough children");
+ BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold < children_count, "unexpected value");
+ BOOST_GEOMETRY_INDEX_ASSERT(children_count == children_contents.size(), "unexpected number of elements");
// for overlap_cost_threshold child nodes find the one with smallest overlap value
size_t choosen_index = 0;
@@ -159,7 +207,7 @@
// for each node
for (size_t i = 0 ; i < overlap_cost_threshold ; ++i )
{
- size_t child_index = boost::get<0>(sorted_children[i]);
+ size_t child_index = boost::get<0>(children_contents[i]);
typedef typename children_type::value_type child_type;
child_type const& ch_i = children[child_index];
@@ -168,8 +216,7 @@
// calculate expanded box of child node ch_i
geometry::expand(box_exp, indexable);
- content_type overlap = 0;
- content_type overlap_exp = 0;
+ content_type overlap_diff = 0;
// calculate overlap
for ( size_t j = 0 ; j < children_count ; ++j )
@@ -178,13 +225,14 @@
{
child_type const& ch_j = children[j];
- overlap += index::detail::intersection_content(ch_i.first, ch_j.first);
- overlap_exp += index::detail::intersection_content(box_exp, ch_j.first);
+ content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
+ if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
+ {
+ overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
+ }
}
}
- content_type overlap_diff = overlap_exp - overlap;
-
// update result
if ( overlap_diff < smallest_overlap_diff )
{
@@ -196,6 +244,138 @@
return choosen_index;
}
+ //template <typename Indexable>
+ //static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
+ // Indexable const& indexable)
+ //{
+ // size_t children_count = children.size();
+
+ // // choose index with smallest overlap change value, or content change or smallest content
+ // size_t choosen_index = 0;
+ // content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
+ // content_type smallest_content_diff = (std::numeric_limits<content_type>::max)();
+ // content_type smallest_content = (std::numeric_limits<content_type>::max)();
+
+ // // for each child node
+ // for (size_t i = 0 ; i < children_count ; ++i )
+ // {
+ // child_type const& ch_i = children[i];
+
+ // Box box_exp(ch_i.first);
+ // // calculate expanded box of child node ch_i
+ // geometry::expand(box_exp, indexable);
+
+ // // calculate content and content diff
+ // content_type content = index::detail::content(box_exp);
+ // content_type content_diff = content - index::detail::content(ch_i.first);
+
+ // content_type overlap_diff = 0;
+ //
+ // // calculate overlap
+ // for ( size_t j = 0 ; j < children_count ; ++j )
+ // {
+ // if ( i != j )
+ // {
+ // child_type const& ch_j = children[j];
+
+ // content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
+ // if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
+ // {
+ // overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
+ // }
+ // }
+ // }
+
+ // // update result
+ // if ( overlap_diff < smallest_overlap_diff ||
+ // ( overlap_diff == smallest_overlap_diff && ( content_diff < smallest_content_diff ||
+ // ( content_diff == smallest_content_diff && content < smallest_content ) )
+ // ) )
+ // {
+ // smallest_overlap_diff = overlap_diff;
+ // smallest_content_diff = content_diff;
+ // smallest_content = content;
+ // choosen_index = i;
+ // }
+ // }
+
+ // return choosen_index;
+ //}
+
+ //template <typename Indexable>
+ //static inline size_t choose_by_nearly_minimum_overlap_cost(children_type const& children,
+ // Indexable const& indexable,
+ // size_t overlap_cost_threshold)
+ //{
+ // const size_t children_count = children.size();
+
+ // // create container of children sorted by content enlargement needed to include the new value
+ // std::vector< boost::tuple<size_t, content_type, content_type> > sorted_children(children_count);
+ // for ( size_t i = 0 ; i < children_count ; ++i )
+ // {
+ // child_type const& ch_i = children[i];
+
+ // // expanded child node's box
+ // Box box_exp(ch_i.first);
+ // geometry::expand(box_exp, indexable);
+
+ // // areas difference
+ // content_type content = index::detail::content(box_exp);
+ // content_type content_diff = content - index::detail::content(ch_i.first);
+
+ // sorted_children[i] = boost::make_tuple(i, content_diff, content);
+ // }
+
+ // BOOST_GEOMETRY_INDEX_ASSERT(overlap_cost_threshold <= children_count, "there is not enough children");
+
+ // // sort by content_diff
+ // //std::sort(sorted_children.begin(), sorted_children.end(), content_diff_less);
+ // std::partial_sort(sorted_children.begin(), sorted_children.begin() + overlap_cost_threshold, sorted_children.end(), content_diff_less);
+
+ // // for overlap_cost_threshold child nodes find the one with smallest overlap value
+ // size_t choosen_index = 0;
+ // content_type smallest_overlap_diff = (std::numeric_limits<content_type>::max)();
+
+ // // for each node
+ // for (size_t i = 0 ; i < overlap_cost_threshold ; ++i )
+ // {
+ // size_t child_index = boost::get<0>(sorted_children[i]);
+
+ // typedef typename children_type::value_type child_type;
+ // child_type const& ch_i = children[child_index];
+
+ // Box box_exp(ch_i.first);
+ // // calculate expanded box of child node ch_i
+ // geometry::expand(box_exp, indexable);
+
+ // content_type overlap_diff = 0;
+
+ // // calculate overlap
+ // for ( size_t j = 0 ; j < children_count ; ++j )
+ // {
+ // if ( child_index != j )
+ // {
+ // child_type const& ch_j = children[j];
+
+ // content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
+ // if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
+ // {
+ // overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
+ // }
+ // }
+ // }
+
+ // // update result
+ // if ( overlap_diff < smallest_overlap_diff )
+ // {
+ // smallest_overlap_diff = overlap_diff;
+ // choosen_index = child_index;
+ // }
+ // }
+
+ // return choosen_index;
+ //}
+
static inline bool content_diff_less(boost::tuple<size_t, content_type, content_type> const& p1, boost::tuple<size_t, content_type, content_type> const& p2)
{
return boost::get<1>(p1) < boost::get<1>(p2) ||
Modified: branches/release/boost/geometry/index/detail/rtree/rstar/insert.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/rstar/insert.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/rstar/insert.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -118,7 +118,7 @@
}
BOOST_CATCH_END
- BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
+ ::boost::ignore_unused_variable_warning(parameters);
}
private:
Modified: branches/release/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -25,9 +25,33 @@
namespace rstar {
-template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
+template <typename Element, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
class element_axis_corner_less
{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
+};
+
+template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
+class element_axis_corner_less<Element, Translator, box_tag, Corner, AxisIndex>
+{
+public:
+ element_axis_corner_less(Translator const& tr)
+ : m_tr(tr)
+ {}
+
+ bool operator()(Element const& e1, Element const& e2) const
+ {
+ return geometry::get<Corner, AxisIndex>(rtree::element_indexable(e1, m_tr))
+ < geometry::get<Corner, AxisIndex>(rtree::element_indexable(e2, m_tr));
+ }
+
+private:
+ Translator const& m_tr;
+};
+
+template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
+class element_axis_corner_less<Element, Translator, point_tag, Corner, AxisIndex>
+{
public:
element_axis_corner_less(Translator const& tr)
: m_tr(tr)
@@ -35,8 +59,8 @@
bool operator()(Element const& e1, Element const& e2) const
{
- return index::detail::get<Corner, AxisIndex>(rtree::element_indexable(e1, m_tr))
- < index::detail::get<Corner, AxisIndex>(rtree::element_indexable(e2, m_tr));
+ return geometry::get<AxisIndex>(rtree::element_indexable(e1, m_tr))
+ < geometry::get<AxisIndex>(rtree::element_indexable(e2, m_tr));
}
private:
@@ -59,6 +83,8 @@
Translator const& translator)
{
typedef typename Elements::value_type element_type;
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+ typedef typename tag<indexable_type>::type indexable_tag;
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == parameters.get_max_elements() + 1, "wrong number of elements");
@@ -66,7 +92,7 @@
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
// sort elements
- element_axis_corner_less<element_type, Translator, Corner, AxisIndex> elements_less(translator);
+ element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// init outputs
@@ -90,6 +116,7 @@
content_type ovl = index::detail::intersection_content(box1, box2);
content_type con = index::detail::content(box1) + index::detail::content(box2);
+ // TODO - shouldn't here be < instead of <= ?
if ( ovl < smallest_overlap || (ovl == smallest_overlap && con <= smallest_content) )
{
choosen_index = i;
@@ -98,14 +125,14 @@
}
}
- BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters)
+ ::boost::ignore_unused_variable_warning(parameters);
}
};
template <typename Parameters, typename Box, size_t AxisIndex, typename ElementIndexableTag>
struct choose_split_axis_and_index_for_axis
{
- //BOOST_STATIC_ASSERT(0);
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
};
template <typename Parameters, typename Box, size_t AxisIndex>
@@ -226,7 +253,7 @@
Parameters,
Box,
Dimension - 1,
- typename index::detail::traits::tag<element_indexable_type>::type
+ typename tag<element_indexable_type>::type
>::apply(elements, corner, index, sum_of_margins, overlap_val, content_val, parameters, translator); // MAY THROW, STRONG
if ( sum_of_margins < smallest_sum_of_margins )
@@ -266,7 +293,7 @@
Parameters,
Box,
0,
- typename index::detail::traits::tag<element_indexable_type>::type
+ typename tag<element_indexable_type>::type
>::apply(elements, choosen_corner, choosen_index, smallest_sum_of_margins, smallest_overlap, smallest_content, parameters, translator); // MAY THROW
}
};
@@ -288,7 +315,10 @@
BOOST_GEOMETRY_INDEX_ASSERT(axis == Dimension - 1, "unexpected axis value");
typedef typename Elements::value_type element_type;
- element_axis_corner_less<element_type, Translator, Corner, Dimension - 1> less(tr);
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+ typedef typename tag<indexable_type>::type indexable_tag;
+
+ element_axis_corner_less<element_type, Translator, indexable_tag, Corner, Dimension - 1> less(tr);
std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
}
@@ -306,7 +336,10 @@
BOOST_GEOMETRY_INDEX_ASSERT(axis == 0, "unexpected axis value");
typedef typename Elements::value_type element_type;
- element_axis_corner_less<element_type, Translator, Corner, 0> less(tr);
+ typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
+ typedef typename tag<indexable_type>::type indexable_tag;
+
+ element_axis_corner_less<element_type, Translator, indexable_tag, Corner, 0> less(tr);
std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
};
@@ -322,7 +355,7 @@
typedef typename Options::parameters_type parameters_type;
- static const size_t dimension = index::detail::traits::dimension<Box>::value;
+ static const size_t dimension = geometry::dimension<Box>::value;
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
@@ -352,7 +385,7 @@
rstar::choose_split_axis_and_index<
typename Options::parameters_type,
Box,
- index::detail::traits::dimension<Box>::value
+ dimension
>::apply(elements1,
split_axis, split_corner, split_index,
smallest_sum_of_margins, smallest_overlap, smallest_content,
@@ -360,7 +393,7 @@
// TODO: awulkiew - get rid of following static_casts?
- BOOST_GEOMETRY_INDEX_ASSERT(split_axis < index::detail::traits::dimension<Box>::value, "unexpected value");
+ BOOST_GEOMETRY_INDEX_ASSERT(split_axis < dimension, "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(split_corner == static_cast<size_t>(min_corner) || split_corner == static_cast<size_t>(max_corner), "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= split_index && split_index <= parameters.get_max_elements() - parameters.get_min_elements() + 1, "unexpected value");
Copied: branches/release/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp)
@@ -0,0 +1,140 @@
+// Boost.Geometry Index
+//
+// R-tree boxes validating visitor implementation
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_BOXES_OK_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_BOXES_OK_HPP
+
+#include <boost/geometry/algorithms/equals.hpp>
+#include <boost/geometry/index/detail/rtree/node/node.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
+
+namespace visitors {
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+class are_boxes_ok
+ : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+public:
+ are_boxes_ok(Translator const& tr, bool exact_match)
+ : result(false), m_tr(tr), m_is_root(true), m_exact_match(exact_match)
+ {}
+
+ void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ if (elements.empty())
+ {
+ result = false;
+ return;
+ }
+
+ Box box_bckup = m_box;
+ bool is_root_bckup = m_is_root;
+
+ m_is_root = false;
+
+ for ( typename elements_type::const_iterator it = elements.begin();
+ it != elements.end() ; ++it)
+ {
+ m_box = it->first;
+
+ rtree::apply_visitor(*this, *it->second);
+
+ if ( result == false )
+ return;
+ }
+
+ m_box = box_bckup;
+ m_is_root = is_root_bckup;
+
+ Box box_exp;
+ geometry::convert(elements.front().first, box_exp);
+ for( typename elements_type::const_iterator it = elements.begin() + 1;
+ it != elements.end() ; ++it)
+ {
+ geometry::expand(box_exp, it->first);
+ }
+
+ if ( m_exact_match )
+ result = m_is_root || geometry::equals(box_exp, m_box);
+ else
+ result = m_is_root || geometry::covered_by(box_exp, m_box);
+ }
+
+ void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type<leaf>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ // non-root node
+ if (!m_is_root)
+ {
+ if ( elements.empty() )
+ {
+ result = false;
+ return;
+ }
+
+ Box box_exp;
+ geometry::convert(m_tr(elements.front()), box_exp);
+ for(typename elements_type::const_iterator it = elements.begin() + 1;
+ it != elements.end() ; ++it)
+ {
+ geometry::expand(box_exp, m_tr(*it));
+ }
+
+ if ( m_exact_match )
+ result = geometry::equals(box_exp, m_box);
+ else
+ result = geometry::covered_by(box_exp, m_box);
+ }
+ else
+ result = true;
+ }
+
+ bool result;
+
+private:
+ Translator const& m_tr;
+ Box m_box;
+ bool m_is_root;
+ bool m_exact_match;
+};
+
+} // namespace visitors
+
+template <typename Rtree> inline
+bool are_boxes_ok(Rtree const& tree, bool exact_match = true)
+{
+ typedef utilities::view<Rtree> RTV;
+ RTV rtv(tree);
+
+ visitors::are_boxes_ok<
+ typename RTV::value_type,
+ typename RTV::options_type,
+ typename RTV::translator_type,
+ typename RTV::box_type,
+ typename RTV::allocators_type
+ > v(rtv.translator(), exact_match);
+
+ rtv.apply_visitor(v);
+
+ return v.result;
+}
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::utilities
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_BOXES_OK_HPP
Copied: branches/release/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp)
@@ -0,0 +1,109 @@
+// Boost.Geometry Index
+//
+// R-tree levels validating visitor implementation
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
+
+#include <boost/geometry/index/detail/rtree/node/node.hpp>
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
+
+namespace visitors {
+
+template <typename Value, typename Options, typename Box, typename Allocators>
+class are_levels_ok
+ : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+public:
+ inline are_levels_ok()
+ : result(true), m_leafs_level((std::numeric_limits<size_t>::max)()), m_current_level(0)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ if (elements.empty())
+ {
+ result = false;
+ return;
+ }
+
+ size_t current_level_backup = m_current_level;
+ ++m_current_level;
+
+ for ( typename elements_type::const_iterator it = elements.begin();
+ it != elements.end() ; ++it)
+ {
+ rtree::apply_visitor(*this, *it->second);
+
+ if ( result == false )
+ return;
+ }
+
+ m_current_level = current_level_backup;
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type<leaf>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ // empty leaf in non-root node
+ if (0 < m_current_level && elements.empty())
+ {
+ result = false;
+ return;
+ }
+
+ if ( m_leafs_level == (std::numeric_limits<size_t>::max)() )
+ {
+ m_leafs_level = m_current_level;
+ }
+ else if ( m_leafs_level != m_current_level )
+ {
+ result = false;
+ }
+ }
+
+ bool result;
+
+private:
+ size_t m_leafs_level;
+ size_t m_current_level;
+};
+
+} // namespace visitors
+
+template <typename Rtree> inline
+bool are_levels_ok(Rtree const& tree)
+{
+ typedef utilities::view<Rtree> RTV;
+ RTV rtv(tree);
+
+ visitors::are_levels_ok<
+ typename RTV::value_type,
+ typename RTV::options_type,
+ typename RTV::box_type,
+ typename RTV::allocators_type
+ > v;
+
+ rtv.apply_visitor(v);
+
+ return v.result;
+}
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::utilities
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
Copied: branches/release/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp)
@@ -0,0 +1,223 @@
+// Boost.Geometry Index
+//
+// R-tree OpenGL drawing visitor implementation
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace utilities {
+
+namespace dispatch {
+
+template <typename Point, size_t Dimension>
+struct gl_draw_point
+{};
+
+template <typename Point>
+struct gl_draw_point<Point, 2>
+{
+ static inline void apply(Point const& p, typename coordinate_type<Point>::type z)
+ {
+ glBegin(GL_POINT);
+ glVertex3f(geometry::get<0>(p), geometry::get<1>(p), z);
+ glEnd();
+ }
+};
+
+template <typename Box, size_t Dimension>
+struct gl_draw_box
+{};
+
+template <typename Box>
+struct gl_draw_box<Box, 2>
+{
+ static inline void apply(Box const& b, typename coordinate_type<Box>::type z)
+ {
+ glBegin(GL_LINE_LOOP);
+ glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
+ glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
+ glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
+ glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
+ glEnd();
+ }
+};
+
+template <typename Indexable, typename Tag>
+struct gl_draw_indexable
+{
+};
+
+template <typename Indexable>
+struct gl_draw_indexable<Indexable, box_tag>
+{
+ static const size_t dimension = dimension<Indexable>::value;
+
+ static inline void apply(Indexable const& i, typename coordinate_type<Indexable>::type z)
+ {
+ gl_draw_box<Indexable, dimension>::apply(i, z);
+ }
+};
+
+template <typename Indexable>
+struct gl_draw_indexable<Indexable, point_tag>
+{
+ static const size_t dimension = dimension<Indexable>::value;
+
+ static inline void apply(Indexable const& i, typename coordinate_type<Indexable>::type z)
+ {
+ gl_draw_point<Indexable, dimension>::apply(i, z);
+ }
+};
+
+} // namespace dispatch
+
+template <typename Indexable> inline
+void gl_draw_indexable(Indexable const& i, typename coordinate_type<Indexable>::type z)
+{
+ dispatch::gl_draw_indexable<
+ Indexable,
+ typename tag<Indexable>::type
+ >::apply(i, z);
+}
+
+} // namespace utilities
+
+namespace rtree { namespace utilities {
+
+namespace visitors {
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+ inline gl_draw(Translator const& t,
+ size_t level_first = 0,
+ size_t level_last = (std::numeric_limits<size_t>::max)(),
+ typename coordinate_type<Box>::type z_coord_level_multiplier = 1
+ )
+ : tr(t)
+ , level_f(level_first)
+ , level_l(level_last)
+ , z_mul(z_coord_level_multiplier)
+ , level(0)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ if ( level_f <= level )
+ {
+ size_t level_rel = level - level_f;
+
+ if ( level_rel == 0 )
+ glColor3f(0.75f, 0.0f, 0.0f);
+ else if ( level_rel == 1 )
+ glColor3f(0.0f, 0.75f, 0.0f);
+ else if ( level_rel == 2 )
+ glColor3f(0.0f, 0.0f, 0.75f);
+ else if ( level_rel == 3 )
+ glColor3f(0.75f, 0.75f, 0.0f);
+ else if ( level_rel == 4 )
+ glColor3f(0.75f, 0.0f, 0.75f);
+ else if ( level_rel == 5 )
+ glColor3f(0.0f, 0.75f, 0.75f);
+ else
+ glColor3f(0.5f, 0.5f, 0.5f);
+
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ detail::utilities::gl_draw_indexable(it->first, level_rel * z_mul);
+ }
+ }
+
+ size_t level_backup = level;
+ ++level;
+
+ if ( level < level_l )
+ {
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ rtree::apply_visitor(*this, *it->second);
+ }
+ }
+
+ level = level_backup;
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type<leaf>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ if ( level_f <= level )
+ {
+ size_t level_rel = level - level_f;
+
+ glColor3f(0.25f, 0.25f, 0.25f);
+
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ detail::utilities::gl_draw_indexable(tr(*it), level_rel * z_mul);
+ }
+ }
+ }
+
+ Translator const& tr;
+ size_t level_f;
+ size_t level_l;
+ typename coordinate_type<Box>::type z_mul;
+
+ size_t level;
+};
+
+} // namespace visitors
+
+template <typename Rtree> inline
+void gl_draw(Rtree const& tree,
+ size_t level_first = 0,
+ size_t level_last = (std::numeric_limits<size_t>::max)(),
+ typename coordinate_type<
+ typename Rtree::bounds_type
+ >::type z_coord_level_multiplier = 1
+ )
+{
+ typedef utilities::view<Rtree> RTV;
+ RTV rtv(tree);
+
+ if ( !tree.empty() )
+ {
+ glColor3f(0.75f, 0.75f, 0.75f);
+ detail::utilities::gl_draw_indexable(tree.bounds(), 0);
+ }
+
+ visitors::gl_draw<
+ typename RTV::value_type,
+ typename RTV::options_type,
+ typename RTV::translator_type,
+ typename RTV::box_type,
+ typename RTV::allocators_type
+ > gl_draw_v(rtv.translator(), level_first, level_last, z_coord_level_multiplier);
+
+ rtv.apply_visitor(gl_draw_v);
+}
+
+}} // namespace rtree::utilities
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
Copied: branches/release/boost/geometry/index/detail/rtree/utilities/print.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/utilities/print.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/utilities/print.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/utilities/print.hpp)
@@ -0,0 +1,203 @@
+// Boost.Geometry Index
+//
+// R-tree ostreaming visitor implementation
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_PRINT_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_PRINT_HPP
+
+#include <iostream>
+
+namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace utilities {
+
+namespace dispatch {
+
+template <typename Point, size_t Dimension>
+struct print_point
+{
+ BOOST_STATIC_ASSERT(0 < Dimension);
+
+ static inline void apply(std::ostream & os, Point const& p)
+ {
+ print_point<Point, Dimension - 1>::apply(os, p);
+
+ os << ", " << geometry::get<Dimension - 1>(p);
+ }
+};
+
+template <typename Point>
+struct print_point<Point, 1>
+{
+ static inline void apply(std::ostream & os, Point const& p)
+ {
+ os << geometry::get<0>(p);
+ }
+};
+
+template <typename Box, size_t Corner, size_t Dimension>
+struct print_corner
+{
+ BOOST_STATIC_ASSERT(0 < Dimension);
+
+ static inline void apply(std::ostream & os, Box const& b)
+ {
+ print_corner<Box, Corner, Dimension - 1>::apply(os, b);
+
+ os << ", " << geometry::get<Corner, Dimension - 1>(b);
+ }
+};
+
+template <typename Box, size_t Corner>
+struct print_corner<Box, Corner, 1>
+{
+ static inline void apply(std::ostream & os, Box const& b)
+ {
+ os << geometry::get<Corner, 0>(b);
+ }
+};
+
+template <typename Indexable, typename Tag>
+struct print_indexable
+{
+};
+
+template <typename Indexable>
+struct print_indexable<Indexable, box_tag>
+{
+ static const size_t dimension = dimension<Indexable>::value;
+
+ static inline void apply(std::ostream &os, Indexable const& i)
+ {
+ os << '(';
+ print_corner<Indexable, min_corner, dimension>::apply(os, i);
+ os << ")x(";
+ print_corner<Indexable, max_corner, dimension>::apply(os, i);
+ os << ')';
+ }
+};
+
+template <typename Indexable>
+struct print_indexable<Indexable, point_tag>
+{
+ static const size_t dimension = dimension<Indexable>::value;
+
+ static inline void apply(std::ostream &os, Indexable const& i)
+ {
+ os << '(';
+ print_point<Indexable, dimension>::apply(os, i);
+ os << ')';
+ }
+};
+
+} // namespace dispatch
+
+template <typename Indexable> inline
+void print_indexable(std::ostream & os, Indexable const& i)
+{
+ dispatch::print_indexable<
+ Indexable,
+ typename tag<Indexable>::type
+ >::apply(os, i);
+}
+
+} // namespace utilities
+
+namespace rtree { namespace utilities {
+
+namespace visitors {
+
+template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
+struct print : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+ inline print(std::ostream & o, Translator const& t)
+ : os(o), tr(t), level(0)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ spaces(level) << "INTERNAL NODE - L:" << level << " Ch:" << elements.size() << " @:" << &n << '\n';
+
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ spaces(level);
+ detail::utilities::print_indexable(os, it->first);
+ os << " ->" << it->second << '\n';
+ }
+
+ size_t level_backup = level;
+ ++level;
+
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ rtree::apply_visitor(*this, *it->second);
+ }
+
+ level = level_backup;
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type<leaf>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ spaces(level) << "LEAF - L:" << level << " V:" << elements.size() << " @:" << &n << '\n';
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ spaces(level);
+ detail::utilities::print_indexable(os, tr(*it));
+ os << '\n';
+ }
+ }
+
+ inline std::ostream & spaces(size_t level)
+ {
+ for ( size_t i = 0 ; i < 2 * level ; ++i )
+ os << ' ';
+ return os;
+ }
+
+ std::ostream & os;
+ Translator const& tr;
+
+ size_t level;
+};
+
+} // namespace visitors
+
+template <typename Rtree> inline
+void print(std::ostream & os, Rtree const& tree)
+{
+ typedef utilities::view<Rtree> RTV;
+ RTV rtv(tree);
+
+ visitors::print<
+ typename RTV::value_type,
+ typename RTV::options_type,
+ typename RTV::translator_type,
+ typename RTV::box_type,
+ typename RTV::allocators_type
+ > print_v(os, rtv.translator());
+ rtv.apply_visitor(print_v);
+}
+
+}} // namespace rtree::utilities
+
+}}}} // namespace boost::geometry::index::detail
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_PRINT_HPP
Copied: branches/release/boost/geometry/index/detail/rtree/utilities/statistics.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/utilities/statistics.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/utilities/statistics.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/utilities/statistics.hpp)
@@ -0,0 +1,105 @@
+// Boost.Geometry Index
+//
+// R-tree visitor collecting basic statistics
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2013 Mateusz Loskot, London, UK.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
+
+#include <algorithm>
+#include <tuple>
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
+
+namespace visitors {
+
+template <typename Value, typename Options, typename Box, typename Allocators>
+struct statistics : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
+{
+ typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
+ typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
+
+ inline statistics()
+ : level(0)
+ , levels(1) // count root
+ , nodes(0)
+ , leaves(0)
+ , values(0)
+ , values_min(0)
+ , values_max(0)
+ {}
+
+ inline void operator()(internal_node const& n)
+ {
+ typedef typename rtree::elements_type<internal_node>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ ++nodes; // count node
+
+ size_t const level_backup = level;
+ ++level;
+
+ levels += level++ > levels ? 1 : 0; // count level (root already counted)
+
+ for (typename elements_type::const_iterator it = elements.begin();
+ it != elements.end(); ++it)
+ {
+ rtree::apply_visitor(*this, *it->second);
+ }
+
+ level = level_backup;
+ }
+
+ inline void operator()(leaf const& n)
+ {
+ typedef typename rtree::elements_type<leaf>::type elements_type;
+ elements_type const& elements = rtree::elements(n);
+
+ ++leaves; // count leaves
+
+ std::size_t const v = elements.size();
+ // count values spread per node and total
+ values_min = (std::min)(values_min == 0 ? v : values_min, v);
+ values_max = (std::max)(values_max, v);
+ values += v;
+ }
+
+ std::size_t level;
+ std::size_t levels;
+ std::size_t nodes;
+ std::size_t leaves;
+ std::size_t values;
+ std::size_t values_min;
+ std::size_t values_max;
+};
+
+} // namespace visitors
+
+template <typename Rtree> inline
+boost::tuple<std::size_t, std::size_t, std::size_t, std::size_t, std::size_t, std::size_t>
+statistics(Rtree const& tree)
+{
+ typedef utilities::view<Rtree> RTV;
+ RTV rtv(tree);
+
+ visitors::statistics<
+ typename RTV::value_type,
+ typename RTV::options_type,
+ typename RTV::box_type,
+ typename RTV::allocators_type
+ > stats_v;
+
+ rtv.apply_visitor(stats_v);
+
+ return boost::make_tuple(stats_v.levels, stats_v.nodes, stats_v.leaves, stats_v.values, stats_v.values_min, stats_v.values_max);
+}
+
+}}}}}} // namespace boost::geometry::index::detail::rtree::utilities
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
Copied: branches/release/boost/geometry/index/detail/rtree/utilities/view.hpp (from r84886, trunk/boost/geometry/index/detail/rtree/utilities/view.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/rtree/utilities/view.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/rtree/utilities/view.hpp)
@@ -0,0 +1,61 @@
+// Boost.Geometry Index
+//
+// Rtree utilities view
+//
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_VIEW_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_VIEW_HPP
+
+namespace boost { namespace geometry { namespace index {
+
+namespace detail { namespace rtree { namespace utilities {
+
+template <typename Rtree>
+class view
+{
+public:
+ typedef typename Rtree::size_type size_type;
+
+ typedef typename Rtree::translator_type translator_type;
+ typedef typename Rtree::value_type value_type;
+ typedef typename Rtree::options_type options_type;
+ typedef typename Rtree::box_type box_type;
+ typedef typename Rtree::allocators_type allocators_type;
+
+ view(Rtree const& rt) : m_rtree(rt) {}
+
+ template <typename Visitor>
+ void apply_visitor(Visitor & vis) const
+ {
+ m_rtree.apply_visitor(vis);
+ }
+
+ // This will most certainly be removed in the future
+ translator_type translator() const
+ {
+ return m_rtree.translator();
+ }
+
+ // This will probably be removed in the future
+ size_type depth() const
+ {
+ return m_rtree.depth();
+ }
+
+private:
+ view(view const&);
+ view & operator=(view const&);
+
+ Rtree const& m_rtree;
+};
+
+}}} // namespace detail::rtree::utilities
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_VIEW_HPP
Deleted: branches/release/boost/geometry/index/detail/rtree/visitors/are_boxes_ok.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/visitors/are_boxes_ok.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84888)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,144 +0,0 @@
-// Boost.Geometry Index
-//
-// R-tree boxes validating visitor implementation
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ARE_BOXES_OK_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ARE_BOXES_OK_HPP
-
-#include <boost/geometry/algorithms/equals.hpp>
-#include <boost/geometry/index/detail/rtree/node/node.hpp>
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
-
-namespace visitors {
-
-template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-class are_boxes_ok
- : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
-{
- typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
- typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
-
-public:
- are_boxes_ok(Translator const& tr, bool exact_match)
- : result(false), m_tr(tr), m_is_root(true), m_exact_match(exact_match)
- {}
-
- void operator()(internal_node const& n)
- {
- typedef typename rtree::elements_type<internal_node>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- if (elements.empty())
- {
- result = false;
- return;
- }
-
- Box box_bckup = m_box;
- bool is_root_bckup = m_is_root;
-
- m_is_root = false;
-
- for ( typename elements_type::const_iterator it = elements.begin();
- it != elements.end() ; ++it)
- {
- m_box = it->first;
-
- rtree::apply_visitor(*this, *it->second);
-
- if ( result == false )
- return;
- }
-
- m_box = box_bckup;
- m_is_root = is_root_bckup;
-
- Box box_exp;
- geometry::convert(elements.front().first, box_exp);
- for( typename elements_type::const_iterator it = elements.begin() + 1;
- it != elements.end() ; ++it)
- {
- geometry::expand(box_exp, it->first);
- }
-
- if ( m_exact_match )
- result = m_is_root || geometry::equals(box_exp, m_box);
- else
- result = m_is_root || geometry::covered_by(box_exp, m_box);
- }
-
- void operator()(leaf const& n)
- {
- typedef typename rtree::elements_type<leaf>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- // non-root node
- if (!m_is_root)
- {
- if ( elements.empty() )
- {
- result = false;
- return;
- }
-
- Box box_exp;
- geometry::convert(m_tr(elements.front()), box_exp);
- for(typename elements_type::const_iterator it = elements.begin() + 1;
- it != elements.end() ; ++it)
- {
- geometry::expand(box_exp, m_tr(*it));
- }
-
- if ( m_exact_match )
- result = geometry::equals(box_exp, m_box);
- else
- result = geometry::covered_by(box_exp, m_box);
- }
- else
- result = true;
- }
-
- bool result;
-
-private:
- Translator const& m_tr;
- Box m_box;
- bool m_is_root;
- bool m_exact_match;
-};
-
-} // namespace visitors
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE
-#error "To use are_boxes_ok BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE should be defined before including the rtree"
-#endif
-
-template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
-bool are_boxes_ok(index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
- bool exact_match = true)
-{
- typedef index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> rt;
-
- detail::rtree::visitors::are_boxes_ok<
- typename rt::value_type,
- typename rt::options_type,
- typename rt::translator_type,
- typename rt::box_type,
- typename rt::allocators_type
- > v(tree.translator(), exact_match);
-
- tree.apply_visitor(v);
-
- return v.result;
-}
-
-}}}}} // namespace boost::geometry::index::detail::rtree
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ARE_BOXES_OK_HPP
Deleted: branches/release/boost/geometry/index/detail/rtree/visitors/are_levels_ok.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/visitors/are_levels_ok.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84888)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,114 +0,0 @@
-// Boost.Geometry Index
-//
-// R-tree levels validating visitor implementation
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ARE_LEVELS_OK_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ARE_LEVELS_OK_HPP
-
-#include <boost/geometry/index/detail/rtree/node/node.hpp>
-
-namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
-
-namespace visitors {
-
-template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-class are_levels_ok
- : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
-{
- typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
- typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
-
-public:
- inline are_levels_ok(Translator const& tr)
- : result(true), m_tr(tr), m_leafs_level((std::numeric_limits<size_t>::max)()), m_current_level(0)
- {}
-
- inline void operator()(internal_node const& n)
- {
- typedef typename rtree::elements_type<internal_node>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- if (elements.empty())
- {
- result = false;
- return;
- }
-
- size_t current_level_backup = m_current_level;
- ++m_current_level;
-
- for ( typename elements_type::const_iterator it = elements.begin();
- it != elements.end() ; ++it)
- {
- rtree::apply_visitor(*this, *it->second);
-
- if ( result == false )
- return;
- }
-
- m_current_level = current_level_backup;
- }
-
- inline void operator()(leaf const& n)
- {
- typedef typename rtree::elements_type<leaf>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- // empty leaf in non-root node
- if (0 < m_current_level && elements.empty())
- {
- result = false;
- return;
- }
-
- if ( m_leafs_level == (std::numeric_limits<size_t>::max)() )
- {
- m_leafs_level = m_current_level;
- }
- else if ( m_leafs_level != m_current_level )
- {
- result = false;
- }
- }
-
- bool result;
-
-private:
- Translator const& m_tr;
- size_t m_leafs_level;
- size_t m_current_level;
-};
-
-} // namespace visitors
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE
-#error "To use are_levels_ok() BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE should be defined before including the rtree"
-#endif
-
-template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
-bool are_levels_ok(index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
-{
- typedef index::rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> rt;
-
- detail::rtree::visitors::are_levels_ok<
- typename rt::value_type,
- typename rt::options_type,
- typename rt::translator_type,
- typename rt::box_type,
- typename rt::allocators_type
- > v(tree.translator());
-
- tree.apply_visitor(v);
-
- return v.result;
-}
-
-}}}}} // namespace boost::geometry::index::detail::rtree
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ARE_LEVELS_OK_HPP
Deleted: branches/release/boost/geometry/index/detail/rtree/visitors/gl_draw.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/visitors/gl_draw.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84888)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,221 +0,0 @@
-// Boost.Geometry Index
-//
-// R-tree OpenGL drawing visitor implementation
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_GL_DRAW_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_GL_DRAW_HPP
-
-#include <boost/geometry/index/detail/indexable.hpp>
-
-namespace boost { namespace geometry { namespace index {
-
-namespace detail { namespace rtree { namespace visitors {
-
-namespace dispatch {
-
-template <typename Point, size_t Dimension>
-struct gl_draw_point
-{};
-
-template <typename Point>
-struct gl_draw_point<Point, 2>
-{
- static inline void apply(Point const& p, typename index::detail::traits::coordinate_type<Point>::type z)
- {
- glBegin(GL_POINT);
- glVertex3f(geometry::get<0>(p), geometry::get<1>(p), z);
- glEnd();
- }
-};
-
-template <typename Box, size_t Dimension>
-struct gl_draw_box
-{};
-
-template <typename Box>
-struct gl_draw_box<Box, 2>
-{
- static inline void apply(Box const& b, typename index::detail::traits::coordinate_type<Box>::type z)
- {
- glBegin(GL_LINE_LOOP);
- glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
- glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
- glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
- glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
- glEnd();
- }
-};
-
-template <typename Indexable, typename Tag>
-struct gl_draw_indexable
-{
-};
-
-template <typename Indexable>
-struct gl_draw_indexable<Indexable, box_tag>
-{
- static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
-
- static inline void apply(Indexable const& i, typename index::detail::traits::coordinate_type<Indexable>::type z)
- {
- gl_draw_box<Indexable, dimension>::apply(i, z);
- }
-};
-
-template <typename Indexable>
-struct gl_draw_indexable<Indexable, point_tag>
-{
- static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
-
- static inline void apply(Indexable const& i, typename index::detail::traits::coordinate_type<Indexable>::type z)
- {
- gl_draw_point<Indexable, dimension>::apply(i, z);
- }
-};
-
-} // namespace dispatch
-
-namespace detail {
-
-template <typename Indexable>
-inline void gl_draw_indexable(Indexable const& i, typename index::detail::traits::coordinate_type<Indexable>::type z)
-{
- dispatch::gl_draw_indexable<
- Indexable,
- typename index::detail::traits::tag<Indexable>::type
- >::apply(i, z);
-}
-
-} // namespace detail
-
-template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
-{
- typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
- typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
-
- inline gl_draw(Translator const& t,
- size_t level_first = 0,
- size_t level_last = (std::numeric_limits<size_t>::max)(),
- typename index::detail::traits::coordinate_type<Box>::type z_coord_level_multiplier = 1
- )
- : tr(t)
- , level_f(level_first)
- , level_l(level_last)
- , z_mul(z_coord_level_multiplier)
- , level(0)
- {}
-
- inline void operator()(internal_node const& n)
- {
- typedef typename rtree::elements_type<internal_node>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- if ( level_f <= level )
- {
- size_t level_rel = level - level_f;
-
- if ( level_rel == 0 )
- glColor3f(0.75f, 0.0f, 0.0f);
- else if ( level_rel == 1 )
- glColor3f(0.0f, 0.75f, 0.0f);
- else if ( level_rel == 2 )
- glColor3f(0.0f, 0.0f, 0.75f);
- else if ( level_rel == 3 )
- glColor3f(0.75f, 0.75f, 0.0f);
- else if ( level_rel == 4 )
- glColor3f(0.75f, 0.0f, 0.75f);
- else if ( level_rel == 5 )
- glColor3f(0.0f, 0.75f, 0.75f);
- else
- glColor3f(0.5f, 0.5f, 0.5f);
-
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- detail::gl_draw_indexable(it->first, level_rel * z_mul);
- }
- }
-
- size_t level_backup = level;
- ++level;
-
- if ( level < level_l )
- {
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- rtree::apply_visitor(*this, *it->second);
- }
- }
-
- level = level_backup;
- }
-
- inline void operator()(leaf const& n)
- {
- typedef typename rtree::elements_type<leaf>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- if ( level_f <= level )
- {
- size_t level_rel = level - level_f;
-
- glColor3f(0.25f, 0.25f, 0.25f);
-
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- detail::gl_draw_indexable(tr(*it), level_rel * z_mul);
- }
- }
- }
-
- Translator const& tr;
- size_t level_f;
- size_t level_l;
- typename index::detail::traits::coordinate_type<Box>::type z_mul;
-
- size_t level;
-};
-
-}}} // namespace detail::rtree::visitors
-
-template <typename Value, typename Options, typename IndexableGetter, typename EqualTo, typename Allocator>
-void gl_draw(rtree<Value, Options, IndexableGetter, EqualTo, Allocator> const& tree,
- size_t level_first = 0,
- size_t level_last = (std::numeric_limits<size_t>::max)(),
- typename index::detail::traits::coordinate_type<
- typename rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::box_type
- >::type z_coord_level_multiplier = 1
- )
-{
- typedef rtree<Value, Options, IndexableGetter, EqualTo, Allocator> rtree_type;
-
- typedef typename rtree_type::value_type value_type;
- typedef typename rtree_type::options_type options_type;
- typedef typename rtree_type::translator_type translator_type;
- typedef typename rtree_type::box_type box_type;
- typedef typename rtree_type::allocators_type allocators_type;
-
- if ( !tree.empty() )
- {
- glColor3f(0.75f, 0.75f, 0.75f);
- detail::rtree::visitors::detail::gl_draw_indexable(tree.bounds(), 0);
- }
-
- detail::rtree::visitors::gl_draw<value_type, options_type, translator_type, box_type, allocators_type>
- gl_draw_v(tree.translator(), level_first, level_last, z_coord_level_multiplier);
-
- tree.apply_visitor(gl_draw_v);
-}
-
-}}} // namespace boost::geometry::index
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_GL_DRAW_HPP
Deleted: branches/release/boost/geometry/index/detail/rtree/visitors/print.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/visitors/print.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84888)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,197 +0,0 @@
-// Boost.Geometry Index
-//
-// R-tree ostreaming visitor implementation
-//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
-//
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_PRINT_HPP
-#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_PRINT_HPP
-
-#include <iostream>
-
-namespace boost { namespace geometry { namespace index {
-
-namespace detail { namespace rtree { namespace visitors {
-
-namespace dispatch {
-
-template <typename Point, size_t Dimension>
-struct print_point
-{
- BOOST_STATIC_ASSERT(0 < Dimension);
-
- static inline void apply(std::ostream & os, Point const& p)
- {
- print_point<Point, Dimension - 1>::apply(os, p);
-
- os << ", " << geometry::get<Dimension - 1>(p);
- }
-};
-
-template <typename Point>
-struct print_point<Point, 1>
-{
- static inline void apply(std::ostream & os, Point const& p)
- {
- os << geometry::get<0>(p);
- }
-};
-
-template <typename Box, size_t Corner, size_t Dimension>
-struct print_corner
-{
- BOOST_STATIC_ASSERT(0 < Dimension);
-
- static inline void apply(std::ostream & os, Box const& b)
- {
- print_corner<Box, Corner, Dimension - 1>::apply(os, b);
-
- os << ", " << geometry::get<Corner, Dimension - 1>(b);
- }
-};
-
-template <typename Box, size_t Corner>
-struct print_corner<Box, Corner, 1>
-{
- static inline void apply(std::ostream & os, Box const& b)
- {
- os << geometry::get<Corner, 0>(b);
- }
-};
-
-template <typename Indexable, typename Tag>
-struct print_indexable
-{
-};
-
-template <typename Indexable>
-struct print_indexable<Indexable, box_tag>
-{
- static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
-
- static inline void apply(std::ostream &os, Indexable const& i)
- {
- os << '(';
- print_corner<Indexable, min_corner, dimension>::apply(os, i);
- os << ")x(";
- print_corner<Indexable, max_corner, dimension>::apply(os, i);
- os << ')';
- }
-};
-
-template <typename Indexable>
-struct print_indexable<Indexable, point_tag>
-{
- static const size_t dimension = index::detail::traits::dimension<Indexable>::value;
-
- static inline void apply(std::ostream &os, Indexable const& i)
- {
- os << '(';
- print_point<Indexable, dimension>::apply(os, i);
- os << ')';
- }
-};
-
-} // namespace dispatch
-
-namespace detail {
-
-template <typename Indexable>
-inline void print_indexable(std::ostream & os, Indexable const& i)
-{
- dispatch::print_indexable<
- Indexable,
- typename geometry::traits::tag<Indexable>::type
- >::apply(os, i);
-}
-
-} // namespace detail
-
-template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
-struct print : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
-{
- typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
- typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
-
- inline print(std::ostream & o, Translator const& t)
- : os(o), tr(t), level(0)
- {}
-
- inline void operator()(internal_node const& n)
- {
- typedef typename rtree::elements_type<internal_node>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- spaces(level) << "INTERNAL NODE - L:" << level << " Ch:" << elements.size() << " @:" << &n << '\n';
-
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- spaces(level);
- detail::print_indexable(os, it->first);
- os << " ->" << it->second << '\n';
- }
-
- size_t level_backup = level;
- ++level;
-
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- rtree::apply_visitor(*this, *it->second);
- }
-
- level = level_backup;
- }
-
- inline void operator()(leaf const& n)
- {
- typedef typename rtree::elements_type<leaf>::type elements_type;
- elements_type const& elements = rtree::elements(n);
-
- spaces(level) << "LEAF - L:" << level << " V:" << elements.size() << " @:" << &n << '\n';
- for (typename elements_type::const_iterator it = elements.begin();
- it != elements.end(); ++it)
- {
- spaces(level);
- detail::print_indexable(os, tr(*it));
- os << '\n';
- }
- }
-
- inline std::ostream & spaces(size_t level)
- {
- for ( size_t i = 0 ; i < 2 * level ; ++i )
- os << ' ';
- return os;
- }
-
- std::ostream & os;
- Translator const& tr;
-
- size_t level;
-};
-
-}}} // namespace detail::rtree::visitors
-
-template <typename Value, typename Options, typename IndexableGetter, typename EqualTo, typename Allocator>
-std::ostream & operator<<(std::ostream & os, rtree<Value, Options, IndexableGetter, EqualTo, Allocator> const& tree)
-{
- typedef rtree<Value, Options, IndexableGetter, EqualTo, Allocator> rtree_type;
- typedef typename rtree_type::value_type value_type;
- typedef typename rtree_type::options_type options_type;
- typedef typename rtree_type::translator_type translator_type;
- typedef typename rtree_type::box_type box_type;
- typedef typename rtree_type::allocators_type allocators_type;
- detail::rtree::visitors::print<value_type, options_type, translator_type, box_type, allocators_type> print_v(os, tree.translator());
- tree.apply_visitor(print_v);
- return os;
-}
-
-}}} // namespace boost::geometry::index
-
-#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_PRINT_HPP
Modified: branches/release/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -59,7 +59,7 @@
// if value meets predicates
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(pred, *it, tr(*it)) )
{
- out_iter = *it;
+ *out_iter = *it;
++out_iter;
++found_count;
Modified: branches/release/boost/geometry/index/detail/varray.hpp
==============================================================================
--- branches/release/boost/geometry/index/detail/varray.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/detail/varray.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -1,6 +1,7 @@
-// Boost.Geometry Index
+// Boost.Container varray
//
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2013 Andrew Hundt.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,224 +10,804 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
-#include <cstddef>
-
-#include <boost/move/move.hpp>
-#include <boost/aligned_storage.hpp>
-#include <boost/iterator/reverse_iterator.hpp>
+// TODO - REMOVE/CHANGE
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/preprocessor.hpp>
+
+#include <boost/config.hpp>
+#include <boost/swap.hpp>
+#include <boost/integer.hpp>
#include <boost/mpl/assert.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/and.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_constructor.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
+
+// TODO - use std::reverse_iterator and std::iterator_traits
+// instead Boost.Iterator to remove dependency?
+// or boost/detail/iterator.hpp ?
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
#include <boost/geometry/index/detail/assert.hpp>
-#ifdef BOOST_MSVC
-#pragma warning (push)
-#pragma warning (disable : 4996) // deprecated functions
-#endif
+#include <boost/geometry/index/detail/assert.hpp>
+#include <boost/geometry/index/detail/varray_detail.hpp>
+
+#include <boost/concept_check.hpp>
+
+/*!
+\defgroup varray_non_member varray non-member functions
+*/
namespace boost { namespace geometry { namespace index { namespace detail {
+
+namespace varray_detail {
-template <typename V>
-struct varray_default_alloc
+template <typename Value, std::size_t Capacity>
+struct varray_traits
{
+ typedef Value value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef V * pointer;
- typedef const V * const_pointer;
+ typedef Value * pointer;
+ typedef const Value * const_pointer;
+ typedef Value & reference;
+ typedef const Value & const_reference;
+
+ typedef boost::false_type use_memop_in_swap_and_move;
+ typedef boost::false_type use_optimized_swap;
+ typedef boost::false_type disable_trivial_init;
};
-template <typename Value, size_t Capacity, typename Al = varray_default_alloc<Value> >
+template <typename Varray>
+struct checker
+{
+ typedef typename Varray::size_type size_type;
+ typedef typename Varray::const_iterator const_iterator;
+
+ static inline void check_capacity(Varray const& v, size_type s)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(s <= v.capacity(), "size too big");
+
+ ::boost::ignore_unused_variable_warning(v);
+ ::boost::ignore_unused_variable_warning(s);
+ }
+
+ static inline void throw_out_of_bounds(Varray const& v, size_type i)
+ {
+//#ifndef BOOST_NO_EXCEPTIONS
+ if ( v.size() <= i )
+ BOOST_THROW_EXCEPTION(std::out_of_range("index out of bounds"));
+//#else // BOOST_NO_EXCEPTIONS
+// BOOST_GEOMETRY_INDEX_ASSERT(i < v.size(), "index out of bounds");
+//#endif // BOOST_NO_EXCEPTIONS
+
+ ::boost::ignore_unused_variable_warning(v);
+ ::boost::ignore_unused_variable_warning(i);
+ }
+
+ static inline void check_index(Varray const& v, size_type i)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(i < v.size(), "index out of bounds");
+
+ ::boost::ignore_unused_variable_warning(v);
+ ::boost::ignore_unused_variable_warning(i);
+ }
+
+ static inline void check_not_empty(Varray const& v)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(!v.empty(), "the container is empty");
+
+ ::boost::ignore_unused_variable_warning(v);
+ }
+
+ static inline void check_iterator_end_neq(Varray const& v, const_iterator position)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(v.begin() <= position && position < v.end(), "iterator out of bounds");
+
+ ::boost::ignore_unused_variable_warning(v);
+ ::boost::ignore_unused_variable_warning(position);
+ }
+
+ static inline void check_iterator_end_eq(Varray const& v, const_iterator position)
+ {
+ BOOST_GEOMETRY_INDEX_ASSERT(v.begin() <= position && position <= v.end(), "iterator out of bounds");
+
+ ::boost::ignore_unused_variable_warning(v);
+ ::boost::ignore_unused_variable_warning(position);
+ }
+};
+
+} // namespace varray_detail
+
+/*!
+\brief A variable-size array container with fixed capacity.
+
+varray is a sequence container like boost::container::vector with contiguous storage that can
+change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
+
+A varray is a sequence that supports random access to elements, constant time insertion and
+removal of elements at the end, and linear time insertion and removal of elements at the beginning or
+in the middle. The number of elements in a varray may vary dynamically up to a fixed capacity
+because elements are stored within the object itself similarly to an array. However, objects are
+initialized as they are inserted into varray unlike C arrays or std::array which must construct
+all elements on instantiation. The behavior of varray enables the use of statically allocated
+elements in cases with complex object lifetime requirements that would otherwise not be trivially
+possible.
+
+\par Error Handling
+ Insertion beyond the capacity and out of bounds errors result in undefined behavior unless
+ otherwise specified. In this respect if size() == capacity(), then varray::push_back()
+ behaves like std::vector pop_front() if size() == empty(). The reason for this difference
+ is because unlike vectors, varray does not perform allocation.
+
+\par Advanced Usage
+ Error handling behavior can be modified to more closely match std::vector exception behavior
+ when exceeding bounds by providing an alternate Strategy and varray_traits instantiation.
+
+\tparam Value The type of element that will be stored.
+\tparam Capacity The maximum number of elements varray can store, fixed at compile time.
+\tparam Strategy Defines the public typedefs and error handlers,
+ implements StaticVectorStrategy and has some similarities
+ to an Allocator.
+*/
+template <typename Value, std::size_t Capacity>
class varray
{
+ typedef varray_detail::varray_traits<Value, Capacity> vt;
+ typedef varray_detail::checker<varray> errh;
+
BOOST_MPL_ASSERT_MSG(
- (0 < Capacity),
- INVALID_CAPACITY,
- (varray));
+ ( boost::is_unsigned<typename vt::size_type>::value &&
+ sizeof(typename boost::uint_value_t<Capacity>::least) <= sizeof(typename vt::size_type) ),
+ SIZE_TYPE_IS_TOO_SMALL_FOR_SPECIFIED_CAPACITY,
+ (varray)
+ );
+
+ typedef boost::aligned_storage<
+ sizeof(Value[Capacity]),
+ boost::alignment_of<Value[Capacity]>::value
+ > aligned_storage_type;
+
+ template <typename V, std::size_t C>
+ friend class varray;
BOOST_COPYABLE_AND_MOVABLE(varray)
+#ifdef BOOST_NO_RVALUE_REFERENCES
public:
- typedef Value value_type;
- typedef Value& reference;
- typedef Value const& const_reference;
- typedef typename Al::size_type size_type;
- typedef typename Al::difference_type difference_type;
- typedef typename Al::pointer pointer;
- typedef typename Al::const_pointer const_pointer;
+ template <std::size_t C>
+ varray & operator=(varray<Value, C> & sv)
+ {
+ typedef varray<Value, C> other;
+ this->operator=(static_cast<const ::boost::rv<other> &>(const_cast<const other &>(sv)));
+ return *this;
+ }
+#endif
+
+public:
+ //! @brief The type of elements stored in the container.
+ typedef typename vt::value_type value_type;
+ //! @brief The unsigned integral type used by the container.
+ typedef typename vt::size_type size_type;
+ //! @brief The pointers difference type.
+ typedef typename vt::difference_type difference_type;
+ //! @brief The pointer type.
+ typedef typename vt::pointer pointer;
+ //! @brief The const pointer type.
+ typedef typename vt::const_pointer const_pointer;
+ //! @brief The value reference type.
+ typedef typename vt::reference reference;
+ //! @brief The value const reference type.
+ typedef typename vt::const_reference const_reference;
+
+ //! @brief The iterator type.
typedef pointer iterator;
+ //! @brief The const iterator type.
typedef const_pointer const_iterator;
+ //! @brief The reverse iterator type.
typedef boost::reverse_iterator<iterator> reverse_iterator;
+ //! @brief The const reverse iterator.
typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
- // nothrow
+ //! @brief Constructs an empty varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
varray()
: m_size(0)
{}
- // strong
+ //! @pre <tt>count <= capacity()</tt>
+ //!
+ //! @brief Constructs a varray containing count default constructed Values.
+ //!
+ //! @param count The number of values which will be contained in the container.
+ //!
+ //! @par Throws
+ //! If Value's default constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
explicit varray(size_type count)
: m_size(0)
{
- resize(count); // may throw
+ this->resize(count); // may throw
}
- // strong
+ //! @pre <tt>count <= capacity()</tt>
+ //!
+ //! @brief Constructs a varray containing count copies of value.
+ //!
+ //! @param count The number of copies of a values that will be contained in the container.
+ //! @param value The value which will be used to copy construct values.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
varray(size_type count, value_type const& value)
: m_size(0)
{
- resize(count, value); // may throw
+ this->resize(count, value); // may throw
}
- // strong
- varray(varray const& other)
- : m_size(other.m_size)
+ //! @pre
+ //! @li <tt>distance(first, last) <= capacity()</tt>
+ //! @li Iterator must meet the \c ForwardTraversalIterator concept.
+ //!
+ //! @brief Constructs a varray containing copy of a range <tt>[first, last)</tt>.
+ //!
+ //! @param first The iterator to the first element in range.
+ //! @param last The iterator to the one after the last element in range.
+ //!
+ //! @par Throws
+ //! If Value's constructor taking a dereferenced Iterator throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ template <typename Iterator>
+ varray(Iterator first, Iterator last)
+ : m_size(0)
{
- this->uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
+ BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
+
+ this->assign(first, last); // may throw
}
- // strong
- varray(BOOST_RV_REF(varray) other)
- : m_size(other.m_size)
+ //! @brief Constructs a copy of other varray.
+ //!
+ //! @param other The varray which content will be copied to this one.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor throws.
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ varray(varray const& other)
+ : m_size(other.size())
{
- this->uninitialized_move(other.begin(), other.end(), this->begin()); // may throw
+ namespace sv = varray_detail;
+ sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
}
- // strong
- template <typename Iterator>
- varray(Iterator first, Iterator last)
- : m_size(0)
+ //! @pre <tt>other.size() <= capacity()</tt>.
+ //!
+ //! @brief Constructs a copy of other varray.
+ //!
+ //! @param other The varray which content will be copied to this one.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ template <std::size_t C>
+ varray(varray<value_type, C> const& other)
+ : m_size(other.size())
{
- assign(first, last); // may throw
+ errh::check_capacity(*this, other.size()); // may throw
+
+ namespace sv = varray_detail;
+ sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
}
- // basic
+ //! @brief Copy assigns Values stored in the other varray to this one.
+ //!
+ //! @param other The varray which content will be copied to this one.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor or copy assignment throws.
+ //!
+ //! @par Complexity
+ //! Linear O(N).
varray & operator=(BOOST_COPY_ASSIGN_REF(varray) other)
{
- assign(other.begin(), other.end()); // may throw
+ this->assign(other.begin(), other.end()); // may throw
return *this;
}
- // basic
+ //! @pre <tt>other.size() <= capacity()</tt>
+ //!
+ //! @brief Copy assigns Values stored in the other varray to this one.
+ //!
+ //! @param other The varray which content will be copied to this one.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor or copy assignment throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ template <std::size_t C>
+// TEMPORARY WORKAROUND
+#if defined(BOOST_NO_RVALUE_REFERENCES)
+ varray & operator=(::boost::rv< varray<value_type, C> > const& other)
+#else
+ varray & operator=(varray<value_type, C> const& other)
+#endif
+ {
+ this->assign(other.begin(), other.end()); // may throw
+
+ return *this;
+ }
+
+ //! @brief Move constructor. Moves Values stored in the other varray to this one.
+ //!
+ //! @param other The varray which content will be moved to this one.
+ //!
+ //! @par Throws
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+ //! @internal
+ //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ varray(BOOST_RV_REF(varray) other)
+ {
+ typedef typename
+ vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+ this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
+ }
+
+ //! @pre <tt>other.size() <= capacity()</tt>
+ //!
+ //! @brief Move constructor. Moves Values stored in the other varray to this one.
+ //!
+ //! @param other The varray which content will be moved to this one.
+ //!
+ //! @par Throws
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+ //! @internal
+ //! @li It throws only if \c use_memop_in_swap_and_move is false_type - default.
+ //! @endinternal
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ template <std::size_t C>
+ varray(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
+ : m_size(other.m_size)
+ {
+ errh::check_capacity(*this, other.size()); // may throw
+
+ typedef typename
+ vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+ this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
+ }
+
+ //! @brief Move assignment. Moves Values stored in the other varray to this one.
+ //!
+ //! @param other The varray which content will be moved to this one.
+ //!
+ //! @par Throws
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+ //! @internal
+ //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
varray & operator=(BOOST_RV_REF(varray) other)
{
- assign(other.begin(), other.end()); // may throw
+ if ( &other == this )
+ return *this;
+
+ typedef typename
+ vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+ this->move_assign_dispatch(other, use_memop_in_swap_and_move());
return *this;
}
- // nothrow
+ //! @pre <tt>other.size() <= capacity()</tt>
+ //!
+ //! @brief Move assignment. Moves Values stored in the other varray to this one.
+ //!
+ //! @param other The varray which content will be moved to this one.
+ //!
+ //! @par Throws
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+ //! @internal
+ //! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
+ //! @endinternal
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ template <std::size_t C>
+ varray & operator=(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
+ {
+ errh::check_capacity(*this, other.size()); // may throw
+
+ typedef typename
+ vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+ this->move_assign_dispatch(other, use_memop_in_swap_and_move());
+
+ return *this;
+ }
+
+ //! @brief Destructor. Destroys Values stored in this container.
+ //!
+ //! @par Throws
+ //! Nothing
+ //!
+ //! @par Complexity
+ //! Linear O(N).
~varray()
{
- this->destroy(this->begin(), this->end());
+ namespace sv = varray_detail;
+ sv::destroy(this->begin(), this->end());
}
- // strong
+ //! @brief Swaps contents of the other varray and this one.
+ //!
+ //! @param other The varray which content will be swapped with this one's content.
+ //!
+ //! @par Throws
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+ //! @internal
+ //! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ void swap(varray & other)
+ {
+ typedef typename
+ vt::use_optimized_swap use_optimized_swap;
+
+ this->swap_dispatch(other, use_optimized_swap());
+ }
+
+ //! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
+ //!
+ //! @brief Swaps contents of the other varray and this one.
+ //!
+ //! @param other The varray which content will be swapped with this one's content.
+ //!
+ //! @par Throws
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+ //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+ //! @internal
+ //! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
+ //! @endinternal
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ template <std::size_t C>
+ void swap(varray<value_type, C> & other)
+ {
+ errh::check_capacity(*this, other.size());
+ errh::check_capacity(other, this->size());
+
+ typedef typename
+ vt::use_optimized_swap use_optimized_swap;
+
+ this->swap_dispatch(other, use_optimized_swap());
+ }
+
+ //! @pre <tt>count <= capacity()</tt>
+ //!
+ //! @brief Inserts or erases elements at the end such that
+ //! the size becomes count. New elements are default constructed.
+ //!
+ //! @param count The number of elements which will be stored in the container.
+ //!
+ //! @par Throws
+ //! If Value's default constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
void resize(size_type count)
{
+ namespace sv = varray_detail;
+ typedef typename vt::disable_trivial_init dti;
+
if ( count < m_size )
{
- this->destroy(this->begin() + count, this->end());
+ sv::destroy(this->begin() + count, this->end());
}
else
{
- check_capacity(count);
+ errh::check_capacity(*this, count); // may throw
- this->construct(this->end(), this->begin() + count); // may throw
+ sv::uninitialized_fill(this->end(), this->begin() + count, dti()); // may throw
}
m_size = count; // update end
}
- // strong
+ //! @pre <tt>count <= capacity()</tt>
+ //!
+ //! @brief Inserts or erases elements at the end such that
+ //! the size becomes count. New elements are copy constructed from value.
+ //!
+ //! @param count The number of elements which will be stored in the container.
+ //! @param value The value used to copy construct the new element.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
void resize(size_type count, value_type const& value)
{
if ( count < m_size )
{
- this->destroy(this->begin() + count, this->end());
+ namespace sv = varray_detail;
+ sv::destroy(this->begin() + count, this->end());
}
else
{
- check_capacity(count);
+ errh::check_capacity(*this, count); // may throw
std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
}
m_size = count; // update end
}
- // nothrow
+ //! @pre <tt>count <= capacity()</tt>
+ //!
+ //! @brief This call has no effect because the Capacity of this container is constant.
+ //!
+ //! @param count The number of elements which the container should be able to contain.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
void reserve(size_type count)
{
- check_capacity(count);
+ errh::check_capacity(*this, count); // may throw
}
- // strong
+ //! @pre <tt>size() < capacity()</tt>
+ //!
+ //! @brief Adds a copy of value at the end.
+ //!
+ //! @param value The value used to copy construct the new element.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Constant O(1).
void push_back(value_type const& value)
{
- check_capacity(m_size + 1);
+ typedef typename vt::disable_trivial_init dti;
+
+ errh::check_capacity(*this, m_size + 1); // may throw
- this->uninitialized_fill(this->end(), value); // may throw
+ namespace sv = varray_detail;
+ sv::construct(dti(), this->end(), value); // may throw
++m_size; // update end
}
+ //! @pre <tt>size() < capacity()</tt>
+ //!
+ //! @brief Moves value to the end.
+ //!
+ //! @param value The value to move construct the new element.
+ //!
+ //! @par Throws
+ //! If Value's move constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Constant O(1).
void push_back(BOOST_RV_REF(value_type) value)
{
- check_capacity(m_size + 1);
+ typedef typename vt::disable_trivial_init dti;
- this->uninitialized_fill(this->end(), value); // may throw
+ errh::check_capacity(*this, m_size + 1); // may throw
+
+ namespace sv = varray_detail;
+ sv::construct(dti(), this->end(), ::boost::move(value)); // may throw
++m_size; // update end
}
- // nothrow
+ //! @pre <tt>!empty()</tt>
+ //!
+ //! @brief Destroys last value and decreases the size.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
void pop_back()
{
- check_empty();
-
- //--m_size; // update end
- //this->destroy(this->end());
+ errh::check_not_empty(*this);
- // safer and more intuitive version
- this->destroy(this->end() - 1);
+ namespace sv = varray_detail;
+ sv::destroy(this->end() - 1);
--m_size; // update end
}
- // basic
- void insert(iterator position, value_type const& value)
+ //! @pre
+ //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+ //! @li <tt>size() < capacity()</tt>
+ //!
+ //! @brief Inserts a copy of element at position.
+ //!
+ //! @param position The position at which the new value will be inserted.
+ //! @param value The value used to copy construct the new element.
+ //!
+ //! @par Throws
+ //! @li If Value's copy constructor or copy assignment throws
+ //! @li If Value's move constructor or move assignment throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Constant or linear.
+ iterator insert(iterator position, value_type const& value)
{
- check_iterator_end_eq(position);
- check_capacity(m_size + 1);
+ typedef typename vt::disable_trivial_init dti;
+ namespace sv = varray_detail;
+
+ errh::check_iterator_end_eq(*this, position);
+ errh::check_capacity(*this, m_size + 1); // may throw
if ( position == this->end() )
{
- this->uninitialized_fill(position, value); // may throw
+ sv::construct(dti(), position, value); // may throw
++m_size; // update end
}
else
{
- // TODO - should following lines check for exception and revert to the old size?
+ // TODO - should move be used only if it's nonthrowing?
+ value_type & r = *(this->end() - 1);
+ sv::construct(dti(), this->end(), boost::move(r)); // may throw
+ ++m_size; // update end
+ sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
+ sv::assign(position, value); // may throw
+ }
- this->uninitialized_fill(this->end(), *(this->end() - 1)); // may throw
+ return position;
+ }
+
+ //! @pre
+ //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+ //! @li <tt>size() < capacity()</tt>
+ //!
+ //! @brief Inserts a move-constructed element at position.
+ //!
+ //! @param position The position at which the new value will be inserted.
+ //! @param value The value used to move construct the new element.
+ //!
+ //! @par Throws
+ //! If Value's move constructor or move assignment throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Constant or linear.
+ iterator insert(iterator position, BOOST_RV_REF(value_type) value)
+ {
+ typedef typename vt::disable_trivial_init dti;
+ namespace sv = varray_detail;
+
+ errh::check_iterator_end_eq(*this, position);
+ errh::check_capacity(*this, m_size + 1); // may throw
+
+ if ( position == this->end() )
+ {
+ sv::construct(dti(), position, boost::move(value)); // may throw
++m_size; // update end
- this->move_backward(position, this->end() - 2, this->end() - 1); // may throw
- this->fill(position, value); // may throw
}
+ else
+ {
+ // TODO - should move be used only if it's nonthrowing?
+ value_type & r = *(this->end() - 1);
+ sv::construct(dti(), this->end(), boost::move(r)); // may throw
+ ++m_size; // update end
+ sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
+ sv::assign(position, boost::move(value)); // may throw
+ }
+
+ return position;
}
- // basic
- void insert(iterator position, size_type count, value_type const& value)
+ //! @pre
+ //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+ //! @li <tt>size() + count <= capacity()</tt>
+ //!
+ //! @brief Inserts a count copies of value at position.
+ //!
+ //! @param position The position at which new elements will be inserted.
+ //! @param count The number of new elements which will be inserted.
+ //! @param value The value used to copy construct new elements.
+ //!
+ //! @par Throws
+ //! @li If Value's copy constructor or copy assignment throws.
+ //! @li If Value's move constructor or move assignment throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ iterator insert(iterator position, size_type count, value_type const& value)
{
- check_iterator_end_eq(position);
- check_capacity(m_size + count);
+ errh::check_iterator_end_eq(*this, position);
+ errh::check_capacity(*this, m_size + count); // may throw
if ( position == this->end() )
{
@@ -235,658 +816,1394 @@
}
else
{
+ namespace sv = varray_detail;
+
difference_type to_move = std::distance(position, this->end());
// TODO - should following lines check for exception and revert to the old size?
if ( count < static_cast<size_type>(to_move) )
{
- this->uninitialized_copy(this->end() - count, this->end(), this->end()); // may throw
+ sv::uninitialized_move(this->end() - count, this->end(), this->end()); // may throw
m_size += count; // update end
- this->move_backward(position, position + to_move - count, this->end() - count); // may throw
- std::fill_n(position, count, value); // may throw
+ sv::move_backward(position, position + to_move - count, this->end() - count); // may throw
+ std::fill_n(position, count, value); // may throw
}
else
{
- std::uninitialized_fill(this->end(), position + count, value); // may throw
+ std::uninitialized_fill(this->end(), position + count, value); // may throw
m_size += count - to_move; // update end
- this->uninitialized_copy(position, position + to_move, position + count); // may throw
+ sv::uninitialized_move(position, position + to_move, position + count); // may throw
m_size += to_move; // update end
- std::fill_n(position, to_move, value); // may throw
+ std::fill_n(position, to_move, value); // may throw
}
}
+
+ return position;
}
- // basic
+ //! @pre
+ //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+ //! @li <tt>distance(first, last) <= capacity()</tt>
+ //! @li \c Iterator must meet the \c ForwardTraversalIterator concept.
+ //!
+ //! @brief Inserts a copy of a range <tt>[first, last)</tt> at position.
+ //!
+ //! @param position The position at which new elements will be inserted.
+ //! @param first The iterator to the first element of a range used to construct new elements.
+ //! @param last The iterator to the one after the last element of a range used to construct new elements.
+ //!
+ //! @par Throws
+ //! @li If Value's constructor and assignment taking a dereferenced \c Iterator.
+ //! @li If Value's move constructor or move assignment throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Linear O(N).
template <typename Iterator>
- void insert(iterator position, Iterator first, Iterator last)
+ iterator insert(iterator position, Iterator first, Iterator last)
{
+ BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
+
typedef typename boost::iterator_traversal<Iterator>::type traversal;
this->insert_dispatch(position, first, last, traversal());
+
+ return position;
}
- // basic
- void erase(iterator position)
- {
- check_iterator_end_neq(position);
+ //! @pre \c position must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
+ //!
+ //! @brief Erases Value from position.
+ //!
+ //! @param position The position of the element which will be erased from the container.
+ //!
+ //! @par Throws
+ //! If Value's move assignment throws.
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ iterator erase(iterator position)
+ {
+ namespace sv = varray_detail;
+
+ errh::check_iterator_end_neq(*this, position);
+
+ //TODO - add empty check?
+ //errh::check_empty(*this);
- this->move(position + 1, this->end(), position); // may throw
- this->destroy(this->end() - 1);
+ sv::move(position + 1, this->end(), position); // may throw
+ sv::destroy(this->end() - 1);
--m_size;
+
+ return position;
}
- // basic
- void erase(iterator first, iterator last)
+ //! @pre
+ //! @li \c first and \c last must define a valid range
+ //! @li iterators must be in range <tt>[begin(), end()]</tt>
+ //!
+ //! @brief Erases Values from a range <tt>[first, last)</tt>.
+ //!
+ //! @param first The position of the first element of a range which will be erased from the container.
+ //! @param last The position of the one after the last element of a range which will be erased from the container.
+ //!
+ //! @par Throws
+ //! If Value's move assignment throws.
+ //!
+ //! @par Complexity
+ //! Linear O(N).
+ iterator erase(iterator first, iterator last)
{
- check_iterator_end_eq(first);
- check_iterator_end_eq(last);
+ namespace sv = varray_detail;
+
+ errh::check_iterator_end_eq(*this, first);
+ errh::check_iterator_end_eq(*this, last);
difference_type n = std::distance(first, last);
- BOOST_ASSERT_MSG(0 <= n, "invalid range");
+
+ //TODO - add invalid range check?
+ //BOOST_ASSERT_MSG(0 <= n, "invalid range");
+ //TODO - add this->size() check?
+ //BOOST_ASSERT_MSG(n <= this->size(), "invalid range");
- this->move(last, this->end(), first); // may throw
- this->destroy(this->end() - n, this->end());
+ sv::move(last, this->end(), first); // may throw
+ sv::destroy(this->end() - n, this->end());
m_size -= n;
+
+ return first;
}
- // basic
+ //! @pre <tt>distance(first, last) <= capacity()</tt>
+ //!
+ //! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
+ //!
+ //! @param first The iterator to the first element of a range used to construct new content of this container.
+ //! @param last The iterator to the one after the last element of a range used to construct new content of this container.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor or copy assignment throws,
+ //!
+ //! @par Complexity
+ //! Linear O(N).
template <typename Iterator>
void assign(Iterator first, Iterator last)
{
+ BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
+
typedef typename boost::iterator_traversal<Iterator>::type traversal;
this->assign_dispatch(first, last, traversal()); // may throw
}
- // basic
+ //! @pre <tt>count <= capacity()</tt>
+ //!
+ //! @brief Assigns a count copies of value to this container.
+ //!
+ //! @param count The new number of elements which will be container in the container.
+ //! @param value The value which will be used to copy construct the new content.
+ //!
+ //! @par Throws
+ //! If Value's copy constructor or copy assignment throws.
+ //!
+ //! @par Complexity
+ //! Linear O(N).
void assign(size_type count, value_type const& value)
{
if ( count < m_size )
{
- std::fill_n(this->begin(), count, value);
- this->destroy(this->begin() + count, this->end());
+ namespace sv = varray_detail;
+
+ std::fill_n(this->begin(), count, value); // may throw
+ sv::destroy(this->begin() + count, this->end());
}
else
{
- check_capacity(count);
+ errh::check_capacity(*this, count); // may throw
- std::fill_n(this->begin(), m_size, value);
+ std::fill_n(this->begin(), m_size, value); // may throw
std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
}
m_size = count; // update end
}
- // nothrow
+#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
+#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! @pre <tt>size() < capacity()</tt>
+ //!
+ //! @brief Inserts a Value constructed with
+ //! \c std::forward<Args>(args)... in the end of the container.
+ //!
+ //! @param args The arguments of the constructor of the new element which will be created at the end of the container.
+ //!
+ //! @par Throws
+ //! If in-place constructor throws or Value's move constructor throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ template<class ...Args>
+ void emplace_back(BOOST_FWD_REF(Args) ...args)
+ {
+ typedef typename vt::disable_trivial_init dti;
+
+ errh::check_capacity(*this, m_size + 1); // may throw
+
+ namespace sv = varray_detail;
+ sv::construct(dti(), this->end(), ::boost::forward<Args>(args)...); // may throw
+ ++m_size; // update end
+ }
+
+ //! @pre
+ //! @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
+ //! @li <tt>size() < capacity()</tt>
+ //!
+ //! @brief Inserts a Value constructed with
+ //! \c std::forward<Args>(args)... before position
+ //!
+ //! @param position The position at which new elements will be inserted.
+ //! @param args The arguments of the constructor of the new element.
+ //!
+ //! @par Throws
+ //! If in-place constructor throws or if Value's move constructor or move assignment throws.
+ //! @internal
+ //! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+ //! @endinternal
+ //!
+ //! @par Complexity
+ //! Constant or linear.
+ template<class ...Args>
+ iterator emplace(iterator position, BOOST_FWD_REF(Args) ...args)
+ {
+ typedef typename vt::disable_trivial_init dti;
+
+ namespace sv = varray_detail;
+
+ errh::check_iterator_end_eq(*this, position);
+ errh::check_capacity(*this, m_size + 1); // may throw
+
+ if ( position == this->end() )
+ {
+ sv::construct(dti(), position, ::boost::forward<Args>(args)...); // may throw
+ ++m_size; // update end
+ }
+ else
+ {
+ // TODO - should following lines check for exception and revert to the old size?
+
+ // TODO - should move be used only if it's nonthrowing?
+ value_type & r = *(this->end() - 1);
+ sv::construct(dti(), this->end(), boost::move(r)); // may throw
+ ++m_size; // update end
+ sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
+
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage;
+ value_type * val_p = static_cast<value_type *>(temp_storage.address());
+ sv::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
+ sv::scoped_destructor<value_type> d(val_p);
+ sv::assign(position, ::boost::move(*val_p)); // may throw
+ }
+
+ return position;
+ }
+
+#else // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ typedef typename vt::disable_trivial_init dti; \
+ \
+ errh::check_capacity(*this, m_size + 1); /*may throw*/\
+ \
+ namespace sv = varray_detail; \
+ sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ ++m_size; /*update end*/ \
+ } \
+ //
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ iterator emplace(iterator position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ typedef typename vt::disable_trivial_init dti; \
+ namespace sv = varray_detail; \
+ \
+ errh::check_iterator_end_eq(*this, position); \
+ errh::check_capacity(*this, m_size + 1); /*may throw*/\
+ \
+ if ( position == this->end() ) \
+ { \
+ sv::construct(dti(), position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ ++m_size; /*update end*/ \
+ } \
+ else \
+ { \
+ /* TODO - should following lines check for exception and revert to the old size? */ \
+ /* TODO - should move be used only if it's nonthrowing? */ \
+ \
+ value_type & r = *(this->end() - 1); \
+ sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
+ ++m_size; /*update end*/ \
+ sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
+ \
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
+ value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
+ sv::construct(dti(), val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ sv::scoped_destructor<value_type> d(val_p); \
+ sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
+ } \
+ \
+ return position; \
+ } \
+ //
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+#endif // BOOST_CONTAINER_PERFECT_FORWARDING || BOOST_CONTAINER_DOXYGEN_INVOKED
+#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
+
+ //! @brief Removes all elements from the container.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
void clear()
{
- this->destroy(this->begin(), this->end());
+ namespace sv = varray_detail;
+ sv::destroy(this->begin(), this->end());
m_size = 0; // update end
}
- // strong
- Value & at(size_type i)
+ //! @pre <tt>i < size()</tt>
+ //!
+ //! @brief Returns reference to the i-th element.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return reference to the i-th element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! \c std::out_of_range exception by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ reference at(size_type i)
{
- if ( m_size <= i )
- throw std::out_of_range("index out of bounds");
+ errh::throw_out_of_bounds(*this, i); // may throw
return *(this->begin() + i);
}
- // strong
- Value const& at(size_type i) const
+ //! @pre <tt>i < size()</tt>
+ //!
+ //! @brief Returns const reference to the i-th element.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return const reference to the i-th element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! \c std::out_of_range exception by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ const_reference at(size_type i) const
{
- if ( m_size <= i )
- throw std::out_of_range("index out of bounds");
+ errh::throw_out_of_bounds(*this, i); // may throw
return *(this->begin() + i);
}
- // nothrow
- Value & operator[](size_type i)
+ //! @pre <tt>i < size()</tt>
+ //!
+ //! @brief Returns reference to the i-th element.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return reference to the i-th element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ reference operator[](size_type i)
{
- BOOST_ASSERT_MSG(i < m_size, "index out of bounds");
+ // TODO: Remove bounds check? std::vector and std::array operator[] don't check.
+ errh::check_index(*this, i);
return *(this->begin() + i);
}
- // nothrow
- Value const& operator[](size_type i) const
+ //! @pre <tt>i < size()</tt>
+ //!
+ //! @brief Returns const reference to the i-th element.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return const reference to the i-th element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ const_reference operator[](size_type i) const
{
- BOOST_ASSERT_MSG(i < m_size, "index out of bounds");
+ errh::check_index(*this, i);
return *(this->begin() + i);
}
- // nothrow
- Value & front()
+ //! @pre \c !empty()
+ //!
+ //! @brief Returns reference to the first element.
+ //!
+ //! @return reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ reference front()
{
- check_empty();
+ errh::check_not_empty(*this);
return *(this->begin());
}
- // nothrow
- Value const& front() const
+ //! @pre \c !empty()
+ //!
+ //! @brief Returns const reference to the first element.
+ //!
+ //! @return const reference to the first element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ const_reference front() const
{
- check_empty();
+ errh::check_not_empty(*this);
return *(this->begin());
}
- // nothrow
- Value & back()
+ //! @pre \c !empty()
+ //!
+ //! @brief Returns reference to the last element.
+ //!
+ //! @return reference to the last element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ reference back()
{
- check_empty();
+ errh::check_not_empty(*this);
return *(this->end() - 1);
}
- // nothrow
- Value const& back() const
+ //! @pre \c !empty()
+ //!
+ //! @brief Returns const reference to the first element.
+ //!
+ //! @return const reference to the last element
+ //! from the beginning of the container.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ const_reference back() const
{
- check_empty();
+ errh::check_not_empty(*this);
return *(this->end() - 1);
}
- // nothrow
- Value * data() { return this->ptr(); }
- const Value * data() const { return this->ptr(); }
-
- // nothrow
+ //! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
+ //! For a non-empty vector <tt>data() == &front()</tt>.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ Value * data()
+ {
+ return boost::addressof(*(this->ptr()));
+ }
+
+ //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
+ //! For a non-empty vector <tt>data() == &front()</tt>.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ const Value * data() const
+ {
+ return boost::addressof(*(this->ptr()));
+ }
+
+
+ //! @brief Returns iterator to the first element.
+ //!
+ //! @return iterator to the first element contained in the vector.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
iterator begin() { return this->ptr(); }
+
+ //! @brief Returns const iterator to the first element.
+ //!
+ //! @return const_iterator to the first element contained in the vector.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_iterator begin() const { return this->ptr(); }
+
+ //! @brief Returns const iterator to the first element.
+ //!
+ //! @return const_iterator to the first element contained in the vector.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_iterator cbegin() const { return this->ptr(); }
+
+ //! @brief Returns iterator to the one after the last element.
+ //!
+ //! @return iterator pointing to the one after the last element contained in the vector.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
iterator end() { return this->begin() + m_size; }
+
+ //! @brief Returns const iterator to the one after the last element.
+ //!
+ //! @return const_iterator pointing to the one after the last element contained in the vector.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_iterator end() const { return this->begin() + m_size; }
+
+ //! @brief Returns const iterator to the one after the last element.
+ //!
+ //! @return const_iterator pointing to the one after the last element contained in the vector.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_iterator cend() const { return this->cbegin() + m_size; }
- // nothrow
+
+ //! @brief Returns reverse iterator to the first element of the reversed container.
+ //!
+ //! @return reverse_iterator pointing to the beginning
+ //! of the reversed varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
reverse_iterator rbegin() { return reverse_iterator(this->end()); }
+
+ //! @brief Returns const reverse iterator to the first element of the reversed container.
+ //!
+ //! @return const_reverse_iterator pointing to the beginning
+ //! of the reversed varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
+
+ //! @brief Returns const reverse iterator to the first element of the reversed container.
+ //!
+ //! @return const_reverse_iterator pointing to the beginning
+ //! of the reversed varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
+
+ //! @brief Returns reverse iterator to the one after the last element of the reversed container.
+ //!
+ //! @return reverse_iterator pointing to the one after the last element
+ //! of the reversed varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
reverse_iterator rend() { return reverse_iterator(this->begin()); }
+
+ //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
+ //!
+ //! @return const_reverse_iterator pointing to the one after the last element
+ //! of the reversed varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
+
+ //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
+ //!
+ //! @return const_reverse_iterator pointing to the one after the last element
+ //! of the reversed varray.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
- // nothrow
+ //! @brief Returns container's capacity.
+ //!
+ //! @return container's capacity.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
static size_type capacity() { return Capacity; }
+
+ //! @brief Returns container's capacity.
+ //!
+ //! @return container's capacity.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
static size_type max_size() { return Capacity; }
+
+ //! @brief Returns the number of stored elements.
+ //!
+ //! @return Number of elements contained in the container.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
size_type size() const { return m_size; }
+
+ //! @brief Queries if the container contains elements.
+ //!
+ //! @return true if the number of elements contained in the
+ //! container is equal to 0.
+ //!
+ //! @par Throws
+ //! Nothing.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
bool empty() const { return 0 == m_size; }
private:
+ // @par Throws
+ // Nothing.
+ // @par Complexity
+ // Linear O(N).
+ template <std::size_t C>
+ void move_ctor_dispatch(varray<value_type, C> & other, boost::true_type /*use_memop*/)
+ {
+ ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
+ m_size = other.m_size;
+ }
+
+ // @par Throws
+ // @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor throws
+ // @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor throws.
+ // @par Complexity
+ // Linear O(N).
+ template <std::size_t C>
+ void move_ctor_dispatch(varray<value_type, C> & other, boost::false_type /*use_memop*/)
+ {
+ namespace sv = varray_detail;
+ sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
+ m_size = other.m_size;
+ }
+
+ // @par Throws
+ // Nothing.
+ // @par Complexity
+ // Linear O(N).
+ template <std::size_t C>
+ void move_assign_dispatch(varray<value_type, C> & other, boost::true_type /*use_memop*/)
+ {
+ this->clear();
+
+ ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
+ std::swap(m_size, other.m_size);
+ }
+
+ // @par Throws
+ // @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor or move assignment throws
+ // @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor or move assignment throws.
+ // @par Complexity
+ // Linear O(N).
+ template <std::size_t C>
+ void move_assign_dispatch(varray<value_type, C> & other, boost::false_type /*use_memop*/)
+ {
+ namespace sv = varray_detail;
+ if ( m_size <= static_cast<size_type>(other.size()) )
+ {
+ sv::move_if_noexcept(other.begin(), other.begin() + m_size, this->begin()); // may throw
+ // TODO - perform uninitialized_copy first?
+ sv::uninitialized_move_if_noexcept(other.begin() + m_size, other.end(), this->end()); // may throw
+ }
+ else
+ {
+ sv::move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
+ sv::destroy(this->begin() + other.size(), this->end());
+ }
+ m_size = other.size(); // update end
+ }
+
+ // @par Throws
+ // Nothing.
+ // @par Complexity
+ // Linear O(N).
+ template <std::size_t C>
+ void swap_dispatch(varray<value_type, C> & other, boost::true_type const& /*use_optimized_swap*/)
+ {
+ typedef typename
+ boost::mpl::if_c<
+ Capacity < C,
+ aligned_storage_type,
+ typename varray<value_type, C>::aligned_storage_type
+ >::type
+ storage_type;
+
+ storage_type temp;
+ Value * temp_ptr = reinterpret_cast<Value*>(temp.address());
+
+ ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
+ ::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
+ ::memcpy(other.data(), temp_ptr, sizeof(Value) * this->size());
+
+ std::swap(m_size, other.m_size);
+ }
+
+ // @par Throws
+ // If Value's move constructor or move assignment throws
+ // but only if use_memop_in_swap_and_move is false_type - default.
+ // @par Complexity
+ // Linear O(N).
+ template <std::size_t C>
+ void swap_dispatch(varray<value_type, C> & other, boost::false_type const& /*use_optimized_swap*/)
+ {
+ namespace sv = varray_detail;
+
+ typedef typename
+ vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+ if ( this->size() < other.size() )
+ swap_dispatch_impl(this->begin(), this->end(), other.begin(), other.end(), use_memop_in_swap_and_move()); // may throw
+ else
+ swap_dispatch_impl(other.begin(), other.end(), this->begin(), this->end(), use_memop_in_swap_and_move()); // may throw
+ std::swap(m_size, other.m_size);
+ }
+
+ // @par Throws
+ // Nothing.
+ // @par Complexity
+ // Linear O(N).
+ void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::true_type const& /*use_memop*/)
+ {
+ //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
+
+ namespace sv = varray_detail;
+ for (; first_sm != last_sm ; ++first_sm, ++first_la)
+ {
+ boost::aligned_storage<
+ sizeof(value_type),
+ boost::alignment_of<value_type>::value
+ > temp_storage;
+ value_type * temp_ptr = reinterpret_cast<value_type*>(temp_storage.address());
+
+ ::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type));
+ ::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type));
+ ::memcpy(boost::addressof(*first_la), temp_ptr, sizeof(value_type));
+ }
+
+ ::memcpy(first_sm, first_la, sizeof(value_type) * std::distance(first_la, last_la));
+ }
+
+ // @par Throws
+ // If Value's move constructor or move assignment throws.
+ // @par Complexity
+ // Linear O(N).
+ void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::false_type const& /*use_memop*/)
+ {
+ //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
+
+ namespace sv = varray_detail;
+ for (; first_sm != last_sm ; ++first_sm, ++first_la)
+ {
+ //boost::swap(*first_sm, *first_la); // may throw
+ value_type temp(boost::move(*first_sm)); // may throw
+ *first_sm = boost::move(*first_la); // may throw
+ *first_la = boost::move(temp); // may throw
+ }
+ sv::uninitialized_move(first_la, last_la, first_sm); // may throw
+ sv::destroy(first_la, last_la);
+ }
+
// insert
+ // @par Throws
+ // If Value's move constructor, move assignment throws
+ // or if Value's copy constructor or copy assignment throws.
+ // @par Complexity
+ // Linear O(N).
template <typename Iterator>
void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
{
- check_iterator_end_eq(position);
+ BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
- difference_type count = std::distance(first, last);
+ errh::check_iterator_end_eq(*this, position);
+
+ typename boost::iterator_difference<Iterator>::type
+ count = std::distance(first, last);
- check_capacity(m_size + count);
+ errh::check_capacity(*this, m_size + count); // may throw
if ( position == this->end() )
{
- this->uninitialized_copy(first, last, position); // may throw
+ namespace sv = varray_detail;
+
+ sv::uninitialized_copy(first, last, position); // may throw
m_size += count; // update end
}
else
{
- this->insert_in_the_middle(position, first, last, count); // may throw
+ this->insert_in_the_middle(position, first, last, count); // may throw
}
}
+ // @par Throws
+ // If Value's move constructor, move assignment throws
+ // or if Value's copy constructor or copy assignment throws.
+ // @par Complexity
+ // Linear O(N).
template <typename Iterator, typename Traversal>
void insert_dispatch(iterator position, Iterator first, Iterator last, Traversal const& /*not_random_access*/)
{
- check_iterator_end_eq(position);
+ errh::check_iterator_end_eq(*this, position);
if ( position == this->end() )
{
- std::pair<bool, size_type> copy_data =
- this->uninitialized_copy_checked(first, last, position, std::distance(position, this->begin() + Capacity)); // may throw
+ namespace sv = varray_detail;
+
+ std::ptrdiff_t d = std::distance(position, this->begin() + Capacity);
+ std::size_t count = sv::uninitialized_copy_s(first, last, position, d); // may throw
- check_capacity(copy_data.first ? m_size + copy_data.second : Capacity + 1);
+ errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? m_size + count : Capacity + 1); // may throw
- m_size += copy_data.second;
+ m_size += count;
}
else
{
- difference_type count = std::distance(first, last);
+ typename boost::iterator_difference<Iterator>::type
+ count = std::distance(first, last);
- check_capacity(m_size + count);
+ errh::check_capacity(*this, m_size + count); // may throw
- this->insert_in_the_middle(position, first, last, count); // may throw
+ this->insert_in_the_middle(position, first, last, count); // may throw
}
}
+ // @par Throws
+ // If Value's move constructor, move assignment throws
+ // or if Value's copy constructor or copy assignment throws.
+ // @par Complexity
+ // Linear O(N).
template <typename Iterator>
void insert_in_the_middle(iterator position, Iterator first, Iterator last, difference_type count)
{
+ namespace sv = varray_detail;
+
difference_type to_move = std::distance(position, this->end());
// TODO - should following lines check for exception and revert to the old size?
if ( count < to_move )
{
- this->uninitialized_copy(this->end() - count, this->end(), this->end()); // may throw
+ sv::uninitialized_move(this->end() - count, this->end(), this->end()); // may throw
m_size += count; // update end
- this->move_backward(position, position + to_move - count, this->end() - count); // may throw
- this->copy(first, last, position); // may throw
+ sv::move_backward(position, position + to_move - count, this->end() - count); // may throw
+ sv::copy(first, last, position); // may throw
}
else
{
Iterator middle_iter = first;
std::advance(middle_iter, to_move);
- this->uninitialized_copy(middle_iter, last, this->end()); // may throw
+ sv::uninitialized_copy(middle_iter, last, this->end()); // may throw
m_size += count - to_move; // update end
- this->uninitialized_copy(position, position + to_move, position + count); // may throw
+ sv::uninitialized_move(position, position + to_move, position + count); // may throw
m_size += to_move; // update end
- this->copy(first, middle_iter, position) ; // may throw
+ sv::copy(first, middle_iter, position); // may throw
}
}
// assign
+ // @par Throws
+ // If Value's constructor or assignment taking dereferenced Iterator throws.
+ // @par Complexity
+ // Linear O(N).
template <typename Iterator>
void assign_dispatch(Iterator first, Iterator last, boost::random_access_traversal_tag const& /*not_random_access*/)
{
- size_type s = std::distance(first, last);
+ namespace sv = varray_detail;
+
+ typename boost::iterator_difference<Iterator>::type
+ s = std::distance(first, last);
- check_capacity(s);
+ errh::check_capacity(*this, s); // may throw
- if ( m_size <= s )
+ if ( m_size <= static_cast<size_type>(s) )
{
- this->copy(first, first + m_size, this->begin()); // may throw
+ sv::copy(first, first + m_size, this->begin()); // may throw
// TODO - perform uninitialized_copy first?
- this->uninitialized_copy(first + m_size, last, this->end()); // may throw
+ sv::uninitialized_copy(first + m_size, last, this->end()); // may throw
}
else
{
- this->copy(first, last, this->begin()); // may throw
- this->destroy(this->begin() + s, this->end());
+ sv::copy(first, last, this->begin()); // may throw
+ sv::destroy(this->begin() + s, this->end());
}
m_size = s; // update end
}
+ // @par Throws
+ // If Value's constructor or assignment taking dereferenced Iterator throws.
+ // @par Complexity
+ // Linear O(N).
template <typename Iterator, typename Traversal>
void assign_dispatch(Iterator first, Iterator last, Traversal const& /*not_random_access*/)
{
+ namespace sv = varray_detail;
+
size_type s = 0;
iterator it = this->begin();
for ( ; it != this->end() && first != last ; ++it, ++first, ++s )
- *it = *first; // may throw
+ *it = *first; // may throw
- this->destroy(it, this->end());
+ sv::destroy(it, this->end());
- std::pair<bool, size_type> copy_data =
- this->uninitialized_copy_checked(first, last, it, std::distance(it, this->begin() + Capacity)); // may throw
- s += copy_data.second;
+ std::ptrdiff_t d = std::distance(it, this->begin() + Capacity);
+ std::size_t count = sv::uninitialized_copy_s(first, last, it, d); // may throw
+ s += count;
- check_capacity(copy_data.first ? s : Capacity + 1);
+ errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? s : Capacity + 1); // may throw
m_size = s; // update end
}
- // uninitialized_copy_checked
-
- template <typename Iterator>
- std::pair<bool, size_type> uninitialized_copy_checked(Iterator first, Iterator last, iterator dest, size_type max_count)
+ pointer ptr()
{
- size_type count = 0;
- iterator it = dest;
- BOOST_TRY
- {
- for ( ; first != last ; ++it, ++first, ++count )
- {
- if ( max_count <= count )
- return std::make_pair(false, count);
+ return pointer(static_cast<Value*>(m_storage.address()));
+ }
- this->uninitialized_fill(it, *first); // may throw
- }
- }
- BOOST_CATCH(...)
- {
- this->destroy(dest, it);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- return std::make_pair(true, count);
+ const_pointer ptr() const
+ {
+ return const_pointer(static_cast<const Value*>(m_storage.address()));
}
- // copy
+ size_type m_size;
+ aligned_storage_type m_storage;
+};
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- template <typename Iterator>
- void copy(Iterator first, Iterator last, iterator dst)
+template<typename Value>
+class varray<Value, 0>
+{
+ typedef varray_detail::varray_traits<Value, 0> vt;
+ typedef varray_detail::checker<varray> errh;
+
+public:
+ typedef typename vt::value_type value_type;
+ typedef typename vt::size_type size_type;
+ typedef typename vt::difference_type difference_type;
+ typedef typename vt::pointer pointer;
+ typedef typename vt::const_pointer const_pointer;
+ typedef typename vt::reference reference;
+ typedef typename vt::const_reference const_reference;
+
+ typedef pointer iterator;
+ typedef const_pointer const_iterator;
+ typedef boost::reverse_iterator<iterator> reverse_iterator;
+ typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ // nothrow
+ varray() {}
+
+ // strong
+ explicit varray(size_type count)
{
- typedef typename
- mpl::and_<
- has_trivial_assign<value_type>,
- mpl::or_<
- is_same<Iterator, value_type *>,
- is_same<Iterator, const value_type *>
- >,
- mpl::or_<
- is_same<iterator, value_type *>,
- is_same<iterator, const value_type *>
- >
- >::type
- use_memcpy;
-
- this->copy_dispatch(first, last, dst, use_memcpy()); // may throw
+ errh::check_capacity(*this, count); // may throw
}
- void copy_dispatch(const value_type * first, const value_type * last, value_type * dst,
- boost::mpl::bool_<true> const& /*use_memcpy*/)
+ // strong
+ varray(size_type count, value_type const&)
{
- ::memmove(dst, first, sizeof(value_type) * std::distance(first, last));
+ errh::check_capacity(*this, count); // may throw
}
- template <typename Iterator>
- void copy_dispatch(Iterator first, Iterator last, iterator dst,
- boost::mpl::bool_<false> const& /*use_memcpy*/)
+ // strong
+ varray(varray const& /*other*/)
{
- std::copy(first, last, dst); // may throw
+ //errh::check_capacity(*this, count);
}
- // uninitialized_copy
+ // strong
+ template <std::size_t C>
+ varray(varray<value_type, C> const& other)
+ {
+ errh::check_capacity(*this, other.size()); // may throw
+ }
+ // strong
template <typename Iterator>
- void uninitialized_copy(Iterator first, Iterator last, iterator dst)
+ varray(Iterator first, Iterator last)
{
- typedef typename
- mpl::and_<
- has_trivial_copy<value_type>,
- mpl::or_<
- is_same<Iterator, value_type *>,
- is_same<Iterator, const value_type *>
- >,
- mpl::or_<
- is_same<iterator, value_type *>,
- is_same<iterator, const value_type *>
- >
- >::type
- use_memcpy;
-
- this->uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
+ errh::check_capacity(*this, std::distance(first, last)); // may throw
}
- void uninitialized_copy_dispatch(const value_type * first, const value_type * last, value_type * dst,
- boost::mpl::bool_<true> const& /*use_memcpy*/)
+ // basic
+ varray & operator=(varray const& /*other*/)
{
- ::memcpy(dst, first, sizeof(value_type) * std::distance(first, last));
+ //errh::check_capacity(*this, other.size());
+ return *this;
}
- template <typename Iterator>
- void uninitialized_copy_dispatch(Iterator first, Iterator last, iterator dst,
- boost::mpl::bool_<false> const& /*use_memcpy*/)
+ // basic
+ template <size_t C>
+ varray & operator=(varray<value_type, C> const& other)
{
- std::uninitialized_copy(first, last, dst); // may throw
+ errh::check_capacity(*this, other.size()); // may throw
+ return *this;
}
- // uninitialized_fill
+ // nothrow
+ ~varray() {}
- template <typename V>
- void uninitialized_fill(iterator dst, V const& v)
+ // strong
+ void resize(size_type count)
{
- typedef typename
- mpl::and_<
- has_trivial_copy<value_type>,
- is_same<V, value_type>
- >::type
- use_memcpy;
-
- uninitialized_fill_dispatch(dst, v, use_memcpy()); // may throw
+ errh::check_capacity(*this, count); // may throw
}
- void uninitialized_fill_dispatch(iterator dst, value_type const& v,
- boost::mpl::bool_<true> const& /*use_memcpy*/)
+ // strong
+ void resize(size_type count, value_type const&)
{
- // TODO - check if value_type has operator& defined and call this version only if it hasn't
- const value_type * vptr = &v;
- ::memcpy(&(*dst), vptr, sizeof(value_type));
+ errh::check_capacity(*this, count); // may throw
}
- template <typename V>
- void uninitialized_fill_dispatch(iterator dst, V const& v,
- boost::mpl::bool_<false> const& /*use_memcpy*/)
+
+ // nothrow
+ void reserve(size_type count)
{
- new (&(*dst)) value_type(v); // may throw
+ errh::check_capacity(*this, count); // may throw
}
- template <typename V>
- void uninitialized_fill(iterator dst, BOOST_RV_REF(V) v)
+ // strong
+ void push_back(value_type const&)
{
- // TODO optimized version if has_trivial_move
- new (&(*dst)) value_type(v); // may throw
+ errh::check_capacity(*this, 1); // may throw
}
- // move
-
- template <typename Iterator>
- void move(Iterator first, Iterator last, iterator dst)
+ // nothrow
+ void pop_back()
{
- typedef typename
- mpl::and_<
- has_trivial_assign<value_type>,
- mpl::or_<
- is_same<Iterator, value_type *>,
- is_same<Iterator, const value_type *>
- >,
- mpl::or_<
- is_same<iterator, value_type *>,
- is_same<iterator, const value_type *>
- >
- >::type
- use_memcpy;
+ errh::check_not_empty(*this);
+ }
- this->move_dispatch(first, last, dst, use_memcpy()); // may throw
+ // basic
+ void insert(iterator position, value_type const&)
+ {
+ errh::check_iterator_end_eq(*this, position);
+ errh::check_capacity(*this, 1); // may throw
}
- void move_dispatch(const value_type * first, const value_type * last, value_type * dst,
- boost::mpl::bool_<true> const& /*use_mem*/)
+ // basic
+ void insert(iterator position, size_type count, value_type const&)
{
- ::memmove(dst, first, sizeof(value_type) * std::distance(first, last));
+ errh::check_iterator_end_eq(*this, position);
+ errh::check_capacity(*this, count); // may throw
}
+ // basic
template <typename Iterator>
- void move_dispatch(Iterator first, Iterator last, iterator dst,
- boost::mpl::bool_<false> const& /*use_mem*/)
+ void insert(iterator, Iterator first, Iterator last)
{
- std::copy(first, last, dst); // may throw
+ // TODO - add MPL_ASSERT, check if Iterator is really an iterator
+ typedef typename boost::iterator_traversal<Iterator>::type traversal;
+ errh::check_capacity(*this, std::distance(first, last)); // may throw
}
- // move_backward
+ // basic
+ void erase(iterator position)
+ {
+ errh::check_iterator_end_neq(*this, position);
+ }
- void move_backward(iterator first, iterator last, iterator dst)
+ // basic
+ void erase(iterator first, iterator last)
{
- typedef typename
- mpl::and_<
- has_trivial_assign<value_type>,
- mpl::or_<
- is_same<iterator, value_type *>,
- is_same<iterator, const value_type *>
- >
- >::type
- use_memcpy;
+ errh::check_iterator_end_eq(*this, first);
+ errh::check_iterator_end_eq(*this, last);
- this->move_backward_dispatch(first, last, dst, use_memcpy()); // may throw
+ //BOOST_ASSERT_MSG(0 <= n, "invalid range");
}
- void move_backward_dispatch(value_type * first, value_type * last, value_type * dst,
- boost::mpl::bool_<true> const& /*has_trivial_assign*/)
+ // basic
+ template <typename Iterator>
+ void assign(Iterator first, Iterator last)
{
- difference_type n = std::distance(first, last);
- ::memmove(dst - n, first, sizeof(value_type) * n);
+ // TODO - add MPL_ASSERT, check if Iterator is really an iterator
+ typedef typename boost::iterator_traversal<Iterator>::type traversal;
+ errh::check_capacity(*this, std::distance(first, last)); // may throw
}
- void move_backward_dispatch(iterator first, iterator last, iterator dst,
- boost::mpl::bool_<false> const& /*has_trivial_assign*/)
+ // basic
+ void assign(size_type count, value_type const&)
{
- std::copy_backward(first, last, dst); // may throw
+ errh::check_capacity(*this, count); // may throw
}
- // uninitialized_fill
+ // nothrow
+ void clear() {}
- template <typename V>
- void fill(iterator dst, V const& v)
+ // strong
+ reference at(size_type i)
{
- fill_dispatch(dst, v, has_trivial_assign<value_type>()); // may throw
+ errh::throw_out_of_bounds(*this, i); // may throw
+ return *(this->begin() + i);
}
- void fill_dispatch(iterator ptr, value_type const& v,
- boost::true_type const& /*has_trivial_assign*/)
+ // strong
+ const_reference at(size_type i) const
{
- // TODO - check if value_type has operator& defined and call this version only if it hasn't
- const value_type * vptr = &v;
- ::memcpy(&(*ptr), vptr, sizeof(value_type));
+ errh::throw_out_of_bounds(*this, i); // may throw
+ return *(this->begin() + i);
}
- template <typename V>
- void fill_dispatch(iterator ptr, V const& v,
- boost::false_type const& /*has_trivial_assign*/)
+ // nothrow
+ reference operator[](size_type i)
{
- *ptr = v; // may throw
+ errh::check_index(*this, i);
+ return *(this->begin() + i);
}
- // destroy
-
- void destroy(iterator first, iterator last)
+ // nothrow
+ const_reference operator[](size_type i) const
{
- this->destroy_dispatch(first, last, has_trivial_destructor<value_type>());
+ errh::check_index(*this, i);
+ return *(this->begin() + i);
}
- void destroy_dispatch(iterator /*first*/, iterator /*last*/,
- boost::true_type const& /*has_trivial_destructor*/)
- {}
-
- void destroy_dispatch(iterator first, iterator last,
- boost::false_type const& /*has_trivial_destructor*/)
+ // nothrow
+ reference front()
{
- for ( ; first != last ; ++first )
- first->~value_type();
+ errh::check_not_empty(*this);
+ return *(this->begin());
}
- // destroy
-
- void destroy(iterator it)
+ // nothrow
+ const_reference front() const
{
- this->destroy_dispatch(it, has_trivial_destructor<value_type>());
+ errh::check_not_empty(*this);
+ return *(this->begin());
}
- void destroy_dispatch(iterator /*ptr*/,
- boost::true_type const& /*has_trivial_destructor*/)
- {}
-
- void destroy_dispatch(iterator ptr,
- boost::false_type const& /*has_trivial_destructor*/)
+ // nothrow
+ reference back()
{
- ptr->~value_type();
+ errh::check_not_empty(*this);
+ return *(this->end() - 1);
}
- // uninitialized_move
-
- template <typename Iterator>
- void uninitialized_move(Iterator first, Iterator last, iterator dst)
+ // nothrow
+ const_reference back() const
{
- iterator o = dst;
- BOOST_TRY
- {
- for (; first != last; ++first, ++o )
- new (boost::addressof(*o)) value_type(boost::move(*first));
- }
- BOOST_CATCH(...)
- {
- destroy(dst, o);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ errh::check_not_empty(*this);
+ return *(this->end() - 1);
}
- // construct
+ // nothrow
+ Value * data() { return boost::addressof(*(this->ptr())); }
+ const Value * data() const { return boost::addressof(*(this->ptr())); }
- void construct(iterator first, iterator last)
- {
- this->construct_dispatch(first, last, has_trivial_constructor<value_type>()); // may throw
- }
+ // nothrow
+ iterator begin() { return this->ptr(); }
+ const_iterator begin() const { return this->ptr(); }
+ const_iterator cbegin() const { return this->ptr(); }
+ iterator end() { return this->begin(); }
+ const_iterator end() const { return this->begin(); }
+ const_iterator cend() const { return this->cbegin(); }
+ // nothrow
+ reverse_iterator rbegin() { return reverse_iterator(this->end()); }
+ const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
+ const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
+ reverse_iterator rend() { return reverse_iterator(this->begin()); }
+ const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
+ const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
- void construct_dispatch(iterator /*first*/, iterator /*last*/,
- boost::true_type const& /*has_trivial_constructor*/)
- {}
+ // nothrow
+ size_type capacity() const { return 0; }
+ size_type max_size() const { return 0; }
+ size_type size() const { return 0; }
+ bool empty() const { return true; }
- void construct_dispatch(iterator first, iterator last,
- boost::false_type const& /*has_trivial_constructor*/)
+private:
+ pointer ptr()
{
- iterator it = first;
- BOOST_TRY
- {
- for ( ; it != last ; ++it )
- new (&(*it)) value_type(); // may throw
- }
- BOOST_CATCH(...)
- {
- this->destroy(first, it);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ return pointer(reinterpret_cast<Value*>(this));
}
- void check_capacity(size_type BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(s)) const
+ const_pointer ptr() const
{
- BOOST_ASSERT_MSG(s <= Capacity, "size can't exceed the capacity");
- //if ( Capacity < s ) throw std::bad_alloc();
+ return const_pointer(reinterpret_cast<const Value*>(this));
}
+};
- void check_empty() const
- {
- BOOST_ASSERT_MSG(0 < m_size, "the container is empty");
- }
+#endif // !BOOST_CONTAINER_DOXYGEN_INVOKED
- void check_iterator_end_neq(const_iterator position) const
- {
- BOOST_ASSERT_MSG(this->begin() <= position && position < this->end(), "iterator out of bounds");
+//! @brief Checks if contents of two varrays are equal.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @return \c true if containers have the same size and elements in both containers are equal.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator== (varray<V, C1> const& x, varray<V, C2> const& y)
+{
+ return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
+}
- /*BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(
- difference_type dist = std::distance(this->begin(), position);
- )
- BOOST_ASSERT_MSG(
- 0 <= dist &&
- ( sizeof(dist) <= sizeof(m_size) ?
- (static_cast<size_type>(dist) < m_size) :
- ( dist < static_cast<difference_type>(m_size))
- ), "invalid iterator"
- );*/
- }
+//! @brief Checks if contents of two varrays are not equal.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @return \c true if containers have different size or elements in both containers are not equal.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator!= (varray<V, C1> const& x, varray<V, C2> const& y)
+{
+ return !(x==y);
+}
- void check_iterator_end_eq(const_iterator position) const
- {
- BOOST_ASSERT_MSG(this->begin() <= position && position <= this->end(), "iterator out of bounds");
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @return \c true if x compares lexicographically less than y.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator< (varray<V, C1> const& x, varray<V, C2> const& y)
+{
+ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
- /*BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(
- difference_type dist = std::distance(this->begin(), position);
- )
- BOOST_ASSERT_MSG(
- 0 <= dist &&
- ( sizeof(dist) <= sizeof(m_size) ?
- (static_cast<size_type>(dist) <= m_size) :
- ( dist <= static_cast<difference_type>(m_size))
- ), "invalid iterator"
- );*/
- }
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @return \c true if y compares lexicographically less than x.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator> (varray<V, C1> const& x, varray<V, C2> const& y)
+{
+ return y<x;
+}
- pointer ptr()
- {
- return pointer(static_cast<value_type *>(m_storage.address()));
- }
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @return \c true if y don't compare lexicographically less than x.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator<= (varray<V, C1> const& x, varray<V, C2> const& y)
+{
+ return !(y<x);
+}
- const_pointer ptr() const
- {
- return const_pointer(static_cast<const value_type *>(m_storage.address()));
- }
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @return \c true if x don't compare lexicographically less than y.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+bool operator>= (varray<V, C1> const& x, varray<V, C2> const& y)
+{
+ return !(x<y);
+}
- boost::aligned_storage<sizeof(Value[Capacity]), boost::alignment_of<Value[Capacity]>::value> m_storage;
- size_type m_size;
-};
+//! @brief Swaps contents of two varrays.
+//!
+//! This function calls varray::swap().
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x The first varray.
+//! @param y The second varray.
+//!
+//! @par Complexity
+//! Linear O(N).
+template<typename V, std::size_t C1, std::size_t C2>
+inline void swap(varray<V, C1> & x, varray<V, C2> & y)
+{
+ x.swap(y);
+}
}}}} // namespace boost::geometry::index::detail
-#ifdef BOOST_MSVC
-#pragma warning (pop)
-#endif
+// TODO - REMOVE/CHANGE
+#include <boost/container/detail/config_end.hpp>
#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_HPP
Copied: branches/release/boost/geometry/index/detail/varray_detail.hpp (from r84886, trunk/boost/geometry/index/detail/varray_detail.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/boost/geometry/index/detail/varray_detail.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/boost/geometry/index/detail/varray_detail.hpp)
@@ -0,0 +1,714 @@
+// Boost.Geometry
+//
+// varray details
+//
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2013 Andrew Hundt.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
+#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
+
+#include <cstddef>
+#include <cstring>
+#include <memory>
+#include <limits>
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/int.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+//#include <boost/type_traits/has_nothrow_constructor.hpp>
+//#include <boost/type_traits/has_nothrow_copy.hpp>
+//#include <boost/type_traits/has_nothrow_assign.hpp>
+//#include <boost/type_traits/has_nothrow_destructor.hpp>
+
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/config.hpp>
+#include <boost/move/move.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+
+// TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
+
+#if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
+#include <vector>
+#include <boost/container/vector.hpp>
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
+
+namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail {
+
+template <typename I>
+struct are_elements_contiguous : boost::is_pointer<I>
+{};
+
+// EXPERIMENTAL - not finished
+// Conditional setup - mark vector iterators defined in known implementations
+// as iterators pointing to contiguous ranges
+
+#if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
+
+template <typename Pointer>
+struct are_elements_contiguous<
+ boost::container::container_detail::vector_const_iterator<Pointer>
+> : boost::true_type
+{};
+
+template <typename Pointer>
+struct are_elements_contiguous<
+ boost::container::container_detail::vector_iterator<Pointer>
+> : boost::true_type
+{};
+
+#if defined(BOOST_DINKUMWARE_STDLIB)
+
+template <typename T>
+struct are_elements_contiguous<
+ std::_Vector_const_iterator<T>
+> : boost::true_type
+{};
+
+template <typename T>
+struct are_elements_contiguous<
+ std::_Vector_iterator<T>
+> : boost::true_type
+{};
+
+#elif defined(BOOST_GNU_STDLIB)
+
+template <typename P, typename T, typename A>
+struct are_elements_contiguous<
+ __gnu_cxx::__normal_iterator<P, std::vector<T, A> >
+> : boost::true_type
+{};
+
+#elif defined(_LIBCPP_VERSION)
+
+// TODO - test it first
+//template <typename P>
+//struct are_elements_contiguous<
+// __wrap_iter<P>
+//> : boost::true_type
+//{};
+
+#else // OTHER_STDLIB
+
+// TODO - add other iterators implementations
+
+#endif // STDLIB
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
+
+// True if iterator values are the same and both iterators points to the ranges of contiguous elements
+
+template <typename I, typename O>
+struct are_corresponding :
+ ::boost::mpl::and_<
+ ::boost::is_same<
+ ::boost::remove_const<
+ typename ::boost::iterator_value<I>::type
+ >,
+ ::boost::remove_const<
+ typename ::boost::iterator_value<O>::type
+ >
+ >,
+ are_elements_contiguous<I>,
+ are_elements_contiguous<O>
+ >
+{};
+
+template <typename I, typename V>
+struct is_corresponding_value :
+ ::boost::is_same<
+ ::boost::remove_const<
+ typename ::boost::iterator_value<I>::type
+ >,
+ ::boost::remove_const<V>
+ >
+{};
+
+// destroy(I, I)
+
+template <typename I>
+void destroy_dispatch(I /*first*/, I /*last*/,
+ boost::true_type const& /*has_trivial_destructor*/)
+{}
+
+template <typename I>
+void destroy_dispatch(I first, I last,
+ boost::false_type const& /*has_trivial_destructor*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ for ( ; first != last ; ++first )
+ first->~value_type();
+}
+
+template <typename I>
+void destroy(I first, I last)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ destroy_dispatch(first, last, has_trivial_destructor<value_type>());
+}
+
+// destroy(I)
+
+template <typename I>
+void destroy_dispatch(I /*pos*/,
+ boost::true_type const& /*has_trivial_destructor*/)
+{}
+
+template <typename I>
+void destroy_dispatch(I pos,
+ boost::false_type const& /*has_trivial_destructor*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ pos->~value_type();
+}
+
+template <typename I>
+void destroy(I pos)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ destroy_dispatch(pos, has_trivial_destructor<value_type>());
+}
+
+// copy(I, I, O)
+
+template <typename I, typename O>
+inline O copy_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<true> const& /*use_memmove*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ typename boost::iterator_difference<I>::type d = std::distance(first, last);
+
+ ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
+ return dst + d;
+}
+
+template <typename I, typename O>
+inline O copy_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<false> const& /*use_memmove*/)
+{
+ return std::copy(first, last, dst); // may throw
+}
+
+template <typename I, typename O>
+inline O copy(I first, I last, O dst)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ are_corresponding<I, O>,
+ ::boost::has_trivial_assign<
+ typename ::boost::iterator_value<O>::type
+ >
+ >::type
+ use_memmove;
+
+ return copy_dispatch(first, last, dst, use_memmove()); // may throw
+}
+
+// uninitialized_copy(I, I, O)
+
+template <typename I, typename O>
+inline
+O uninitialized_copy_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<true> const& /*use_memcpy*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ typename boost::iterator_difference<I>::type d = std::distance(first, last);
+
+ ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
+ return dst + d;
+}
+
+template <typename I, typename F>
+inline
+F uninitialized_copy_dispatch(I first, I last, F dst,
+ boost::mpl::bool_<false> const& /*use_memcpy*/)
+{
+ return std::uninitialized_copy(first, last, dst); // may throw
+}
+
+template <typename I, typename F>
+inline
+F uninitialized_copy(I first, I last, F dst)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ are_corresponding<I, F>,
+ ::boost::has_trivial_copy<
+ typename ::boost::iterator_value<F>::type
+ >
+ >::type
+ use_memcpy;
+
+ return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
+}
+
+// uninitialized_move(I, I, O)
+
+template <typename I, typename O>
+inline
+O uninitialized_move_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<true> const& /*use_memcpy*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ typename boost::iterator_difference<I>::type d = std::distance(first, last);
+
+ ::memcpy(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
+ return dst + d;
+}
+
+template <typename I, typename O>
+inline
+O uninitialized_move_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<false> const& /*use_memcpy*/)
+{
+ //return boost::uninitialized_move(first, last, dst); // may throw
+
+ O o = dst;
+
+ BOOST_TRY
+ {
+ typedef typename std::iterator_traits<O>::value_type value_type;
+ for (; first != last; ++first, ++o )
+ new (boost::addressof(*o)) value_type(boost::move(*first));
+ }
+ BOOST_CATCH(...)
+ {
+ destroy(dst, o);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+
+ return dst;
+}
+
+template <typename I, typename O>
+inline
+O uninitialized_move(I first, I last, O dst)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ are_corresponding<I, O>,
+ ::boost::has_trivial_copy<
+ typename ::boost::iterator_value<O>::type
+ >
+ >::type
+ use_memcpy;
+
+ return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw
+}
+
+// TODO - move uses memmove - implement 2nd version using memcpy?
+
+// move(I, I, O)
+
+template <typename I, typename O>
+inline
+O move_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<true> const& /*use_memmove*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ typename boost::iterator_difference<I>::type d = std::distance(first, last);
+
+ ::memmove(boost::addressof(*dst), boost::addressof(*first), sizeof(value_type) * d);
+ return dst + d;
+}
+
+template <typename I, typename O>
+inline
+O move_dispatch(I first, I last, O dst,
+ boost::mpl::bool_<false> const& /*use_memmove*/)
+{
+ return boost::move(first, last, dst); // may throw
+}
+
+template <typename I, typename O>
+inline
+O move(I first, I last, O dst)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ are_corresponding<I, O>,
+ ::boost::has_trivial_assign<
+ typename ::boost::iterator_value<O>::type
+ >
+ >::type
+ use_memmove;
+
+ return move_dispatch(first, last, dst, use_memmove()); // may throw
+}
+
+// move_backward(BDI, BDI, BDO)
+
+template <typename BDI, typename BDO>
+inline
+BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
+ boost::mpl::bool_<true> const& /*use_memmove*/)
+{
+ typedef typename boost::iterator_value<BDI>::type value_type;
+ typename boost::iterator_difference<BDI>::type d = std::distance(first, last);
+
+ BDO foo(dst - d);
+ ::memmove(boost::addressof(*foo), boost::addressof(*first), sizeof(value_type) * d);
+ return foo;
+}
+
+template <typename BDI, typename BDO>
+inline
+BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
+ boost::mpl::bool_<false> const& /*use_memmove*/)
+{
+ return boost::move_backward(first, last, dst); // may throw
+}
+
+template <typename BDI, typename BDO>
+inline
+BDO move_backward(BDI first, BDI last, BDO dst)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ are_corresponding<BDI, BDO>,
+ ::boost::has_trivial_assign<
+ typename ::boost::iterator_value<BDO>::type
+ >
+ >::type
+ use_memmove;
+
+ return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
+}
+
+template <typename T>
+struct has_nothrow_move : public
+ ::boost::mpl::or_<
+ boost::mpl::bool_<
+ ::boost::has_nothrow_move<
+ typename ::boost::remove_const<T>::type
+ >::value
+ >,
+ boost::mpl::bool_<
+ ::boost::has_nothrow_move<T>::value
+ >
+ >
+{};
+
+// uninitialized_move_if_noexcept(I, I, O)
+
+template <typename I, typename O>
+inline
+O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
+{ return uninitialized_move(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
+{ return uninitialized_copy(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O uninitialized_move_if_noexcept(I first, I last, O dst)
+{
+ typedef typename has_nothrow_move<
+ typename ::boost::iterator_value<O>::type
+ >::type use_move;
+
+ return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
+}
+
+// move_if_noexcept(I, I, O)
+
+template <typename I, typename O>
+inline
+O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
+{ return move(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
+{ return copy(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O move_if_noexcept(I first, I last, O dst)
+{
+ typedef typename has_nothrow_move<
+ typename ::boost::iterator_value<O>::type
+ >::type use_move;
+
+ return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
+}
+
+// uninitialized_fill(I, I)
+
+template <typename I>
+inline
+void uninitialized_fill_dispatch(I /*first*/, I /*last*/,
+ boost::true_type const& /*has_trivial_constructor*/,
+ boost::true_type const& /*disable_trivial_init*/)
+{}
+
+template <typename I>
+inline
+void uninitialized_fill_dispatch(I first, I last,
+ boost::true_type const& /*has_trivial_constructor*/,
+ boost::false_type const& /*disable_trivial_init*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ for ( ; first != last ; ++first )
+ new (boost::addressof(*first)) value_type();
+}
+
+template <typename I, typename DisableTrivialInit>
+inline
+void uninitialized_fill_dispatch(I first, I last,
+ boost::false_type const& /*has_trivial_constructor*/,
+ DisableTrivialInit const& /*not_used*/)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ I it = first;
+
+ BOOST_TRY
+ {
+ for ( ; it != last ; ++it )
+ new (boost::addressof(*it)) value_type(); // may throw
+ }
+ BOOST_CATCH(...)
+ {
+ destroy(first, it);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+}
+
+template <typename I, typename DisableTrivialInit>
+inline
+void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
+{
+ typedef typename boost::iterator_value<I>::type value_type;
+ uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
+}
+
+// construct(I)
+
+template <typename I>
+inline
+void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I /*pos*/)
+{}
+
+template <typename I>
+inline
+void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
+{
+ typedef typename ::boost::iterator_value<I>::type value_type;
+ new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
+}
+
+template <typename DisableTrivialInit, typename I>
+inline
+void construct(DisableTrivialInit const&, I pos)
+{
+ typedef typename ::boost::iterator_value<I>::type value_type;
+ typedef typename ::boost::mpl::and_<
+ boost::has_trivial_constructor<value_type>,
+ DisableTrivialInit
+ >::type dont_init;
+
+ construct_dispatch(dont_init(), pos); // may throw
+}
+
+// construct(I, V)
+
+template <typename I, typename V>
+inline
+void construct_dispatch(I pos, V const& v,
+ boost::mpl::bool_<true> const& /*use_memcpy*/)
+{
+ ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
+}
+
+template <typename I, typename P>
+inline
+void construct_dispatch(I pos, P const& p,
+ boost::mpl::bool_<false> const& /*use_memcpy*/)
+{
+ typedef typename boost::iterator_value<I>::type V;
+ new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
+}
+
+template <typename DisableTrivialInit, typename I, typename P>
+inline
+void construct(DisableTrivialInit const&,
+ I pos, P const& p)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ is_corresponding_value<I, P>,
+ ::boost::has_trivial_copy<P>
+ >::type
+ use_memcpy;
+
+ construct_dispatch(pos, p, use_memcpy()); // may throw
+}
+
+// Needed by push_back(V &&)
+
+template <typename DisableTrivialInit, typename I, typename P>
+inline
+void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ is_corresponding_value<I, P>,
+ ::boost::has_trivial_copy<P>
+ >::type
+ use_memcpy;
+
+ typedef typename boost::iterator_value<I>::type V;
+ new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
+}
+
+// Needed by emplace_back() and emplace()
+
+#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+template <typename DisableTrivialInit, typename I, class ...Args>
+inline
+void construct(DisableTrivialInit const&,
+ I pos,
+ BOOST_FWD_REF(Args) ...args)
+{
+ typedef typename boost::iterator_value<I>::type V;
+ new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
+}
+
+#else // !BOOST_NO_VARIADIC_TEMPLATES
+
+// BOOST_NO_RVALUE_REFERENCES -> P0 const& p0
+// !BOOST_NO_RVALUE_REFERENCES -> P0 && p0
+// which means that version with one parameter may take V const& v
+
+#define BOOST_PP_LOCAL_MACRO(n) \
+template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
+inline \
+void construct(DisableTrivialInit const&, \
+ I pos, \
+ BOOST_CONTAINER_PP_PARAM(P, p) \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+{ \
+ typedef typename boost::iterator_value<I>::type V; \
+ new \
+ (static_cast<void*>(boost::addressof(*pos))) \
+ V(p, BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); /*may throw*/ \
+} \
+//
+#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#endif // !BOOST_NO_VARIADIC_TEMPLATES
+#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
+
+// assign(I, V)
+
+template <typename I, typename V>
+inline
+void assign_dispatch(I pos, V const& v,
+ boost::mpl::bool_<true> const& /*use_memcpy*/)
+{
+ ::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
+}
+
+template <typename I, typename V>
+inline
+void assign_dispatch(I pos, V const& v,
+ boost::mpl::bool_<false> const& /*use_memcpy*/)
+{
+ *pos = v; // may throw
+}
+
+template <typename I, typename V>
+inline
+void assign(I pos, V const& v)
+{
+ typedef typename
+ ::boost::mpl::and_<
+ is_corresponding_value<I, V>,
+ ::boost::has_trivial_assign<V>
+ >::type
+ use_memcpy;
+
+ assign_dispatch(pos, v, use_memcpy()); // may throw
+}
+
+template <typename I, typename V>
+inline
+void assign(I pos, BOOST_RV_REF(V) v)
+{
+ *pos = boost::move(v); // may throw
+}
+
+
+// uninitialized_copy_s
+
+template <typename I, typename F>
+inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count)
+{
+ std::size_t count = 0;
+ F it = dest;
+
+ BOOST_TRY
+ {
+ for ( ; first != last ; ++it, ++first, ++count )
+ {
+ if ( max_count <= count )
+ return (std::numeric_limits<std::size_t>::max)();
+
+ // dummy 0 as DisableTrivialInit
+ construct(0, it, *first); // may throw
+ }
+ }
+ BOOST_CATCH(...)
+ {
+ destroy(dest, it);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+
+ return count;
+}
+
+// scoped_destructor
+
+template<class T>
+class scoped_destructor
+{
+public:
+ scoped_destructor(T * ptr) : m_ptr(ptr) {}
+
+ ~scoped_destructor()
+ {
+ if(m_ptr)
+ destroy(m_ptr);
+ }
+
+ void release() { m_ptr = 0; }
+
+private:
+ T * m_ptr;
+};
+
+}}}}} // namespace boost::geometry::index::detail::varray_detail
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
Modified: branches/release/boost/geometry/index/parameters.hpp
==============================================================================
--- branches/release/boost/geometry/index/parameters.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/parameters.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -52,7 +52,7 @@
inline size_t default_rstar_reinserted_elements_d()
{
return (std::numeric_limits<size_t>::max)();
-};
+}
inline size_t default_rstar_reinserted_elements_d_calc(size_t max_elements, size_t reinserted_elements)
{
Modified: branches/release/boost/geometry/index/predicates.hpp
==============================================================================
--- branches/release/boost/geometry/index/predicates.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/predicates.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -15,9 +15,6 @@
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/assert.hpp>
-// TODO: awulkiew - temporary
-#include <boost/geometry/algorithms/covered_by.hpp>
-
#include <boost/geometry/index/detail/predicates.hpp>
#include <boost/geometry/index/detail/tuples.hpp>
@@ -27,6 +24,35 @@
namespace boost { namespace geometry { namespace index {
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
+/*!
+\brief Generate \c contains() predicate.
+
+Generate a predicate defining Value and Geometry relationship.
+Value will be returned by the query if <tt>bg::within(Geometry, Indexable)</tt>
+returns true.
+
+\par Example
+\verbatim
+bgi::query(spatial_index, bgi::contains(box), std::back_inserter(result));
+\endverbatim
+
+\ingroup predicates
+
+\tparam Geometry The Geometry type.
+
+\param g The Geometry object.
+*/
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::contains_tag, false>
+contains(Geometry const& g)
+{
+ return detail::spatial_predicate<Geometry, detail::contains_tag, false>(g);
+}
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
/*!
\brief Generate \c covered_by() predicate.
@@ -45,12 +71,42 @@
\param g The Geometry object.
*/
-template <typename Geometry>
-inline detail::covered_by<Geometry> covered_by(Geometry const& g)
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::covered_by_tag, false>
+covered_by(Geometry const& g)
+{
+ return detail::spatial_predicate<Geometry, detail::covered_by_tag, false>(g);
+}
+
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
+/*!
+\brief Generate \c covers() predicate.
+
+Generate a predicate defining Value and Geometry relationship.
+Value will be returned by the query if <tt>bg::covered_by(Geometry, Indexable)</tt>
+returns true.
+
+\par Example
+\verbatim
+bgi::query(spatial_index, bgi::covers(box), std::back_inserter(result));
+\endverbatim
+
+\ingroup predicates
+
+\tparam Geometry The Geometry type.
+
+\param g The Geometry object.
+*/
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::covers_tag, false>
+covers(Geometry const& g)
{
- return detail::covered_by<Geometry>(g);
+ return detail::spatial_predicate<Geometry, detail::covers_tag, false>(g);
}
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
/*!
\brief Generate \c disjoint() predicate.
@@ -69,10 +125,11 @@
\param g The Geometry object.
*/
-template <typename Geometry>
-inline detail::disjoint<Geometry> disjoint(Geometry const& g)
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::disjoint_tag, false>
+disjoint(Geometry const& g)
{
- return detail::disjoint<Geometry>(g);
+ return detail::spatial_predicate<Geometry, detail::disjoint_tag, false>(g);
}
/*!
@@ -95,10 +152,11 @@
\param g The Geometry object.
*/
-template <typename Geometry>
-inline detail::intersects<Geometry> intersects(Geometry const& g)
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::intersects_tag, false>
+intersects(Geometry const& g)
{
- return detail::intersects<Geometry>(g);
+ return detail::spatial_predicate<Geometry, detail::intersects_tag, false>(g);
}
/*!
@@ -119,30 +177,36 @@
\param g The Geometry object.
*/
-template <typename Geometry>
-inline detail::overlaps<Geometry> overlaps(Geometry const& g)
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::overlaps_tag, false>
+overlaps(Geometry const& g)
{
- return detail::overlaps<Geometry>(g);
+ return detail::spatial_predicate<Geometry, detail::overlaps_tag, false>(g);
}
-//*!
-//\brief Generate \c touches() predicate.
-//
-//Generate a predicate defining Value and Geometry relationship.
-//Value will be returned by the query if <tt>bg::touches(Indexable, Geometry)</tt>
-//returns true.
-//
-//\ingroup predicates
-//
-//\tparam Geometry The Geometry type.
-//
-//\param g The Geometry object.
-//*/
-//template <typename Geometry>
-//inline detail::touches<Geometry> touches(Geometry const& g)
-//{
-// return detail::touches<Geometry>(g);
-//}
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
+/*!
+\brief Generate \c touches() predicate.
+
+Generate a predicate defining Value and Geometry relationship.
+Value will be returned by the query if <tt>bg::touches(Indexable, Geometry)</tt>
+returns true.
+
+\ingroup predicates
+
+\tparam Geometry The Geometry type.
+
+\param g The Geometry object.
+*/
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::touches_tag, false>
+touches(Geometry const& g)
+{
+ return detail::spatial_predicate<Geometry, detail::touches_tag, false>(g);
+}
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
/*!
\brief Generate \c within() predicate.
@@ -162,10 +226,11 @@
\param g The Geometry object.
*/
-template <typename Geometry>
-inline detail::within<Geometry> within(Geometry const& g)
+template <typename Geometry> inline
+detail::spatial_predicate<Geometry, detail::within_tag, false>
+within(Geometry const& g)
{
- return detail::within<Geometry>(g);
+ return detail::spatial_predicate<Geometry, detail::within_tag, false>(g);
}
/*!
@@ -201,10 +266,11 @@
\param pred The unary predicate function or function object.
*/
-template <typename UnaryPredicate>
-inline detail::satisfies<UnaryPredicate> satisfies(UnaryPredicate const& pred)
+template <typename UnaryPredicate> inline
+detail::satisfies<UnaryPredicate, false>
+satisfies(UnaryPredicate const& pred)
{
- return detail::satisfies<UnaryPredicate>(pred);
+ return detail::satisfies<UnaryPredicate, false>(pred);
}
/*!
@@ -271,102 +337,18 @@
// operator! generators
-template <typename Fun> inline
-not_satisfies<Fun>
-operator!(satisfies<Fun> const& p)
+template <typename Fun, bool Negated> inline
+satisfies<Fun, !Negated>
+operator!(satisfies<Fun, Negated> const& p)
{
- return not_satisfies<Fun>(p);
+ return satisfies<Fun, !Negated>(p);
}
-template <typename Fun> inline
-satisfies<Fun>
-operator!(not_satisfies<Fun> const& p)
-{
- return satisfies<Fun>(p);
-}
-
-template <typename Geometry> inline
-not_covered_by<Geometry>
-operator!(covered_by<Geometry> const& p)
-{
- return not_covered_by<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-covered_by<Geometry>
-operator!(not_covered_by<Geometry> const& p)
-{
- return covered_by<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-not_disjoint<Geometry>
-operator!(disjoint<Geometry> const& p)
-{
- return not_disjoint<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-disjoint<Geometry>
-operator!(not_disjoint<Geometry> const& p)
-{
- return disjoint<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-not_intersects<Geometry>
-operator!(intersects<Geometry> const& p)
-{
- return not_intersects<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-intersects<Geometry>
-operator!(not_intersects<Geometry> const& p)
-{
- return intersects<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-not_overlaps<Geometry>
-operator!(overlaps<Geometry> const& p)
-{
- return not_overlaps<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-overlaps<Geometry>
-operator!(not_overlaps<Geometry> const& p)
-{
- return overlaps<Geometry>(p.geometry);
-}
-
-//template <typename Geometry> inline
-//not_touches<Geometry>
-//operator!(touches<Geometry> const& p)
-//{
-// return not_touches<Geometry>(p.geometry);
-//}
-//
-//template <typename Geometry> inline
-//touches<Geometry>
-//operator!(not_touches<Geometry> const& p)
-//{
-// return touches<Geometry>(p.geometry);
-//}
-
-template <typename Geometry> inline
-not_within<Geometry>
-operator!(within<Geometry> const& p)
-{
- return not_within<Geometry>(p.geometry);
-}
-
-template <typename Geometry> inline
-within<Geometry>
-operator!(not_within<Geometry> const& p)
+template <typename Geometry, typename Tag, bool Negated> inline
+spatial_predicate<Geometry, Tag, !Negated>
+operator!(spatial_predicate<Geometry, Tag, Negated> const& p)
{
- return within<Geometry>(p.geometry);
+ return spatial_predicate<Geometry, Tag, !Negated>(p.geometry);
}
// operator&& generators
Modified: branches/release/boost/geometry/index/rtree.hpp
==============================================================================
--- branches/release/boost/geometry/index/rtree.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/index/rtree.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -29,7 +29,6 @@
#include <boost/geometry/index/indexable.hpp>
#include <boost/geometry/index/equal_to.hpp>
-#include <boost/geometry/index/detail/indexable.hpp>
#include <boost/geometry/index/detail/translator.hpp>
#include <boost/geometry/index/predicates.hpp>
@@ -56,8 +55,12 @@
#include <boost/geometry/index/detail/rtree/rstar/rstar.hpp>
//#include <boost/geometry/extensions/index/detail/rtree/kmeans/kmeans.hpp>
+#include <boost/geometry/index/detail/rtree/pack_create.hpp>
+
#include <boost/geometry/index/inserter.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
+
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
#include <boost/geometry/index/detail/rtree/query_iterators.hpp>
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_TYPE_ERASED_ITERATORS
@@ -139,11 +142,17 @@
>::type indexable_type;
/*! \brief The Box type used by the R-tree. */
- typedef typename index::detail::default_box_type<indexable_type>::type bounds_type;
+ typedef geometry::model::box<
+ geometry::model::point<
+ typename coordinate_type<indexable_type>::type,
+ dimension<indexable_type>::value,
+ typename coordinate_system<indexable_type>::type
+ >
+ >
+ bounds_type;
-#if !defined(BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE)
private:
-#endif
+
typedef detail::translator<IndexableGetter, EqualTo> translator_type;
typedef bounds_type box_type;
@@ -158,6 +167,8 @@
typedef typename allocators_type::node_pointer node_pointer;
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
+ friend class detail::rtree::utilities::view<rtree>;
+
public:
/*! \brief Type of reference to Value. */
@@ -232,16 +243,12 @@
allocator_type const& allocator = allocator_type())
: m_members(getter, equal, parameters, allocator)
{
- BOOST_TRY
- {
- this->insert(first, last);
- }
- BOOST_CATCH(...)
- {
- this->raw_destroy(*this);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
+ size_type vc = 0, ll = 0;
+ m_members.root = pack::apply(first, last, vc, ll,
+ m_members.parameters(), m_members.translator(), m_members.allocators());
+ m_members.values_count = vc;
+ m_members.leafs_level = ll;
}
/*!
@@ -266,16 +273,12 @@
allocator_type const& allocator = allocator_type())
: m_members(getter, equal, parameters, allocator)
{
- BOOST_TRY
- {
- this->insert(rng);
- }
- BOOST_CATCH(...)
- {
- this->raw_destroy(*this);
- BOOST_RETHROW
- }
- BOOST_CATCH_END
+ typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
+ size_type vc = 0, ll = 0;
+ m_members.root = pack::apply(::boost::begin(rng), ::boost::end(rng), vc, ll,
+ m_members.parameters(), m_members.translator(), m_members.allocators());
+ m_members.values_count = vc;
+ m_members.leafs_level = ll;
}
/*!
@@ -972,9 +975,8 @@
return m_members.allocators().allocator();
}
-#if !defined(BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE)
private:
-#endif
+
/*!
\brief Returns the translator object.
@@ -1007,21 +1009,6 @@
}
/*!
- \brief Returns the number of stored objects. Same as size().
-
- This function is not a part of the 'official' interface.
-
- \return The number of stored objects.
-
- \par Throws
- Nothing.
- */
- inline size_type values_count() const
- {
- return m_members.values_count;
- }
-
- /*!
\brief Returns the depth of the R-tree.
This function is not a part of the 'official' interface.
@@ -1037,6 +1024,7 @@
}
private:
+
/*!
\pre Root node must exist - m_root != 0.
Modified: branches/release/boost/geometry/strategies/side_info.hpp
==============================================================================
--- branches/release/boost/geometry/strategies/side_info.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/boost/geometry/strategies/side_info.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -14,9 +14,11 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
#define BOOST_GEOMETRY_STRATEGIES_SIDE_INFO_HPP
-
+#include <cmath>
#include <utility>
-
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
+#include <iostream>
+#endif
namespace boost { namespace geometry
{
@@ -143,7 +145,7 @@
return sides[Which].first == 0 ? 0 : 1;
}
-
+#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
inline void debug() const
{
std::cout << sides[0].first << " "
@@ -152,7 +154,7 @@
<< sides[1].second
<< std::endl;
}
-
+#endif
inline void reverse()
{
Modified: branches/release/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp
==============================================================================
--- branches/release/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/doxy/doxygen_input/groups/groups.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -56,7 +56,7 @@
\defgroup set set: set geometries
\defgroup simplify simplify: remove points from a geometry, keeping shape (simplification or generalization)
\defgroup strategies strategies: strategies
-\defgroup svg x Extension svg: Stream SVG (Scalable Vector Graphics)
+\defgroup svg svg: Stream SVG (Scalable Vector Graphics)
\defgroup sym_difference sym_difference: sym_difference of two geometries
\defgroup touches touches: detect if a geometry self-touches or if two geometries touch
\defgroup traits traits: adapt geometries
Modified: branches/release/libs/geometry/doc/geometry.qbk
==============================================================================
--- branches/release/libs/geometry/doc/geometry.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/geometry.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -109,8 +109,10 @@
* Akira Takahashi (adaption of Boost.Fusion)
* Alfredo Correa (adaption of Boost.Array)
+* Andrew Hundt (varray container, aka. static_vector)
* Federico Fern\u00E1ndez (preliminary version of R-tree spatial index)
* Karsten Ahnert (patch for cross-track distance)
+* Mats Taraldsvik (documentation: adapting a legacy model)
[include imports.qbk]
Copied: branches/release/libs/geometry/doc/html/img/index/rtree/build_non_ovl.png (from r84886, trunk/libs/geometry/doc/html/img/index/rtree/build_non_ovl.png)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: branches/release/libs/geometry/doc/html/img/index/rtree/build_ovl.png (from r84886, trunk/libs/geometry/doc/html/img/index/rtree/build_ovl.png)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: branches/release/libs/geometry/doc/html/img/index/rtree/bulk.png (from r84886, trunk/libs/geometry/doc/html/img/index/rtree/bulk.png)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: branches/release/libs/geometry/doc/html/img/index/rtree/query_non_ovl.png (from r84886, trunk/libs/geometry/doc/html/img/index/rtree/query_non_ovl.png)
==============================================================================
Binary file (source and/or target). No diff available.
Copied: branches/release/libs/geometry/doc/html/img/index/rtree/query_ovl.png (from r84886, trunk/libs/geometry/doc/html/img/index/rtree/query_ovl.png)
==============================================================================
Binary file (source and/or target). No diff available.
Modified: branches/release/libs/geometry/doc/html/index.html
==============================================================================
--- branches/release/libs/geometry/doc/html/index.html Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/html/index.html 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Chapter 1. Geometry</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
-<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
+<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="index.html" title="Chapter 1. Geometry">
<link rel="next" href="geometry/introduction.html" title="Introduction">
</head>
@@ -70,6 +70,7 @@
<dt><span class="section">Core Metafunctions</span></dt>
<dt><span class="section">Enumerations</span></dt>
<dt><span class="section">Exceptions</span></dt>
+<dt><span class="section">IO (input/output)</span></dt>
<dt><span class="section">Iterators</span></dt>
<dt><span class="section">Models</span></dt>
<dt><span class="section">Spatial Indexes</span></dt>
@@ -81,6 +82,13 @@
<dt><span class="section">Reference Matrix</span></dt>
<dt><span class="section">Alphabetical Index</span></dt>
</dl></dd>
+<dt><span class="section">Examples</span></dt>
+<dd><dl>
+<dt><span class="section"><a href="geometry/examples/example__adapting_a_legacy_geometry_object_model.html">Example:
+ Adapting a legacy geometry object model</a></span></dt>
+<dt><span class="section"><a href="geometry/examples/example_source_code__adapting_a_legacy_geometry_object_model.html">Example
+ source code: Adapting a legacy geometry object model</a></span></dt>
+</dl></dd>
<dt><span class="section">Release Notes</span></dt>
<dt><span class="section">About this Documentation</span></dt>
<dt><span class="section">Acknowledgments</span></dt>
@@ -88,12 +96,12 @@
</div>
<h3>
<a name="geometry.h0"></a>
- <span class="phrase"><a name="geometry.contributions"></a></span><a class="link" href="index.html#geometry.contributions">Contributions</a>
+ <span><a name="geometry.contributions"></a></span><a class="link" href="index.html#geometry.contributions">Contributions</a>
</h3>
<p>
Boost.Geometry contains contributions by:
</p>
-<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
Akira Takahashi (adaption of Boost.Fusion)
</li>
@@ -101,15 +109,21 @@
Alfredo Correa (adaption of Boost.Array)
</li>
<li class="listitem">
+ Andrew Hundt (varray container, aka. static_vector)
+ </li>
+<li class="listitem">
Federico Fernández (preliminary version of R-tree spatial index)
</li>
<li class="listitem">
Karsten Ahnert (patch for cross-track distance)
</li>
+<li class="listitem">
+ Mats Taraldsvik (documentation: adapting a legacy model)
+ </li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
-<td align="left"><p><small>Last revised: May 16, 2013 at 10:14:50 GMT</small></p></td>
+<td align="left"><p><small>Last revised: June 23, 2013 at 18:26:39 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
Modified: branches/release/libs/geometry/doc/index/introduction.qbk
==============================================================================
--- branches/release/libs/geometry/doc/index/introduction.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/index/introduction.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -23,10 +23,10 @@
Antonin Guttman in 1984 [footnote Guttman, A. (1984). /R-Trees: A Dynamic Index Structure for Spatial Searching/]
as an expansion of B-tree for multi-dimensional data. It may be used to store points or volumetric data in order to
perform a spatial query. This query may for example return objects that are inside some area or are close to some point in space
-[footnote Cheung, K.; Fu, A. (1998). /Enhanced Nearest Neighbour Search on the R-tree/]. It's possible to insert new objects or
-to remove the ones already stored.
+[footnote Cheung, K.; Fu, A. (1998). /Enhanced Nearest Neighbour Search on the R-tree/].
+It's possible to insert new objects or to remove the ones already stored.
-The __rtree__ structure is presented on the image below. Each __rtree__'s node store a box descring the space occupied by
+The __rtree__ structure is presented on the image below. Each __rtree__'s node store a box describing the space occupied by
its children nodes. At the bottom of the structure, there are leaf-nodes which contains values
(geometric objects representations).
@@ -36,18 +36,36 @@
[footnote Greene, D. (1989). /An implementation and performance analysis of spatial data access methods/]
[footnote Beckmann, N.; Kriegel, H. P.; Schneider, R.; Seeger, B. (1990). /The R*-tree: an efficient and robust access method for points and rectangles/].
Each algorithm produces different splits so the internal structure of a tree may be different for each one of them.
-In general more complex algorithms analyses elements better and produces less overlapping nodes. In the searching process less nodes must be traversed
-in order to find desired obejcts. On the other hand more complex analysis takes more time. In general faster inserting will result in slower searching
+In general, more complex algorithms analyses elements better and produces less overlapping nodes. In the searching process less nodes must be traversed
+in order to find desired objects. On the other hand more complex analysis takes more time. In general faster inserting will result in slower searching
and vice versa. The performance of the R-tree depends on balancing algorithm, parameters and data inserted into the container.
-Example structures of trees created by use of three different algorithms and operations time are presented below. Data used in benchmark was random,
-non-overlapping boxes.
+
+Additionally there are also algorithms creating R-tree containing some, number of objects. This technique is called bulk loading and is
+done by use of packing algorithm
+[footnote Leutenegger, Scott T.; Edgington, Jeffrey M.; Lopez, Mario A. (1997). /STR: A Simple and Efficient Algorithm for R-Tree Packing/]
+[footnote Garcia, Yvan J.; Lopez, Mario A.; Leutenegger, Scott T. (1997). /A Greedy Algorithm for Bulk Loading R-trees/].
+This method is faster and results in R-trees with better internal structure. This means that the query performance is increased.
+
+The examples of structures of trees created by use of different algorithms and exemplary operations times are presented below.
[table
-[[] [linear algorithm] [quadratic algorithm] [R*-tree]]
-[[*Example structure*] [[$img/index/rtree/linear.png]] [[$img/index/rtree/quadratic.png]] [[$img/index/rtree/rstar.png]]]
-[[*1M Values inserts*] [1.65s] [2.51s] [4.96s]]
-[[*100k spatial queries*] [0.87s] [0.25s] [0.09s]]
-[[*100k knn queries*] [3.25s] [1.41s] [0.51s]]
+[[] [Linear algorithm] [Quadratic algorithm] [R*-tree] [Packing algorithm (trunk)]]
+[[*Example structure*] [[$img/index/rtree/linear.png]] [[$img/index/rtree/quadratic.png]] [[$img/index/rtree/rstar.png]] [[$img/index/rtree/bulk.png]]]
+[[*1M Values inserts*] [1.76s] [2.47s] [6.19s] [1.67s]]
+[[*100k spatial queries*] [2.21s] [0.51s] [0.12s] [0.07s]]
+[[*100k knn queries*] [6.37s] [2.09s] [0.64s] [0.52]]
+]
+
+The performance of the R-tree for different values of Max parameter and Min=0.5*Max is presented in the table below.
+The configuration of the machine used for testing is: /Intel(R) Core(TM) i7 870 @ 2.93GHz, 8GB RAM, MS Windows 7 x64/.
+In the two upper figures you can see the performance of the __rtree__ storing random, relatively small, non-overlapping, 2d boxes.
+In the lower ones, the performance of the __rtree__ also storing random, 2d boxes, but this time quite big and possibly overlapping.
+As you can see, the __rtree__ performance is different in both cases.
+
+[table
+[[] [building] [querying]]
+[[*non overlapping*] [[$img/index/rtree/build_non_ovl.png]] [[$img/index/rtree/query_non_ovl.png]]]
+[[*overlapping*] [[$img/index/rtree/build_ovl.png]] [[$img/index/rtree/query_ovl.png]]]
]
[heading Implementation details]
@@ -55,11 +73,30 @@
Key features of this implementation of the __rtree__ are:
* capable to store arbitrary __value__ type,
-* three different creation algorithms - linear, quadratic or rstar,
-* parameters (including maximal and minimal number of elements) may be passed as compile- or run-time parameters,
-* advanced queries - e.g. search for 5 nearest values to some point and intersecting some region but not within the other one,
+* three different balancing algorithms - linear, quadratic or rstar,
+* parameters (including maximal and minimal number of elements) may be passed as compile- or run-time parameters, in compile-time
+ version nodes elements are stored in static-size containers,
+* advanced queries - e.g. search for 5 nearest Values to some point and intersecting some Geometry but not within the other one,
* C++11 conformant: move semantics, stateful allocators,
-* capable to store __value__ type with no default constructor.
+* capable to store __value__ type with no default constructor,
+* in-memory storage (shared memory by use of Boost.Interprocess allocator).
+
+[heading Planned and experimental features]
+
+Below you can find features that will (or probably will) be added in the future releases:
+
+* rstar optimization (planned for release in Boost 1.55),
+* bulk loading (planned for release in Boost 1.55),
+* iterative queries - query iterators / type-erased query iterators (experimental),
+* path/ray query predicate - search for Values along Segment or LineString, closest to the starting point (experimental),
+* persistent storage.
+[/
+* 'reversed' spatial predicates or additional spatial predicates like contains(),
+* other geometries as Values, e.g. NSpheres. Rings would probably require using move semantics instead of copying
+* bounding tree - rtree variation capable to use other Geometries as bounds, e.g. NSpheres, Rings/convex polygons/ (moving required), Capsules, Elipses, Variants etc.
+* moving instead of copying + optimizations for movable/nonthrowing/trivialy copied elements
+* passing more than one nearest/path predicate - "returned value is one of k1 nearest values to p1 and ... and one of kN nearest values to pN"
+/]
[heading Dependencies]
Modified: branches/release/libs/geometry/doc/index/rtree/creation.qbk
==============================================================================
--- branches/release/libs/geometry/doc/index/rtree/creation.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/index/rtree/creation.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -51,7 +51,7 @@
The predefined `index::indexable<Value>` returns const reference to the `__indexable__` stored in the `__value__`.
-[important The translation is done quite frequently inside the continer - each time the rtree needs it. ]
+[important The translation is done quite frequently inside the container - each time the rtree needs it. ]
The predefined `index::equal_to<Value>`:
Modified: branches/release/libs/geometry/doc/index/rtree/experimental.qbk
==============================================================================
--- branches/release/libs/geometry/doc/index/rtree/experimental.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/index/rtree/experimental.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -22,13 +22,13 @@
It is possible to define how distance to the non-point `__value__` should be calculated. To do this one may pass
a relation object instead of a Point to the nearest predicate, as follows:
- /* caluclate distance to the Indexables' nearest points */
+ /* calculate distance to the Indexables' nearest points */
rtree.query(index::nearest(index::to_nearest(pt), k), std::back_inserter(returned_values)); // same as default
- /* caluclate distance to the Indexables' centroid */
+ /* calculate distance to the Indexables' centroid */
rtree.query(index::nearest(index::to_centroid(pt), k), std::back_inserter(returned_values));
- /* caluclate distance to the Indexables' furthest points */
+ /* calculate distance to the Indexables' furthest points */
rtree.query(index::nearest(index::to_furthest(pt), k), std::back_inserter(returned_values));
[heading Path query]
@@ -68,14 +68,14 @@
const_query_iterator last = rtree.qend(index::nearest(pt, 5));
// ...
for ( ; first != last ; ++first )
- *first; // do domething with Value
+ *first; // do something with Value
/* C++11 */
auto first = rtree.qbegin(index::nearest(pt, 5));
auto last = rtree.qend(index::nearest(pt, 5));
// ...
for ( ; first != last ; ++first )
- *first; // do domething with Value
+ *first; // do something with Value
`qend()` method is overloaded to return a different, lighter type of iterator which may be compared
with query iterator to check if the querying was finished. But since it has different type than the one returned by
@@ -99,13 +99,13 @@
end_iterator last = rtree.qend();
// ...
for ( ; first != last ; ++first )
- *first; // do domething with Value
+ *first; // do something with Value
/* C++11 */
auto first = rtree.qbegin(index::nearest(pt, 5));
auto last = rtree.qend();
// ...
for ( ; first != last ; ++first )
- *first; // do domething with Value
+ *first; // do something with Value
[endsect] [/ Experimental features /]
Modified: branches/release/libs/geometry/doc/index/rtree/introduction.qbk
==============================================================================
--- branches/release/libs/geometry/doc/index/rtree/introduction.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/index/rtree/introduction.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -16,7 +16,7 @@
perform a spatial query later. This query may return objects that are inside some area or are close to some point in space
[footnote Cheung, K.; Fu, A. (1998). /Enhanced Nearest Neighbour Search on the R-tree/].
-The __rtree__ structure is presented on the image below. Each __rtree__'s node store a box descring the space occupied by
+The __rtree__ structure is presented on the image below. Each __rtree__'s node store a box describing the space occupied by
its children nodes. At the bottom of the structure, there are leaf-nodes which contains values
(geometric objects representations).
@@ -27,7 +27,7 @@
[footnote Beckmann, N.; Kriegel, H. P.; Schneider, R.; Seeger, B. (1990). /The R*-tree: an efficient and robust access method for points and rectangles/].
Each algorithm produces different splits so the internal structure of a tree may be different for each one of them.
In general more complex algorithms analyses elements better and produces less overlapping nodes. In the searching process less nodes must be traversed
-in order to find desired obejcts. On the other hand more complex analysis takes more time. In general faster inserting will result in slower searching
+in order to find desired objects. On the other hand more complex analysis takes more time. In general faster inserting will result in slower searching
and vice versa. The performance of the R-tree depends on balancing algorithm, parameters and data inserted into the container.
Example structures of trees created by use of three different algorithms and operations time are presented below. Data used in benchmark was random,
non-overlapping boxes.
Modified: branches/release/libs/geometry/doc/index/rtree/query.qbk
==============================================================================
--- branches/release/libs/geometry/doc/index/rtree/query.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/index/rtree/query.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -162,7 +162,7 @@
These predicates are connected by logical AND. Passing all predicates together not only makes possible
to construct advanced queries but is also faster than separate calls because the tree is traversed only once.
Traversing is continued and `Value`s are returned only if all predicates are met. Predicates are checked
-left-to-right so placing most restictive predicates first should accelerate the search.
+left-to-right so placing most restrictive predicates first should accelerate the search.
rt.query(index::intersects(box1) && !index::within(box2),
std::back_inserter(result));
Modified: branches/release/libs/geometry/doc/index/rtree/quickstart.qbk
==============================================================================
--- branches/release/libs/geometry/doc/index/rtree/quickstart.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/index/rtree/quickstart.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -18,7 +18,7 @@
[rtree_quickstart_include]
Typically you'll store e.g. `std::pair<Box, MyGeometryId>` in the __rtree__. `MyGeometryId`
-will be some indentifier of a complex `Geometry` stored in other container, e.g. index type
+will be some identifier of a complex `Geometry` stored in other container, e.g. index type
of a `Polygon` stored in the vector or an iterator of list of `Ring`s. To keep it simple to
define `Value` we will use predefined __box__ and unsigned int.
Modified: branches/release/libs/geometry/doc/release_notes.qbk
==============================================================================
--- branches/release/libs/geometry/doc/release_notes.qbk Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/release_notes.qbk 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -25,6 +25,7 @@
[*Documentation]
* small fixes of missing words
+* fixes in doc of template parameters (convex_hull, exterior_ring, return_buffer)
[*Bugfixes]
Modified: branches/release/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp
==============================================================================
--- branches/release/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -59,7 +59,9 @@
-void quickbook_template_parameter_list(std::vector<parameter> const& parameters, std::ostream& out)
+void quickbook_template_parameter_list(std::vector<parameter> const& parameters,
+ std::string const& related_name,
+ std::ostream& out)
{
if (!parameters.empty())
{
@@ -67,6 +69,10 @@
bool first = true;
BOOST_FOREACH(parameter const& p, parameters)
{
+ if (p.fulltype.empty())
+ {
+ std::cerr << "Warning: template parameter " << p.name << " has no type in " << related_name << std::endl;
+ }
out << (first ? "" : ", ") << p.fulltype;
first = false;
}
@@ -78,7 +84,7 @@
void quickbook_synopsis(function const& f, std::ostream& out)
{
out << "``";
- quickbook_template_parameter_list(f.template_parameters, out);
+ quickbook_template_parameter_list(f.template_parameters, f.name, out);
switch(f.type)
{
@@ -516,7 +522,7 @@
quickbook_markup(cos.qbk_markup, markup_before, markup_synopsis, out);
out << "[heading Synopsis]" << std::endl
<< "``";
- quickbook_template_parameter_list(cos.template_parameters, out);
+ quickbook_template_parameter_list(cos.template_parameters, cos.name, out);
out << (cos.is_class ? "class" : "struct")
<< " " << short_name << std::endl;
Copied: branches/release/libs/geometry/index/example/Jamfile.v2 (from r84886, trunk/libs/geometry/index/example/Jamfile.v2)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/libs/geometry/index/example/Jamfile.v2 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/libs/geometry/index/example/Jamfile.v2)
@@ -0,0 +1,54 @@
+# Boost.Geometry (aka GGL, Generic Geometry Library)
+#
+# Copyright (c) 2013 Mateusz Loskot, London, UK.
+#
+# Use, modification and distribution is subject to the Boost Software License,
+# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+# Usage:
+# Build as optimised for proper benchmarking:
+# b2 variant=release threading=multi
+# b2 variant=release threading=multi link=static runtime-link=static
+#
+# Set GLUT_ROOT to installation prefix of GLUT or, for Windows,
+# it may be all-in-one directory with GLUT header and binaries.
+
+import os ;
+
+project boost-geometry-index-example
+ : requirements
+ <source>/boost//headers
+ ;
+
+local GLUT_ROOT = [ os.environ GLUT_ROOT ] ;
+if $(GLUT_ROOT)
+{
+ local glut_name = glut ;
+ if [ os.name ] = NT
+ {
+ glut_name = glut32 ;
+ }
+
+ lib glut
+ :
+ :
+ <name>$(glut_name)
+ <search>$(GLUT_ROOT)
+ <search>$(GLUT_ROOT)/lib
+ :
+ :
+ <include>$(GLUT_ROOT)
+ <include>$(GLUT_ROOT)/include
+ ;
+}
+
+exe random_test : random_test.cpp ;
+link benchmark.cpp /boost//chrono : <threading>multi ;
+link benchmark2.cpp /boost//chrono : <threading>multi ;
+link benchmark3.cpp /boost//chrono : <threading>multi ;
+link benchmark_experimental.cpp /boost//chrono : <threading>multi ;
+if $(GLUT_ROOT)
+{
+ link glut_vis.cpp glut ;
+}
Modified: branches/release/libs/geometry/index/example/benchmark2.cpp
==============================================================================
--- branches/release/libs/geometry/index/example/benchmark2.cpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/example/benchmark2.cpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -1,5 +1,6 @@
// Boost.Geometry Index
-// Additional tests
+// Compare performance with std::set using 1-dimensional object
+// (i.e. angle, or number line coordiante)
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
Modified: branches/release/libs/geometry/index/example/benchmark_experimental.cpp
==============================================================================
--- branches/release/libs/geometry/index/example/benchmark_experimental.cpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/example/benchmark_experimental.cpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -27,6 +27,33 @@
typedef bg::model::box<P> B;
typedef bg::model::linestring<P> LS;
typedef bg::model::segment<P> S;
+typedef B V;
+//typedef P V;
+
+template <typename V>
+struct generate_value {};
+
+template <>
+struct generate_value<B>
+{
+ static inline B apply(float x, float y) { return B(P(x - 0.5f, y - 0.5f), P(x + 0.5f, y + 0.5f)); }
+};
+
+template <>
+struct generate_value<P>
+{
+ static inline P apply(float x, float y) { return P(x, y); }
+};
+
+//#include <boost/geometry/extensions/nsphere/nsphere.hpp>
+//typedef bg::model::nsphere<P, double> NS;
+//typedef NS V;
+//
+//template <>
+//struct generate_value<NS>
+//{
+// static inline NS apply(float x, float y) { return NS(P(x, y), 0.5); }
+//};
template <typename I1, typename I2, typename O>
void mycopy(I1 first, I2 last, O o)
@@ -35,11 +62,14 @@
*o = *first;
}
+//#define BOOST_GEOMETRY_INDEX_BENCHMARK_DEBUG
+
int main()
{
typedef boost::chrono::thread_clock clock_t;
typedef boost::chrono::duration<float> dur_t;
+#ifndef BOOST_GEOMETRY_INDEX_BENCHMARK_DEBUG
size_t values_count = 1000000;
size_t queries_count = 100000;
size_t nearest_queries_count = 10000;
@@ -47,9 +77,19 @@
size_t path_queries_count = 2000;
size_t path_queries_count2 = 10000;
unsigned path_values_count = 10;
+#else
+ size_t values_count = 1000;
+ size_t queries_count = 1;
+ size_t nearest_queries_count = 1;
+ unsigned neighbours_count = 10;
+ size_t path_queries_count = 1;
+ size_t path_queries_count2 = 1;
+ unsigned path_values_count = 10;
+#endif
float max_val = static_cast<float>(values_count / 2);
std::vector< std::pair<float, float> > coords;
+ std::vector<V> values;
//randomize values
{
@@ -63,39 +103,62 @@
std::cout << "randomizing data\n";
for ( size_t i = 0 ; i < values_count ; ++i )
{
- coords.push_back(std::make_pair(rnd(), rnd()));
+ float x = rnd();
+ float y = rnd();
+ coords.push_back(std::make_pair(x, y));
+ values.push_back(generate_value<V>::apply(x, y));
}
std::cout << "randomized\n";
}
- typedef bgi::rtree<B, bgi::linear<16, 4> > RT;
- //typedef bgi::rtree<B, bgi::quadratic<8, 3> > RT;
- //typedef bgi::rtree<B, bgi::rstar<8, 3> > RT;
+ typedef bgi::rtree<V, bgi::linear<16, 4> > RT;
+ //typedef bgi::rtree<V, bgi::quadratic<16, 4> > RT;
+ //typedef bgi::rtree<V, bgi::rstar<16, 4> > RT;
std::cout << "sizeof rtree: " << sizeof(RT) << std::endl;
for (;;)
{
- RT t;
+ std::vector<V> result;
+ result.reserve(100);
+ B result_one;
- // inserting test
+ // packing test
{
clock_t::time_point start = clock_t::now();
- for (size_t i = 0 ; i < values_count ; ++i )
- {
- float x = coords[i].first;
- float y = coords[i].second;
- B b(P(x - 0.5f, y - 0.5f), P(x + 0.5f, y + 0.5f));
- t.insert(b);
+ RT t(values.begin(), values.end());
+
+ dur_t time = clock_t::now() - start;
+ std::cout << time << " - pack " << values_count << '\n';
+
+ {
+ clock_t::time_point start = clock_t::now();
+ size_t temp = 0;
+ for (size_t i = 0 ; i < queries_count ; ++i )
+ {
+ float x = coords[i].first;
+ float y = coords[i].second;
+ result.clear();
+ t.query(bgi::intersects(B(P(x - 10, y - 10), P(x + 10, y + 10))), std::back_inserter(result));
+ temp += result.size();
+ }
+ dur_t time = clock_t::now() - start;
+ std::cout << time << " - query(B) " << queries_count << " found " << temp << '\n';
}
+ }
+
+ RT t;
+
+ // inserting test
+ {
+ clock_t::time_point start = clock_t::now();
+ t.insert(values);
dur_t time = clock_t::now() - start;
std::cout << time << " - insert " << values_count << '\n';
}
- std::vector<B> result;
- result.reserve(100);
- B result_one;
+
{
clock_t::time_point start = clock_t::now();
@@ -184,14 +247,14 @@
&&
!bgi::within(B(P(x2 - 10, y2 - 10), P(x2 + 10, y2 + 10)))
&&
- !bgi::overlaps(B(P(x3 - 10, y3 - 10), P(x3 + 10, y3 + 10)))
+ !bgi::covered_by(B(P(x3 - 10, y3 - 10), P(x3 + 10, y3 + 10)))
,
std::back_inserter(result)
);
temp += result.size();
}
dur_t time = clock_t::now() - start;
- std::cout << time << " - query(i && !w && !o) " << queries_count << " found " << temp << '\n';
+ std::cout << time << " - query(i && !w && !c) " << queries_count << " found " << temp << '\n';
}
result.clear();
@@ -330,9 +393,8 @@
{
float x = coords[i].first;
float y = coords[i].second;
- B b(P(x - 0.5f, y - 0.5f), P(x + 0.5f, y + 0.5f));
-
- t.remove(b);
+
+ t.remove(generate_value<V>::apply(x, y));
}
dur_t time = clock_t::now() - start;
std::cout << time << " - remove " << values_count / 10 << '\n';
Modified: branches/release/libs/geometry/index/example/glut_vis.cpp
==============================================================================
--- branches/release/libs/geometry/index/example/glut_vis.cpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/example/glut_vis.cpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -9,8 +9,6 @@
#include <GL/glut.h>
-#define BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE
-
#include <boost/foreach.hpp>
#include <boost/geometry/index/rtree.hpp>
@@ -20,10 +18,11 @@
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
-#include <boost/geometry/index/detail/rtree/visitors/gl_draw.hpp>
-#include <boost/geometry/index/detail/rtree/visitors/print.hpp>
-#include <boost/geometry/index/detail/rtree/visitors/are_boxes_ok.hpp>
-#include <boost/geometry/index/detail/rtree/visitors/are_levels_ok.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/gl_draw.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/print.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/statistics.hpp>
namespace bg = boost::geometry;
namespace bgi = bg::index;
@@ -36,10 +35,11 @@
typedef bg::model::polygon<P> Poly;
typedef bg::model::multi_polygon<Poly> MPoly;
-bgi::rtree<
+typedef bgi::rtree<
B,
bgi::rstar<4, 2>
-> t;
+> RTree;
+RTree t;
std::vector<B> vect;
size_t found_count = 0;
@@ -73,11 +73,11 @@
if ( found_count > 0 )
{
std::cout << "search point: ";
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, search_point);
+ bgi::detail::utilities::print_indexable(std::cout, search_point);
std::cout << "\nfound: ";
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, nearest_boxes[i]);
+ bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
std::cout << '\n';
}
}
@@ -110,11 +110,11 @@
{
std::cout << "search path: ";
BOOST_FOREACH(P const& p, search_path)
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, p);
+ bgi::detail::utilities::print_indexable(std::cout, p);
std::cout << "\nfound: ";
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, nearest_boxes[i]);
+ bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
std::cout << '\n';
}
}
@@ -146,11 +146,11 @@
if ( found_count > 0 )
{
std::cout << "search box: ";
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, search_box);
+ bgi::detail::utilities::print_indexable(std::cout, search_box);
std::cout << "\nfound: ";
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, nearest_boxes[i]);
+ bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
std::cout << '\n';
}
}
@@ -193,13 +193,13 @@
std::cout << "search ring: ";
BOOST_FOREACH(P const& p, search_ring)
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, p);
+ bgi::detail::utilities::print_indexable(std::cout, p);
std::cout << ' ';
}
std::cout << "\nfound: ";
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, nearest_boxes[i]);
+ bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
std::cout << '\n';
}
}
@@ -249,13 +249,13 @@
std::cout << "search poly outer: ";
BOOST_FOREACH(P const& p, search_poly.outer())
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, p);
+ bgi::detail::utilities::print_indexable(std::cout, p);
std::cout << ' ';
}
std::cout << "\nfound: ";
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, nearest_boxes[i]);
+ bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
std::cout << '\n';
}
}
@@ -321,13 +321,13 @@
std::cout << "search multi_poly[0] outer: ";
BOOST_FOREACH(P const& p, search_multi_poly[0].outer())
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, p);
+ bgi::detail::utilities::print_indexable(std::cout, p);
std::cout << ' ';
}
std::cout << "\nfound: ";
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
{
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, nearest_boxes[i]);
+ bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]);
std::cout << '\n';
}
}
@@ -337,36 +337,38 @@
void search()
{
+ namespace d = bgi::detail;
+
if ( query_mode == qm_knn )
query_knn();
else if ( query_mode == qm_c )
- query< bgi::detail::covered_by<B> >();
+ query< d::spatial_predicate<B, d::covered_by_tag, false> >();
else if ( query_mode == qm_d )
- query< bgi::detail::disjoint<B> >();
+ query< d::spatial_predicate<B, d::disjoint_tag, false> >();
else if ( query_mode == qm_i )
- query< bgi::detail::intersects<B> >();
+ query< d::spatial_predicate<B, d::intersects_tag, false> >();
else if ( query_mode == qm_o )
- query< bgi::detail::overlaps<B> >();
+ query< d::spatial_predicate<B, d::overlaps_tag, false> >();
else if ( query_mode == qm_w )
- query< bgi::detail::within<B> >();
+ query< d::spatial_predicate<B, d::within_tag, false> >();
else if ( query_mode == qm_nc )
- query< bgi::detail::not_covered_by<B> >();
+ query< d::spatial_predicate<B, d::covered_by_tag, true> >();
else if ( query_mode == qm_nd )
- query< bgi::detail::not_disjoint<B> >();
+ query< d::spatial_predicate<B, d::disjoint_tag, true> >();
else if ( query_mode == qm_ni )
- query< bgi::detail::not_intersects<B> >();
+ query< d::spatial_predicate<B, d::intersects_tag, true> >();
else if ( query_mode == qm_no )
- query< bgi::detail::not_overlaps<B> >();
+ query< d::spatial_predicate<B, d::overlaps_tag, true> >();
else if ( query_mode == qm_nw )
- query< bgi::detail::not_within<B> >();
+ query< d::spatial_predicate<B, d::within_tag, true> >();
else if ( query_mode == qm_all )
- query< bgi::detail::intersects<B> >();
+ query< d::spatial_predicate<B, d::intersects_tag, false> >();
else if ( query_mode == qm_ri )
- query_ring< bgi::detail::intersects<R> >();
+ query_ring< d::spatial_predicate<R, d::intersects_tag, false> >();
else if ( query_mode == qm_pi )
- query_poly< bgi::detail::intersects<Poly> >();
+ query_poly< d::spatial_predicate<Poly, d::intersects_tag, false> >();
else if ( query_mode == qm_mpi )
- query_multi_poly< bgi::detail::intersects<MPoly> >();
+ query_multi_poly< d::spatial_predicate<MPoly, d::intersects_tag, false> >();
else if ( query_mode == qm_path )
query_path();
@@ -377,7 +379,7 @@
{
float x = boost::geometry::get<0>(search_point);
float y = boost::geometry::get<1>(search_point);
- float z = t.depth();
+ float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
// search point
glBegin(GL_TRIANGLES);
@@ -409,7 +411,7 @@
{
float x = boost::geometry::get<0>(p);
float y = boost::geometry::get<1>(p);
- float z = t.depth();
+ float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
glVertex3f(x, y, z);
}
@@ -423,7 +425,7 @@
float y1 = boost::geometry::get<bg::min_corner, 1>(box);
float x2 = boost::geometry::get<bg::max_corner, 0>(box);
float y2 = boost::geometry::get<bg::max_corner, 1>(box);
- float z = t.depth();
+ float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
// search box
glBegin(GL_LINE_LOOP);
@@ -437,7 +439,7 @@
template <typename Range>
void draw_ring(Range const& range)
{
- float z = t.depth();
+ float z = bgi::detail::rtree::utilities::view<RTree>(t).depth();
// search box
glBegin(GL_LINE_LOOP);
@@ -471,7 +473,7 @@
{
glClear(GL_COLOR_BUFFER_BIT);
- boost::geometry::index::gl_draw(t);
+ bgi::detail::rtree::utilities::gl_draw(t);
if ( search_valid )
{
@@ -491,7 +493,9 @@
draw_box(search_box);
for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i )
- boost::geometry::index::detail::rtree::visitors::detail::gl_draw_indexable(nearest_boxes[i], t.depth());
+ bgi::detail::utilities::gl_draw_indexable(
+ nearest_boxes[i],
+ bgi::detail::rtree::utilities::view<RTree>(t).depth());
}
glFlush();
@@ -502,7 +506,7 @@
if ( h == 0 )
h = 1;
- float ratio = float(w) / h;
+ //float ratio = float(w) / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -528,7 +532,7 @@
srand(1);
}
-void mouse(int button, int state, int x, int y)
+void mouse(int button, int state, int /*x*/, int /*y*/)
{
if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
@@ -543,11 +547,11 @@
vect.push_back(b);
std::cout << "inserted: ";
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, b);
+ bgi::detail::utilities::print_indexable(std::cout, b);
std::cout << '\n';
- std::cout << ( bgi::detail::rtree::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
- std::cout << ( bgi::detail::rtree::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
std::cout << "\n";
search_valid = false;
@@ -564,11 +568,11 @@
vect.erase(vect.begin() + i);
std::cout << "removed: ";
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, b);
+ bgi::detail::utilities::print_indexable(std::cout, b);
std::cout << '\n';
- std::cout << ( bgi::detail::rtree::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
- std::cout << ( bgi::detail::rtree::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
std::cout << "\n";
search_valid = false;
@@ -583,13 +587,15 @@
std::string current_line;
-void keyboard(unsigned char key, int x, int y)
+void keyboard(unsigned char key, int /*x*/, int /*y*/)
{
if ( key == '\r' || key == '\n' )
{
if ( current_line == "t" )
{
- std::cout << "\n" << t << "\n";
+ std::cout << "\n";
+ bgi::detail::rtree::utilities::print(std::cout, t);
+ std::cout << "\n";
}
else if ( current_line == "rand" )
{
@@ -606,12 +612,42 @@
vect.push_back(b);
std::cout << "inserted: ";
- bgi::detail::rtree::visitors::detail::print_indexable(std::cout, b);
+ bgi::detail::utilities::print_indexable(std::cout, b);
std::cout << '\n';
}
- std::cout << ( bgi::detail::rtree::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
- std::cout << ( bgi::detail::rtree::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
+ std::cout << "\n";
+
+ search_valid = false;
+
+ glutPostRedisplay();
+ }
+ else if ( current_line == "bulk" )
+ {
+ vect.clear();
+
+ for ( size_t i = 0 ; i < 35 ; ++i )
+ {
+ float x = ( rand() % 100 );
+ float y = ( rand() % 100 );
+ float w = ( rand() % 2 ) + 1;
+ float h = ( rand() % 2 ) + 1;
+
+ B b(P(x - w, y - h),P(x + w, y + h));
+ vect.push_back(b);
+
+ std::cout << "inserted: ";
+ bgi::detail::utilities::print_indexable(std::cout, b);
+ std::cout << '\n';
+ }
+
+ RTree t2(vect);
+ t = boost::move(t2);
+
+ std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" );
+ std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" );
std::cout << "\n";
search_valid = false;
Modified: branches/release/libs/geometry/index/test/Jamfile.v2
==============================================================================
--- branches/release/libs/geometry/index/test/Jamfile.v2 Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/test/Jamfile.v2 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -17,8 +17,9 @@
<toolset>msvc:<asynch-exceptions>on
;
-test-suite boost-geometry-index
+test-suite boost-geometry-index-varray
:
+ [ run varray_old.cpp ]
[ run varray.cpp ]
;
Copied: branches/release/libs/geometry/index/test/movable.hpp (from r84886, trunk/libs/geometry/index/test/movable.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/libs/geometry/index/test/movable.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/libs/geometry/index/test/movable.hpp)
@@ -0,0 +1,92 @@
+// Boost.Geometry.Index varray
+// Unit Test
+
+// Copyright (c) 2009 Ion Gaztanaga
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_TEST_MOVABLE_HPP
+#define BOOST_GEOMETRY_INDEX_TEST_MOVABLE_HPP
+
+//[movable_definition
+//header file "movable.hpp"
+#include <boost/move/move.hpp>
+
+//A movable class
+class movable
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
+ int value_;
+
+public:
+ movable() : value_(1){}
+
+ //Move constructor and assignment
+ movable(BOOST_RV_REF(movable) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ movable & operator=(BOOST_RV_REF(movable) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ bool moved() const //Observer
+ { return value_ == 0; }
+};
+
+
+class copy_movable
+{
+ BOOST_COPYABLE_AND_MOVABLE(copy_movable)
+ size_t value_;
+
+public:
+ copy_movable(size_t value = 1) : value_(value){}
+
+ //Move constructor and assignment
+ copy_movable(BOOST_RV_REF(copy_movable) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ copy_movable(const copy_movable &m)
+ { value_ = m.value_; }
+
+ copy_movable & operator=(BOOST_RV_REF(copy_movable) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m)
+ { value_ = m.value_; return *this; }
+
+ bool moved() const //Observer
+ { return value_ == 0; }
+
+ bool operator==(const copy_movable& m) const
+ { return value_ == m.value_; }
+};
+
+struct copy_movable_wrapper
+{
+ copy_movable cm;
+};
+
+copy_movable produce()
+{ return copy_movable(); }
+
+namespace boost{
+
+template<>
+struct has_nothrow_move<movable>
+{
+ static const bool value = true;
+};
+
+template<>
+struct has_nothrow_move<copy_movable>
+{
+ static const bool value = true;
+};
+
+} //namespace boost{
+//]
+
+#endif //BOOST_GEOMETRY_INDEX_TEST_MOVABLE_HPP
Modified: branches/release/libs/geometry/index/test/rtree/exceptions/test_exceptions.hpp
==============================================================================
--- branches/release/libs/geometry/index/test/rtree/exceptions/test_exceptions.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/test/rtree/exceptions/test_exceptions.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -26,7 +26,7 @@
{
typedef std::pair<bg::model::point<float, 2, bg::cs::cartesian>, throwing_value> Value;
typedef bgi::rtree<Value, Parameters> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
throwing_value::reset_calls_counter();
throwing_value::set_max_calls((std::numeric_limits<size_t>::max)());
@@ -47,7 +47,15 @@
BOOST_CHECK_THROW( tree.insert(input.begin(), input.end()), throwing_value_copy_exception );
}
- for ( size_t i = 0 ; i < 20 ; i += 2 )
+ for ( size_t i = 0 ; i < 20 ; i += 1 )
+ {
+ throwing_value::reset_calls_counter();
+ throwing_value::set_max_calls(i);
+
+ BOOST_CHECK_THROW( Tree tree(input.begin(), input.end(), parameters), throwing_value_copy_exception );
+ }
+
+ for ( size_t i = 0 ; i < 10 ; i += 1 )
{
throwing_value::reset_calls_counter();
throwing_value::set_max_calls(10000);
@@ -100,7 +108,7 @@
{
typedef std::pair<bg::model::point<float, 2, bg::cs::cartesian>, throwing_value> Value;
typedef bgi::rtree<Value, Parameters> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
throwing_value::reset_calls_counter();
throwing_value::set_max_calls((std::numeric_limits<size_t>::max)());
@@ -121,6 +129,19 @@
BOOST_CHECK_THROW( tree.insert(input.begin(), input.end()), throwing_varray_exception );
}
+
+ for ( size_t i = 0 ; i < 100 ; i += 2 )
+ {
+ throwing_varray_settings::reset_calls_counter();
+ throwing_varray_settings::set_max_calls(i);
+
+ throwing_nodes_stats::reset_counters();
+
+ BOOST_CHECK_THROW( Tree tree(input.begin(), input.end(), parameters), throwing_varray_exception );
+
+ BOOST_CHECK_EQUAL(throwing_nodes_stats::internal_nodes_count(), 0u);
+ BOOST_CHECK_EQUAL(throwing_nodes_stats::leafs_count(), 0u);
+ }
for ( size_t i = 0 ; i < 50 ; i += 2 )
{
Modified: branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing.hpp
==============================================================================
--- branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -122,6 +122,12 @@
container::resize(s);
}
+ inline void reserve(size_type s)
+ {
+ throwing_varray_settings::throw_if_required();
+ container::reserve(s);
+ }
+
void push_back(Element const& v)
{
throwing_varray_settings::throw_if_required();
Modified: branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing_node.hpp
==============================================================================
--- branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing_node.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/test/rtree/exceptions/test_throwing_node.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -16,6 +16,16 @@
#include <rtree/exceptions/test_throwing.hpp>
+struct throwing_nodes_stats
+{
+ static void reset_counters() { get_internal_nodes_counter_ref() = 0; get_leafs_counter_ref() = 0; }
+ static size_t internal_nodes_count() { return get_internal_nodes_counter_ref(); }
+ static size_t leafs_count() { return get_leafs_counter_ref(); }
+
+ static size_t & get_internal_nodes_counter_ref() { static size_t cc = 0; return cc; }
+ static size_t & get_leafs_counter_ref() { static size_t cc = 0; return cc; }
+};
+
namespace boost { namespace geometry { namespace index {
template <size_t MaxElements, size_t MinElements>
@@ -79,12 +89,17 @@
> elements_type;
template <typename Dummy>
- inline dynamic_internal_node(Dummy const&) {}
+ inline dynamic_internal_node(Dummy const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; }
+ inline ~dynamic_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, true> & v) const { v(*this); }
elements_type elements;
+
+private:
+ dynamic_internal_node(dynamic_internal_node const&);
+ dynamic_internal_node & operator=(dynamic_internal_node const&);
};
template <typename Value, typename Parameters, typename Box, typename Allocators>
@@ -94,12 +109,17 @@
typedef throwing_varray<Value, Parameters::max_elements + 1> elements_type;
template <typename Dummy>
- inline dynamic_leaf(Dummy const&) {}
+ inline dynamic_leaf(Dummy const&) { throwing_nodes_stats::get_leafs_counter_ref()++; }
+ inline ~dynamic_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, false> & v) { v(*this); }
void apply_visitor(dynamic_visitor<Value, Parameters, Box, Allocators, node_throwing_d_mem_static_tag, true> & v) const { v(*this); }
elements_type elements;
+
+private:
+ dynamic_leaf(dynamic_leaf const&);
+ dynamic_leaf & operator=(dynamic_leaf const&);
};
// elements derived type
Modified: branches/release/libs/geometry/index/test/rtree/test_rtree.hpp
==============================================================================
--- branches/release/libs/geometry/index/test/rtree/test_rtree.hpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/test/rtree/test_rtree.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -16,14 +16,13 @@
#include <geometry_index_test_common.hpp>
-#define BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_DEBUG_INTERFACE
// TEST
//#define BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
//#define BOOST_GEOMETRY_INDEX_DETAIL_ENABLE_TYPE_ERASED_ITERATORS
#include <boost/geometry/index/rtree.hpp>
-#include <boost/geometry/index/detail/rtree/visitors/are_levels_ok.hpp>
-#include <boost/geometry/index/detail/rtree/visitors/are_boxes_ok.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
+#include <boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp>
//#include <boost/geometry/geometries/ring.hpp>
//#include <boost/geometry/geometries/polygon.hpp>
@@ -580,7 +579,7 @@
typedef typename Rtree::value_type V;
typedef typename Rtree::indexable_type I;
- return value_outside_impl<V, bgi::detail::traits::dimension<I>::value>::apply();
+ return value_outside_impl<V, bg::dimension<I>::value>::apply();
}
template<typename Rtree, typename Elements, typename Box>
@@ -589,7 +588,7 @@
typedef typename Rtree::indexable_type I;
generate::input<
- bgi::detail::traits::dimension<I>::value
+ bg::dimension<I>::value
>::apply(input, qbox);
tree.insert(input.begin(), input.end());
@@ -651,9 +650,9 @@
template <typename Rtree, typename Value, typename Predicates>
void spatial_query(Rtree & rtree, Predicates const& pred, std::vector<Value> const& expected_output)
{
- BOOST_CHECK( bgi::detail::rtree::are_levels_ok(rtree) );
+ BOOST_CHECK( bgi::detail::rtree::utilities::are_levels_ok(rtree) );
if ( !rtree.empty() )
- BOOST_CHECK( bgi::detail::rtree::are_boxes_ok(rtree) );
+ BOOST_CHECK( bgi::detail::rtree::utilities::are_boxes_ok(rtree) );
std::vector<Value> output;
size_t n = rtree.query(pred, std::back_inserter(output));
@@ -735,6 +734,51 @@
spatial_query(tree, bgi::disjoint(qpoly), expected_output);*/
}
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
+template <typename Tag>
+struct contains_impl
+{
+ template <typename Rtree, typename Value, typename Box>
+ static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
+ {
+ std::vector<Value> expected_output;
+
+ BOOST_FOREACH(Value const& v, input)
+ if ( bg::within(qbox, tree.indexable_get()(v)) )
+ expected_output.push_back(v);
+
+ spatial_query(tree, bgi::contains(qbox), expected_output);
+
+ /*typedef bg::traits::point_type<Box>::type P;
+ bg::model::ring<P> qring;
+ bg::convert(qbox, qring);
+ spatial_query(tree, bgi::contains(qring), expected_output);
+ bg::model::polygon<P> qpoly;
+ bg::convert(qbox, qpoly);
+ spatial_query(tree, bgi::contains(qpoly), expected_output);*/
+ }
+};
+
+template <>
+struct contains_impl<bg::point_tag>
+{
+ template <typename Rtree, typename Value, typename Box>
+ static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
+ {}
+};
+
+template <typename Rtree, typename Value, typename Box>
+void contains(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
+{
+ contains_impl<
+ typename bg::tag<
+ typename Rtree::indexable_type
+ >::type
+ >::apply(tree, input, qbox);
+}
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
template <typename Rtree, typename Value, typename Box>
void covered_by(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
@@ -756,6 +800,52 @@
spatial_query(tree, bgi::covered_by(qpoly), expected_output);*/
}
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
+template <typename Tag>
+struct covers_impl
+{
+ template <typename Rtree, typename Value, typename Box>
+ static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
+ {
+ std::vector<Value> expected_output;
+
+ BOOST_FOREACH(Value const& v, input)
+ if ( bg::covered_by(qbox, tree.indexable_get()(v)) )
+ expected_output.push_back(v);
+
+ spatial_query(tree, bgi::covers(qbox), expected_output);
+
+ /*typedef bg::traits::point_type<Box>::type P;
+ bg::model::ring<P> qring;
+ bg::convert(qbox, qring);
+ spatial_query(tree, bgi::covers(qring), expected_output);
+ bg::model::polygon<P> qpoly;
+ bg::convert(qbox, qpoly);
+ spatial_query(tree, bgi::covers(qpoly), expected_output);*/
+ }
+};
+
+template <>
+struct covers_impl<bg::point_tag>
+{
+ template <typename Rtree, typename Value, typename Box>
+ static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
+ {}
+};
+
+template <typename Rtree, typename Value, typename Box>
+void covers(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
+{
+ covers_impl<
+ typename bg::tag<
+ typename Rtree::indexable_type
+ >::type
+ >::apply(tree, input, qbox);
+}
+
+#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+
template <typename Tag>
struct overlaps_impl
{
@@ -792,7 +882,7 @@
void overlaps(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
{
overlaps_impl<
- typename bgi::detail::traits::tag<
+ typename bg::tag<
typename Rtree::indexable_type
>::type
>::apply(tree, input, qbox);
@@ -1113,7 +1203,7 @@
//TODO - test SWAP
- BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(params)
+ ::boost::ignore_unused_variable_warning(params);
}
template <typename I, typename O>
@@ -1154,14 +1244,14 @@
BOOST_CHECK(tree.size() == t.size());
std::vector<Value> output;
t.query(bgi::intersects(qbox), std::back_inserter(output));
- exactly_the_same_outputs(t, output, expected_output);
+ compare_outputs(t, output, expected_output);
}
{
Rtree t(input, tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
BOOST_CHECK(tree.size() == t.size());
std::vector<Value> output;
t.query(bgi::intersects(qbox), std::back_inserter(output));
- exactly_the_same_outputs(t, output, expected_output);
+ compare_outputs(t, output, expected_output);
}
{
Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
@@ -1330,8 +1420,12 @@
basictest::overlaps(tree, input, qbox);
//basictest::touches(tree, input, qbox);
basictest::within(tree, input, qbox);
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+ basictest::contains(tree, input, qbox);
+ basictest::covers(tree, input, qbox);
+#endif
- typedef typename bgi::detail::traits::point_type<Box>::type P;
+ typedef typename bg::point_type<Box>::type P;
P pt;
bg::centroid(qbox, pt);
@@ -1361,7 +1455,7 @@
typedef bgi::equal_to<Value> E;
typedef typename Allocator::template rebind<Value>::other A;
typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
Tree tree(parameters, I(), E(), allocator);
std::vector<Value> input;
@@ -1384,7 +1478,7 @@
typedef bgi::equal_to<Value> E;
typedef typename Allocator::template rebind<Value>::other A;
typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
Tree tree(parameters, I(), E(), allocator);
std::vector<Value> input;
@@ -1421,7 +1515,7 @@
typedef bgi::equal_to<Value> E;
typedef typename Allocator::template rebind<Value>::other A;
typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
Tree t(parameters, I(), E(), allocator);
std::vector<Value> input;
@@ -1464,7 +1558,7 @@
typedef bgi::equal_to<Value> E;
typedef typename Allocator::template rebind<Value>::other A;
typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
Tree t(parameters, I(), E(), allocator);
std::vector<Value> input;
@@ -1495,7 +1589,7 @@
typedef bgi::equal_to<Value> E;
typedef typename Allocator::template rebind<Value>::other A;
typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
- typedef typename Tree::box_type B;
+ typedef typename Tree::bounds_type B;
typedef typename bg::traits::point_type<B>::type P;
B b;
Modified: branches/release/libs/geometry/index/test/varray.cpp
==============================================================================
--- branches/release/libs/geometry/index/test/varray.cpp Sun Jun 23 16:47:03 2013 (r84888)
+++ branches/release/libs/geometry/index/test/varray.cpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889)
@@ -1,7 +1,8 @@
-// Boost.Geometry Index
+// Boost.Geometry.Index varray
// Unit Test
-// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2012-2013 Andrew Hundt.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,65 +11,36 @@
#include <boost/test/included/test_exec_monitor.hpp>
#include <boost/test/impl/execution_monitor.ipp>
-#include <boost/geometry/index/detail/varray.hpp>
+// TODO: Disable parts of the unit test that should not run when BOOST_NO_EXCEPTIONS
+// if exceptions are enabled there must be a user defined throw_exception function
+#ifdef BOOST_NO_EXCEPTIONS
+namespace boost {
+ void throw_exception(std::exception const & e){}; // user defined
+} // namespace boost
+#endif // BOOST_NO_EXCEPTIONS
+
+#include <vector>
+#include <list>
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#include <boost/container/vector.hpp>
+#include <boost/container/stable_vector.hpp>
+using namespace boost::container;
+#endif
-using namespace boost::geometry::index::detail;
+#include "varray_test.hpp"
-class value_ndc
-{
-public:
- explicit value_ndc(int a) : aa(a) {}
- ~value_ndc() {}
- bool operator==(value_ndc const& v) const { return aa == v.aa; }
-private:
- value_ndc(value_ndc const&) {}
- value_ndc & operator=(value_ndc const&) { return *this; }
- int aa;
-};
-
-class value_nd
-{
-public:
- explicit value_nd(int a) : aa(a) {}
- ~value_nd() {}
- bool operator==(value_nd const& v) const { return aa == v.aa; }
-private:
- int aa;
-};
-
-class value_nc
-{
-public:
- explicit value_nc(int a = 0) : aa(a) {}
- ~value_nc() {}
- bool operator==(value_nc const& v) const { return aa == v.aa; }
-private:
- value_nc(value_nc const&) {}
- value_nc & operator=(value_ndc const&) { return *this; }
- int aa;
-};
-
-class counting_value
-{
-public:
- explicit counting_value(int a = 0) : aa(a) { ++c(); }
- counting_value(counting_value const& v) : aa(v.aa) { ++c(); }
- counting_value & operator=(counting_value const& v) { aa = v.aa; return *this; }
- ~counting_value() { --c(); }
- bool operator==(counting_value const& v) const { return aa == v.aa; }
- static size_t count() { return c(); }
-private:
- static size_t & c() { static size_t co = 0; return co; }
- int aa;
-};
+using namespace boost::geometry::index::detail;
template <typename T, size_t N>
void test_ctor_ndc()
{
varray<T, N> s;
- BOOST_CHECK(s.size() == 0);
+ BOOST_CHECK_EQUAL(s.size(), 0u);
BOOST_CHECK(s.capacity() == N);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(0), std::out_of_range );
+#endif // BOOST_NO_EXCEPTIONS
}
template <typename T, size_t N>
@@ -77,11 +49,19 @@
varray<T, N> s(n);
BOOST_CHECK(s.size() == n);
BOOST_CHECK(s.capacity() == N);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(n), std::out_of_range );
- if ( !boost::has_trivial_constructor<T>::value )
+#endif // BOOST_NO_EXCEPTIONS
+ if ( 1 < n )
{
- for ( size_t i = 0 ; i < n ; ++i )
- BOOST_CHECK(T() == s[i]);
+ T val10(10);
+ s[0] = val10;
+ BOOST_CHECK(T(10) == s[0]);
+ BOOST_CHECK(T(10) == s.at(0));
+ T val20(20);
+ s.at(1) = val20;
+ BOOST_CHECK(T(20) == s[1]);
+ BOOST_CHECK(T(20) == s.at(1));
}
}
@@ -91,7 +71,9 @@
varray<T, N> s(n, v);
BOOST_CHECK(s.size() == n);
BOOST_CHECK(s.capacity() == N);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(n), std::out_of_range );
+#endif // BOOST_NO_EXCEPTIONS
if ( 1 < n )
{
BOOST_CHECK(v == s[0]);
@@ -115,12 +97,19 @@
s.resize(n);
BOOST_CHECK(s.size() == n);
BOOST_CHECK(s.capacity() == N);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(n), std::out_of_range );
-
- if ( !boost::has_trivial_constructor<T>::value )
+#endif // BOOST_NO_EXCEPTIONS
+ if ( 1 < n )
{
- for ( size_t i = 0 ; i < n ; ++i )
- BOOST_CHECK(T() == s[i]);
+ T val10(10);
+ s[0] = val10;
+ BOOST_CHECK(T(10) == s[0]);
+ BOOST_CHECK(T(10) == s.at(0));
+ T val20(20);
+ s.at(1) = val20;
+ BOOST_CHECK(T(20) == s[1]);
+ BOOST_CHECK(T(20) == s.at(1));
}
}
@@ -132,7 +121,9 @@
s.resize(n, v);
BOOST_CHECK(s.size() == n);
BOOST_CHECK(s.capacity() == N);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(n), std::out_of_range );
+#endif // BOOST_NO_EXCEPTIONS
if ( 1 < n )
{
BOOST_CHECK(v == s[0]);
@@ -154,17 +145,23 @@
varray<T, N> s;
BOOST_CHECK(s.size() == 0);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(0), std::out_of_range );
+#endif // BOOST_NO_EXCEPTIONS
for ( size_t i = 0 ; i < N ; ++i )
{
- s.push_back(T(i));
+ T t(i);
+ s.push_back(t);
BOOST_CHECK(s.size() == i + 1);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(i + 1), std::out_of_range );
+#endif // BOOST_NO_EXCEPTIONS
BOOST_CHECK(T(i) == s.at(i));
BOOST_CHECK(T(i) == s[i]);
BOOST_CHECK(T(i) == s.back());
BOOST_CHECK(T(0) == s.front());
+ BOOST_CHECK(T(i) == *(s.data() + i));
}
}
@@ -174,13 +171,18 @@
varray<T, N> s;
for ( size_t i = 0 ; i < N ; ++i )
- s.push_back(T(i));
+ {
+ T t(i);
+ s.push_back(t);
+ }
for ( size_t i = N ; i > 1 ; --i )
{
s.pop_back();
BOOST_CHECK(s.size() == i - 1);
+#ifndef BOOST_NO_EXCEPTIONS
BOOST_CHECK_THROW( s.at(i - 1), std::out_of_range );
+#endif // BOOST_NO_EXCEPTIONS
BOOST_CHECK(T(i - 2) == s.at(i - 2));
BOOST_CHECK(T(i - 2) == s[i - 2]);
BOOST_CHECK(T(i - 2) == s.back());
@@ -196,6 +198,23 @@
BOOST_CHECK(*first1 == *first2);
}
+template <typename T, size_t N, typename C>
+void test_copy_and_assign(C const& c)
+{
+ {
+ varray<T, N> s(c.begin(), c.end());
+ BOOST_CHECK(s.size() == c.size());
+ test_compare_ranges(s.begin(), s.end(), c.begin(), c.end());
+ }
+ {
+ varray<T, N> s;
+ BOOST_CHECK(0 == s.size());
+ s.assign(c.begin(), c.end());
+ BOOST_CHECK(s.size() == c.size());
+ test_compare_ranges(s.begin(), s.end(), c.begin(), c.end());
+ }
+}
+
template <typename T, size_t N>
void test_copy_and_assign_nd(T const& val)
{
@@ -205,9 +224,10 @@
for ( size_t i = 0 ; i < N ; ++i )
{
- s.push_back(T(i));
- v.push_back(T(i));
- l.push_back(T(i));
+ T t(i);
+ s.push_back(t);
+ v.push_back(t);
+ l.push_back(t);
}
// copy ctor
{
@@ -223,44 +243,12 @@
BOOST_CHECK(s.size() == s1.size());
test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
}
- // ctor(Iter, Iter)
- {
- varray<T, N> s1(s.begin(), s.end());
- BOOST_CHECK(s.size() == s1.size());
- test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
- }
- {
- varray<T, N> s1(v.begin(), v.end());
- BOOST_CHECK(v.size() == s1.size());
- test_compare_ranges(v.begin(), v.end(), s1.begin(), s1.end());
- }
- {
- varray<T, N> s1(l.begin(), l.end());
- BOOST_CHECK(l.size() == s1.size());
- test_compare_ranges(l.begin(), l.end(), s1.begin(), s1.end());
- }
- // assign(Iter, Iter)
- {
- varray<T, N> s1;
- BOOST_CHECK(0 == s1.size());
- s1.assign(s.begin(), s.end());
- BOOST_CHECK(s.size() == s1.size());
- test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
- }
- {
- varray<T, N> s1;
- BOOST_CHECK(0 == s1.size());
- s1.assign(v.begin(), v.end());
- BOOST_CHECK(v.size() == s1.size());
- test_compare_ranges(v.begin(), v.end(), s1.begin(), s1.end());
- }
- {
- varray<T, N> s1;
- BOOST_CHECK(0 == s1.size());
- s1.assign(l.begin(), l.end());
- BOOST_CHECK(l.size() == s1.size());
- test_compare_ranges(l.begin(), l.end(), s1.begin(), s1.end());
- }
+
+ // ctor(Iter, Iter) and assign(Iter, Iter)
+ test_copy_and_assign<T, N>(s);
+ test_copy_and_assign<T, N>(v);
+ test_copy_and_assign<T, N>(l);
+
// assign(N, V)
{
varray<T, N> s1(s);
@@ -269,6 +257,13 @@
s1.assign(N, val);
test_compare_ranges(a.begin(), a.end(), s1.begin(), s1.end());
}
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ stable_vector<T> bsv(s.begin(), s.end());
+ vector<T> bv(s.begin(), s.end());
+ test_copy_and_assign<T, N>(bsv);
+ test_copy_and_assign<T, N>(bv);
+#endif
}
template <typename T, size_t N>
@@ -296,7 +291,8 @@
void test_erase_nd()
{
varray<T, N> s;
-
+ typedef typename varray<T, N>::iterator It;
+
for ( size_t i = 0 ; i < N ; ++i )
s.push_back(T(i));
@@ -305,13 +301,14 @@
for ( size_t i = 0 ; i < N ; ++i )
{
varray<T, N> s1(s);
- s1.erase(s1.begin() + i);
+ It it = s1.erase(s1.begin() + i);
+ BOOST_CHECK(s1.begin() + i == it);
BOOST_CHECK(s1.size() == N - 1);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
for ( size_t j = i+1 ; j < N ; ++j )
BOOST_CHECK(s1[j-1] == T(j));
- }
+ }
}
// erase(first, last)
{
@@ -320,13 +317,40 @@
{
varray<T, N> s1(s);
size_t removed = i + n < N ? n : N - i;
- s1.erase(s1.begin() + i, s1.begin() + i + removed);
+ It it = s1.erase(s1.begin() + i, s1.begin() + i + removed);
+ BOOST_CHECK(s1.begin() + i == it);
BOOST_CHECK(s1.size() == N - removed);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
for ( size_t j = i+n ; j < N ; ++j )
BOOST_CHECK(s1[j-n] == T(j));
- }
+ }
+ }
+}
+
+template <typename T, size_t N, typename SV, typename C>
+void test_insert(SV const& s, C const& c)
+{
+ size_t h = N/2;
+ size_t n = size_t(h/1.5f);
+
+ for ( size_t i = 0 ; i <= h ; ++i )
+ {
+ varray<T, N> s1(s);
+
+ typename C::const_iterator it = c.begin();
+ std::advance(it, n);
+ typename varray<T, N>::iterator
+ it1 = s1.insert(s1.begin() + i, c.begin(), it);
+
+ BOOST_CHECK(s1.begin() + i == it1);
+ BOOST_CHECK(s1.size() == h+n);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = 0 ; j < n ; ++j )
+ BOOST_CHECK(s1[j+i] == T(100 + j));
+ for ( size_t j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(s1[j+i+n] == T(j+i));
}
}
@@ -339,6 +363,8 @@
std::vector<T> v;
std::list<T> l;
+ typedef typename varray<T, N>::iterator It;
+
for ( size_t i = 0 ; i < h ; ++i )
{
s.push_back(T(i));
@@ -352,14 +378,15 @@
for ( size_t i = 0 ; i <= h ; ++i )
{
varray<T, N> s1(s);
- s1.insert(s1.begin() + i, val);
+ It it = s1.insert(s1.begin() + i, val);
+ BOOST_CHECK(s1.begin() + i == it);
BOOST_CHECK(s1.size() == h+1);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
BOOST_CHECK(s1[i] == val);
for ( size_t j = 0 ; j < h-i ; ++j )
BOOST_CHECK(s1[j+i+1] == T(j+i));
- }
+ }
}
// insert(pos, n, val)
{
@@ -367,7 +394,8 @@
for ( size_t i = 0 ; i <= h ; ++i )
{
varray<T, N> s1(s);
- s1.insert(s1.begin() + i, n, val);
+ It it = s1.insert(s1.begin() + i, n, val);
+ BOOST_CHECK(s1.begin() + i == it);
BOOST_CHECK(s1.size() == h+n);
for ( size_t j = 0 ; j < i ; ++j )
BOOST_CHECK(s1[j] == T(j));
@@ -375,116 +403,372 @@
BOOST_CHECK(s1[j+i] == val);
for ( size_t j = 0 ; j < h-i ; ++j )
BOOST_CHECK(s1[j+i+n] == T(j+i));
- }
+ }
}
// insert(pos, first, last)
- {
- size_t n = size_t(h/1.5f);
- for ( size_t i = 0 ; i <= h ; ++i )
+ test_insert<T, N>(s, ss);
+ test_insert<T, N>(s, v);
+ test_insert<T, N>(s, l);
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ stable_vector<T> bsv(ss.begin(), ss.end());
+ vector<T> bv(ss.begin(), ss.end());
+ test_insert<T, N>(s, bv);
+ test_insert<T, N>(s, bsv);
+#endif
+}
+
+template <typename T>
+void test_capacity_0_nd()
+{
+ varray<T, 10> v(5u, T(0));
+
+ //varray<T, 0, bad_alloc_strategy<T> > s;
+ varray<T, 0> s;
+ BOOST_CHECK(s.size() == 0);
+ BOOST_CHECK(s.capacity() == 0);
+#ifndef BOOST_NO_EXCEPTIONS
+ BOOST_CHECK_THROW(s.at(0), std::out_of_range);
+ //BOOST_CHECK_THROW(s.resize(5u, T(0)), std::bad_alloc);
+ //BOOST_CHECK_THROW(s.push_back(T(0)), std::bad_alloc);
+ //BOOST_CHECK_THROW(s.insert(s.end(), T(0)), std::bad_alloc);
+ //BOOST_CHECK_THROW(s.insert(s.end(), 5u, T(0)), std::bad_alloc);
+ //BOOST_CHECK_THROW(s.insert(s.end(), v.begin(), v.end()), std::bad_alloc);
+ //BOOST_CHECK_THROW(s.assign(v.begin(), v.end()), std::bad_alloc);
+ //BOOST_CHECK_THROW(s.assign(5u, T(0)), std::bad_alloc);
+ //try{
+ // varray<T, 0, bad_alloc_strategy<T> > s2(v.begin(), v.end());
+ // BOOST_CHECK(false);
+ //}catch(std::bad_alloc &){}
+ //try{
+ // varray<T, 0, bad_alloc_strategy<T> > s1(5u, T(0));
+ // BOOST_CHECK(false);
+ //}catch(std::bad_alloc &){}
+#endif // BOOST_NO_EXCEPTIONS
+}
+
+template <typename T, size_t N>
+void test_exceptions_nd()
+{
+ varray<T, N> v(N, T(0));
+ //varray<T, N/2, bad_alloc_strategy<T> > s(N/2, T(0));
+ varray<T, N/2> s(N/2, T(0));
+
+#ifndef BOOST_NO_EXCEPTIONS
+ /*BOOST_CHECK_THROW(s.resize(N, T(0)), std::bad_alloc);
+ BOOST_CHECK_THROW(s.push_back(T(0)), std::bad_alloc);
+ BOOST_CHECK_THROW(s.insert(s.end(), T(0)), std::bad_alloc);
+ BOOST_CHECK_THROW(s.insert(s.end(), N, T(0)), std::bad_alloc);
+ BOOST_CHECK_THROW(s.insert(s.end(), v.begin(), v.end()), std::bad_alloc);
+ BOOST_CHECK_THROW(s.assign(v.begin(), v.end()), std::bad_alloc);
+ BOOST_CHECK_THROW(s.assign(N, T(0)), std::bad_alloc);
+ try{
+ container_detail::varray<T, N/2, bad_alloc_strategy<T> > s2(v.begin(), v.end());
+ BOOST_CHECK(false);
+ }catch(std::bad_alloc &){}
+ try{
+ container_detail::varray<T, N/2, bad_alloc_strategy<T> > s1(N, T(0));
+ BOOST_CHECK(false);
+ }catch(std::bad_alloc &){}*/
+#endif // BOOST_NO_EXCEPTIONS
+}
+
+template <typename T, size_t N>
+void test_swap_and_move_nd()
+{
+ {
+ varray<T, N> v1, v2, v3, v4;
+ varray<T, N> s1, s2;
+ //varray<T, N, bad_alloc_strategy<T> > s4;
+ varray<T, N> s4;
+
+ for (size_t i = 0 ; i < N ; ++i )
{
- varray<T, N> s1(s);
- s1.insert(s1.begin() + i, ss.begin(), ss.begin() + n);
- BOOST_CHECK(s1.size() == h+n);
- for ( size_t j = 0 ; j < i ; ++j )
- BOOST_CHECK(s1[j] == T(j));
- for ( size_t j = 0 ; j < n ; ++j )
- BOOST_CHECK(s1[j+i] == T(100 + j));
- for ( size_t j = 0 ; j < h-i ; ++j )
- BOOST_CHECK(s1[j+i+n] == T(j+i));
- }
+ v1.push_back(T(i));
+ v2.push_back(T(i));
+ v3.push_back(T(i));
+ v4.push_back(T(i));
+ }
+ for (size_t i = 0 ; i < N/2 ; ++i )
+ {
+ s1.push_back(T(100 + i));
+ s2.push_back(T(100 + i));
+ s4.push_back(T(100 + i));
+ }
+
+ s1.swap(v1);
+ s2 = boost::move(v2);
+ varray<T, N> s3(boost::move(v3));
+ s4.swap(v4);
+
+ BOOST_CHECK(v1.size() == N/2);
+ BOOST_CHECK(s1.size() == N);
+ BOOST_CHECK(v2.size() == N); // objects aren't destroyed
+ BOOST_CHECK(s2.size() == N);
+ BOOST_CHECK(v3.size() == N); // objects aren't destroyed
+ BOOST_CHECK(s3.size() == N);
+ BOOST_CHECK(v4.size() == N/2);
+ BOOST_CHECK(s4.size() == N);
+ for (size_t i = 0 ; i < N/2 ; ++i )
+ {
+ BOOST_CHECK(v1[i] == T(100 + i));
+ BOOST_CHECK(v4[i] == T(100 + i));
+ }
+ for (size_t i = 0 ; i < N ; ++i )
+ {
+ BOOST_CHECK(s1[i] == T(i));
+ BOOST_CHECK(s2[i] == T(i));
+ BOOST_CHECK(s3[i] == T(i));
+ BOOST_CHECK(s4[i] == T(i));
+ }
}
{
- size_t n = size_t(h/1.5f);
- for ( size_t i = 0 ; i <= h ; ++i )
+ varray<T, N> v1, v2, v3;
+ varray<T, N/2> s1, s2;
+
+ for (size_t i = 0 ; i < N/2 ; ++i )
{
- varray<T, N> s1(s);
- s1.insert(s1.begin() + i, v.begin(), v.begin() + n);
- BOOST_CHECK(s1.size() == h+n);
- for ( size_t j = 0 ; j < i ; ++j )
- BOOST_CHECK(s1[j] == T(j));
- for ( size_t j = 0 ; j < n ; ++j )
- BOOST_CHECK(s1[j+i] == T(100 + j));
- for ( size_t j = 0 ; j < h-i ; ++j )
- BOOST_CHECK(s1[j+i+n] == T(j+i));
- }
+ v1.push_back(T(i));
+ v2.push_back(T(i));
+ v3.push_back(T(i));
+ }
+ for (size_t i = 0 ; i < N/3 ; ++i )
+ {
+ s1.push_back(T(100 + i));
+ s2.push_back(T(100 + i));
+ }
+
+ s1.swap(v1);
+ s2 = boost::move(v2);
+ varray<T, N/2> s3(boost::move(v3));
+
+ BOOST_CHECK(v1.size() == N/3);
+ BOOST_CHECK(s1.size() == N/2);
+ BOOST_CHECK(v2.size() == N/2); // objects aren't destroyed
+ BOOST_CHECK(s2.size() == N/2);
+ BOOST_CHECK(v3.size() == N/2); // objects aren't destroyed
+ BOOST_CHECK(s3.size() == N/2);
+ for (size_t i = 0 ; i < N/3 ; ++i )
+ BOOST_CHECK(v1[i] == T(100 + i));
+ for (size_t i = 0 ; i < N/2 ; ++i )
+ {
+ BOOST_CHECK(s1[i] == T(i));
+ BOOST_CHECK(s2[i] == T(i));
+ BOOST_CHECK(s3[i] == T(i));
+ }
}
{
- size_t n = size_t(h/1.5f);
- for ( size_t i = 0 ; i <= h ; ++i )
+ varray<T, N> v(N, T(0));
+ //varray<T, N/2, bad_alloc_strategy<T> > s(N/2, T(1));
+ varray<T, N/2> s(N/2, T(1));
+#ifndef BOOST_NO_EXCEPTIONS
+ //BOOST_CHECK_THROW(s.swap(v), std::bad_alloc);
+ //v.resize(N, T(0));
+ //BOOST_CHECK_THROW(s = boost::move(v), std::bad_alloc);
+ //v.resize(N, T(0));
+ //try {
+ // varray<T, N/2, bad_alloc_strategy<T> > s2(boost::move(v));
+ // BOOST_CHECK(false);
+ //} catch (std::bad_alloc &) {}
+#endif // BOOST_NO_EXCEPTIONS
+ }
+}
+
+template <typename T, size_t N>
+void test_emplace_0p()
+{
+ //emplace_back()
+ {
+ //varray<T, N, bad_alloc_strategy<T> > v;
+ varray<T, N> v;
+
+ for (int i = 0 ; i < int(N) ; ++i )
+ v.emplace_back();
+ BOOST_CHECK(v.size() == N);
+#ifndef BOOST_NO_EXCEPTIONS
+ //BOOST_CHECK_THROW(v.emplace_back(), std::bad_alloc);
+#endif
+ }
+}
+
+template <typename T, size_t N>
+void test_emplace_2p()
+{
+ //emplace_back(pos, int, int)
+ {
+ //varray<T, N, bad_alloc_strategy<T> > v;
+ varray<T, N> v;
+
+ for (int i = 0 ; i < int(N) ; ++i )
+ v.emplace_back(i, 100 + i);
+ BOOST_CHECK(v.size() == N);
+#ifndef BOOST_NO_EXCEPTIONS
+ //BOOST_CHECK_THROW(v.emplace_back(N, 100 + N), std::bad_alloc);
+#endif
+ BOOST_CHECK(v.size() == N);
+ for (int i = 0 ; i < int(N) ; ++i )
+ BOOST_CHECK(v[i] == T(i, 100 + i));
+ }
+
+ // emplace(pos, int, int)
+ {
+ //typedef typename varray<T, N, bad_alloc_strategy<T> >::iterator It;
+ typedef typename varray<T, N>::iterator It;
+
+ int h = N / 2;
+
+ //varray<T, N, bad_alloc_strategy<T> > v;
+ varray<T, N> v;
+ for ( int i = 0 ; i < h ; ++i )
+ v.emplace_back(i, 100 + i);
+
+ for ( int i = 0 ; i <= h ; ++i )
{
- varray<T, N> s1(s);
- typename std::list<T>::iterator it = l.begin();
- std::advance(it, n);
- s1.insert(s1.begin() + i, l.begin(), it);
- BOOST_CHECK(s1.size() == h+n);
- for ( size_t j = 0 ; j < i ; ++j )
- BOOST_CHECK(s1[j] == T(j));
- for ( size_t j = 0 ; j < n ; ++j )
- BOOST_CHECK(s1[j+i] == T(100 + j));
- for ( size_t j = 0 ; j < h-i ; ++j )
- BOOST_CHECK(s1[j+i+n] == T(j+i));
- }
+ //varray<T, N, bad_alloc_strategy<T> > vv(v);
+ varray<T, N> vv(v);
+ It it = vv.emplace(vv.begin() + i, i+100, i+200);
+ BOOST_CHECK(vv.begin() + i == it);
+ BOOST_CHECK(vv.size() == size_t(h+1));
+ for ( int j = 0 ; j < i ; ++j )
+ BOOST_CHECK(vv[j] == T(j, j+100));
+ BOOST_CHECK(vv[i] == T(i+100, i+200));
+ for ( int j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(vv[j+i+1] == T(j+i, j+i+100));
+ }
}
}
+template <typename T, size_t N>
+void test_sv_elem(T const& t)
+{
+ //typedef varray<T, N, bad_alloc_strategy<T> > V;
+ typedef varray<T, N> V;
+
+ //varray<V, N, bad_alloc_strategy<V> > v;
+ varray<V, N> v;
+
+ v.push_back(V(N/2, t));
+ V vvv(N/2, t);
+ v.push_back(boost::move(vvv));
+ v.insert(v.begin(), V(N/2, t));
+ v.insert(v.end(), V(N/2, t));
+ v.emplace_back(N/2, t);
+}
+
int test_main(int, char* [])
{
BOOST_CHECK(counting_value::count() == 0);
- test_ctor_ndc<int, 10>();
+ test_ctor_ndc<size_t, 10>();
test_ctor_ndc<value_ndc, 10>();
test_ctor_ndc<counting_value, 10>();
BOOST_CHECK(counting_value::count() == 0);
+ test_ctor_ndc<shptr_value, 10>();
+ test_ctor_ndc<copy_movable, 10>();
- test_ctor_nc<int, 10>(5);
+ test_ctor_nc<size_t, 10>(5);
test_ctor_nc<value_nc, 10>(5);
test_ctor_nc<counting_value, 10>(5);
BOOST_CHECK(counting_value::count() == 0);
+ test_ctor_nc<shptr_value, 10>(5);
+ test_ctor_nc<copy_movable, 10>(5);
- test_ctor_nd<int, 10>(5, 1);
+ test_ctor_nd<size_t, 10>(5, 1);
test_ctor_nd<value_nd, 10>(5, value_nd(1));
test_ctor_nd<counting_value, 10>(5, counting_value(1));
BOOST_CHECK(counting_value::count() == 0);
+ test_ctor_nd<shptr_value, 10>(5, shptr_value(1));
+ test_ctor_nd<copy_movable, 10>(5, produce());
- test_resize_nc<int, 10>(5);
+ test_resize_nc<size_t, 10>(5);
test_resize_nc<value_nc, 10>(5);
test_resize_nc<counting_value, 10>(5);
BOOST_CHECK(counting_value::count() == 0);
+ test_resize_nc<shptr_value, 10>(5);
+ test_resize_nc<copy_movable, 10>(5);
- test_resize_nd<int, 10>(5, 1);
+ test_resize_nd<size_t, 10>(5, 1);
test_resize_nd<value_nd, 10>(5, value_nd(1));
test_resize_nd<counting_value, 10>(5, counting_value(1));
BOOST_CHECK(counting_value::count() == 0);
+ test_resize_nd<shptr_value, 10>(5, shptr_value(1));
+ test_resize_nd<copy_movable, 10>(5, produce());
- test_push_back_nd<int, 10>();
+ test_push_back_nd<size_t, 10>();
test_push_back_nd<value_nd, 10>();
test_push_back_nd<counting_value, 10>();
BOOST_CHECK(counting_value::count() == 0);
+ test_push_back_nd<shptr_value, 10>();
+ test_push_back_nd<copy_movable, 10>();
- test_pop_back_nd<int, 10>();
+ test_pop_back_nd<size_t, 10>();
test_pop_back_nd<value_nd, 10>();
test_pop_back_nd<counting_value, 10>();
BOOST_CHECK(counting_value::count() == 0);
+ test_pop_back_nd<shptr_value, 10>();
+ test_pop_back_nd<copy_movable, 10>();
- test_copy_and_assign_nd<int, 10>(1);
+ test_copy_and_assign_nd<size_t, 10>(1);
test_copy_and_assign_nd<value_nd, 10>(value_nd(1));
test_copy_and_assign_nd<counting_value, 10>(counting_value(1));
BOOST_CHECK(counting_value::count() == 0);
+ test_copy_and_assign_nd<shptr_value, 10>(shptr_value(1));
+ test_copy_and_assign_nd<copy_movable, 10>(produce());
- test_iterators_nd<int, 10>();
+ test_iterators_nd<size_t, 10>();
test_iterators_nd<value_nd, 10>();
test_iterators_nd<counting_value, 10>();
BOOST_CHECK(counting_value::count() == 0);
+ test_iterators_nd<shptr_value, 10>();
+ test_iterators_nd<copy_movable, 10>();
- test_erase_nd<int, 10>();
+ test_erase_nd<size_t, 10>();
test_erase_nd<value_nd, 10>();
test_erase_nd<counting_value, 10>();
BOOST_CHECK(counting_value::count() == 0);
+ test_erase_nd<shptr_value, 10>();
+ test_erase_nd<copy_movable, 10>();
- test_insert_nd<int, 10>(50);
+ test_insert_nd<size_t, 10>(50);
test_insert_nd<value_nd, 10>(value_nd(50));
test_insert_nd<counting_value, 10>(counting_value(50));
BOOST_CHECK(counting_value::count() == 0);
+ test_insert_nd<shptr_value, 10>(shptr_value(50));
+ test_insert_nd<copy_movable, 10>(produce());
+
+ test_capacity_0_nd<size_t>();
+ test_capacity_0_nd<value_nd>();
+ test_capacity_0_nd<counting_value>();
+ BOOST_CHECK(counting_value::count() == 0);
+ test_capacity_0_nd<shptr_value>();
+ test_capacity_0_nd<copy_movable>();
+
+ test_exceptions_nd<size_t, 10>();
+ test_exceptions_nd<value_nd, 10>();
+ test_exceptions_nd<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+ test_exceptions_nd<shptr_value, 10>();
+ test_exceptions_nd<copy_movable, 10>();
+
+ test_swap_and_move_nd<size_t, 10>();
+ test_swap_and_move_nd<value_nd, 10>();
+ test_swap_and_move_nd<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+ test_swap_and_move_nd<shptr_value, 10>();
+ test_swap_and_move_nd<copy_movable, 10>();
+
+ test_emplace_0p<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_emplace_2p<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_sv_elem<size_t, 10>(50);
+ test_sv_elem<value_nd, 10>(value_nd(50));
+ test_sv_elem<counting_value, 10>(counting_value(50));
+ BOOST_CHECK(counting_value::count() == 0);
+ test_sv_elem<shptr_value, 10>(shptr_value(50));
+ test_sv_elem<copy_movable, 10>(copy_movable(50));
return 0;
}
Copied: branches/release/libs/geometry/index/test/varray_old.cpp (from r84886, trunk/libs/geometry/index/test/varray_old.cpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/libs/geometry/index/test/varray_old.cpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/libs/geometry/index/test/varray_old.cpp)
@@ -0,0 +1,490 @@
+// Boost.Geometry Index
+// Unit Test
+
+// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/test/included/test_exec_monitor.hpp>
+#include <boost/test/impl/execution_monitor.ipp>
+
+#include <boost/geometry/index/detail/varray.hpp>
+
+using namespace boost::geometry::index::detail;
+
+class value_ndc
+{
+public:
+ explicit value_ndc(int a) : aa(a) {}
+ ~value_ndc() {}
+ bool operator==(value_ndc const& v) const { return aa == v.aa; }
+private:
+ value_ndc(value_ndc const&) {}
+ value_ndc & operator=(value_ndc const&) { return *this; }
+ int aa;
+};
+
+class value_nd
+{
+public:
+ explicit value_nd(int a) : aa(a) {}
+ ~value_nd() {}
+ bool operator==(value_nd const& v) const { return aa == v.aa; }
+private:
+ int aa;
+};
+
+class value_nc
+{
+public:
+ explicit value_nc(int a = 0) : aa(a) {}
+ ~value_nc() {}
+ bool operator==(value_nc const& v) const { return aa == v.aa; }
+private:
+ value_nc(value_nc const&) {}
+ value_nc & operator=(value_ndc const&) { return *this; }
+ int aa;
+};
+
+class counting_value
+{
+public:
+ explicit counting_value(int a = 0) : aa(a) { ++c(); }
+ counting_value(counting_value const& v) : aa(v.aa) { ++c(); }
+ counting_value & operator=(counting_value const& v) { aa = v.aa; return *this; }
+ ~counting_value() { --c(); }
+ bool operator==(counting_value const& v) const { return aa == v.aa; }
+ static size_t count() { return c(); }
+private:
+ static size_t & c() { static size_t co = 0; return co; }
+ int aa;
+};
+
+template <typename T, size_t N>
+void test_ctor_ndc()
+{
+ varray<T, N> s;
+ BOOST_CHECK(s.size() == 0);
+ BOOST_CHECK(s.capacity() == N);
+ BOOST_CHECK_THROW( s.at(0), std::out_of_range );
+}
+
+template <typename T, size_t N>
+void test_ctor_nc(size_t n)
+{
+ varray<T, N> s(n);
+ BOOST_CHECK(s.size() == n);
+ BOOST_CHECK(s.capacity() == N);
+ BOOST_CHECK_THROW( s.at(n), std::out_of_range );
+ if ( !boost::has_trivial_constructor<T>::value )
+ {
+ for ( size_t i = 0 ; i < n ; ++i )
+ BOOST_CHECK(T() == s[i]);
+ }
+}
+
+template <typename T, size_t N>
+void test_ctor_nd(size_t n, T const& v)
+{
+ varray<T, N> s(n, v);
+ BOOST_CHECK(s.size() == n);
+ BOOST_CHECK(s.capacity() == N);
+ BOOST_CHECK_THROW( s.at(n), std::out_of_range );
+ if ( 1 < n )
+ {
+ BOOST_CHECK(v == s[0]);
+ BOOST_CHECK(v == s.at(0));
+ BOOST_CHECK(v == s[1]);
+ BOOST_CHECK(v == s.at(1));
+ s[0] = T(10);
+ BOOST_CHECK(T(10) == s[0]);
+ BOOST_CHECK(T(10) == s.at(0));
+ s.at(1) = T(20);
+ BOOST_CHECK(T(20) == s[1]);
+ BOOST_CHECK(T(20) == s.at(1));
+ }
+}
+
+template <typename T, size_t N>
+void test_resize_nc(size_t n)
+{
+ varray<T, N> s;
+
+ s.resize(n);
+ BOOST_CHECK(s.size() == n);
+ BOOST_CHECK(s.capacity() == N);
+ BOOST_CHECK_THROW( s.at(n), std::out_of_range );
+
+ if ( !boost::has_trivial_constructor<T>::value )
+ {
+ for ( size_t i = 0 ; i < n ; ++i )
+ BOOST_CHECK(T() == s[i]);
+ }
+}
+
+template <typename T, size_t N>
+void test_resize_nd(size_t n, T const& v)
+{
+ varray<T, N> s;
+
+ s.resize(n, v);
+ BOOST_CHECK(s.size() == n);
+ BOOST_CHECK(s.capacity() == N);
+ BOOST_CHECK_THROW( s.at(n), std::out_of_range );
+ if ( 1 < n )
+ {
+ BOOST_CHECK(v == s[0]);
+ BOOST_CHECK(v == s.at(0));
+ BOOST_CHECK(v == s[1]);
+ BOOST_CHECK(v == s.at(1));
+ s[0] = T(10);
+ BOOST_CHECK(T(10) == s[0]);
+ BOOST_CHECK(T(10) == s.at(0));
+ s.at(1) = T(20);
+ BOOST_CHECK(T(20) == s[1]);
+ BOOST_CHECK(T(20) == s.at(1));
+ }
+}
+
+template <typename T, size_t N>
+void test_push_back_nd()
+{
+ varray<T, N> s;
+
+ BOOST_CHECK(s.size() == 0);
+ BOOST_CHECK_THROW( s.at(0), std::out_of_range );
+
+ for ( size_t i = 0 ; i < N ; ++i )
+ {
+ s.push_back(T(i));
+ BOOST_CHECK(s.size() == i + 1);
+ BOOST_CHECK_THROW( s.at(i + 1), std::out_of_range );
+ BOOST_CHECK(T(i) == s.at(i));
+ BOOST_CHECK(T(i) == s[i]);
+ BOOST_CHECK(T(i) == s.back());
+ BOOST_CHECK(T(0) == s.front());
+ }
+}
+
+template <typename T, size_t N>
+void test_pop_back_nd()
+{
+ varray<T, N> s;
+
+ for ( size_t i = 0 ; i < N ; ++i )
+ s.push_back(T(i));
+
+ for ( size_t i = N ; i > 1 ; --i )
+ {
+ s.pop_back();
+ BOOST_CHECK(s.size() == i - 1);
+ BOOST_CHECK_THROW( s.at(i - 1), std::out_of_range );
+ BOOST_CHECK(T(i - 2) == s.at(i - 2));
+ BOOST_CHECK(T(i - 2) == s[i - 2]);
+ BOOST_CHECK(T(i - 2) == s.back());
+ BOOST_CHECK(T(0) == s.front());
+ }
+}
+
+template <typename It1, typename It2>
+void test_compare_ranges(It1 first1, It1 last1, It2 first2, It2 last2)
+{
+ BOOST_CHECK(std::distance(first1, last1) == std::distance(first2, last2));
+ for ( ; first1 != last1 && first2 != last2 ; ++first1, ++first2 )
+ BOOST_CHECK(*first1 == *first2);
+}
+
+template <typename T, size_t N>
+void test_copy_and_assign_nd(T const& val)
+{
+ varray<T, N> s;
+ std::vector<T> v;
+ std::list<T> l;
+
+ for ( size_t i = 0 ; i < N ; ++i )
+ {
+ s.push_back(T(i));
+ v.push_back(T(i));
+ l.push_back(T(i));
+ }
+ // copy ctor
+ {
+ varray<T, N> s1(s);
+ BOOST_CHECK(s.size() == s1.size());
+ test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
+ }
+ // copy assignment
+ {
+ varray<T, N> s1;
+ BOOST_CHECK(0 == s1.size());
+ s1 = s;
+ BOOST_CHECK(s.size() == s1.size());
+ test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
+ }
+ // ctor(Iter, Iter)
+ {
+ varray<T, N> s1(s.begin(), s.end());
+ BOOST_CHECK(s.size() == s1.size());
+ test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
+ }
+ {
+ varray<T, N> s1(v.begin(), v.end());
+ BOOST_CHECK(v.size() == s1.size());
+ test_compare_ranges(v.begin(), v.end(), s1.begin(), s1.end());
+ }
+ {
+ varray<T, N> s1(l.begin(), l.end());
+ BOOST_CHECK(l.size() == s1.size());
+ test_compare_ranges(l.begin(), l.end(), s1.begin(), s1.end());
+ }
+ // assign(Iter, Iter)
+ {
+ varray<T, N> s1;
+ BOOST_CHECK(0 == s1.size());
+ s1.assign(s.begin(), s.end());
+ BOOST_CHECK(s.size() == s1.size());
+ test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
+ }
+ {
+ varray<T, N> s1;
+ BOOST_CHECK(0 == s1.size());
+ s1.assign(v.begin(), v.end());
+ BOOST_CHECK(v.size() == s1.size());
+ test_compare_ranges(v.begin(), v.end(), s1.begin(), s1.end());
+ }
+ {
+ varray<T, N> s1;
+ BOOST_CHECK(0 == s1.size());
+ s1.assign(l.begin(), l.end());
+ BOOST_CHECK(l.size() == s1.size());
+ test_compare_ranges(l.begin(), l.end(), s1.begin(), s1.end());
+ }
+ // assign(N, V)
+ {
+ varray<T, N> s1(s);
+ test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
+ std::vector<T> a(N, val);
+ s1.assign(N, val);
+ test_compare_ranges(a.begin(), a.end(), s1.begin(), s1.end());
+ }
+}
+
+template <typename T, size_t N>
+void test_iterators_nd()
+{
+ varray<T, N> s;
+ std::vector<T> v;
+
+ for ( size_t i = 0 ; i < N ; ++i )
+ {
+ s.push_back(T(i));
+ v.push_back(T(i));
+ }
+
+ test_compare_ranges(s.begin(), s.end(), v.begin(), v.end());
+ test_compare_ranges(s.rbegin(), s.rend(), v.rbegin(), v.rend());
+
+ s.assign(v.rbegin(), v.rend());
+
+ test_compare_ranges(s.begin(), s.end(), v.rbegin(), v.rend());
+ test_compare_ranges(s.rbegin(), s.rend(), v.begin(), v.end());
+}
+
+template <typename T, size_t N>
+void test_erase_nd()
+{
+ varray<T, N> s;
+
+ for ( size_t i = 0 ; i < N ; ++i )
+ s.push_back(T(i));
+
+ // erase(pos)
+ {
+ for ( size_t i = 0 ; i < N ; ++i )
+ {
+ varray<T, N> s1(s);
+ s1.erase(s1.begin() + i);
+ BOOST_CHECK(s1.size() == N - 1);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = i+1 ; j < N ; ++j )
+ BOOST_CHECK(s1[j-1] == T(j));
+ }
+ }
+ // erase(first, last)
+ {
+ size_t n = N/3;
+ for ( size_t i = 0 ; i <= N ; ++i )
+ {
+ varray<T, N> s1(s);
+ size_t removed = i + n < N ? n : N - i;
+ s1.erase(s1.begin() + i, s1.begin() + i + removed);
+ BOOST_CHECK(s1.size() == N - removed);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = i+n ; j < N ; ++j )
+ BOOST_CHECK(s1[j-n] == T(j));
+ }
+ }
+}
+
+template <typename T, size_t N>
+void test_insert_nd(T const& val)
+{
+ size_t h = N/2;
+
+ varray<T, N> s, ss;
+ std::vector<T> v;
+ std::list<T> l;
+
+ for ( size_t i = 0 ; i < h ; ++i )
+ {
+ s.push_back(T(i));
+ ss.push_back(T(100 + i));
+ v.push_back(T(100 + i));
+ l.push_back(T(100 + i));
+ }
+
+ // insert(pos, val)
+ {
+ for ( size_t i = 0 ; i <= h ; ++i )
+ {
+ varray<T, N> s1(s);
+ s1.insert(s1.begin() + i, val);
+ BOOST_CHECK(s1.size() == h+1);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ BOOST_CHECK(s1[i] == val);
+ for ( size_t j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(s1[j+i+1] == T(j+i));
+ }
+ }
+ // insert(pos, n, val)
+ {
+ size_t n = size_t(h/1.5f);
+ for ( size_t i = 0 ; i <= h ; ++i )
+ {
+ varray<T, N> s1(s);
+ s1.insert(s1.begin() + i, n, val);
+ BOOST_CHECK(s1.size() == h+n);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = 0 ; j < n ; ++j )
+ BOOST_CHECK(s1[j+i] == val);
+ for ( size_t j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(s1[j+i+n] == T(j+i));
+ }
+ }
+ // insert(pos, first, last)
+ {
+ size_t n = size_t(h/1.5f);
+ for ( size_t i = 0 ; i <= h ; ++i )
+ {
+ varray<T, N> s1(s);
+ s1.insert(s1.begin() + i, ss.begin(), ss.begin() + n);
+ BOOST_CHECK(s1.size() == h+n);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = 0 ; j < n ; ++j )
+ BOOST_CHECK(s1[j+i] == T(100 + j));
+ for ( size_t j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(s1[j+i+n] == T(j+i));
+ }
+ }
+ {
+ size_t n = size_t(h/1.5f);
+ for ( size_t i = 0 ; i <= h ; ++i )
+ {
+ varray<T, N> s1(s);
+ s1.insert(s1.begin() + i, v.begin(), v.begin() + n);
+ BOOST_CHECK(s1.size() == h+n);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = 0 ; j < n ; ++j )
+ BOOST_CHECK(s1[j+i] == T(100 + j));
+ for ( size_t j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(s1[j+i+n] == T(j+i));
+ }
+ }
+ {
+ size_t n = size_t(h/1.5f);
+ for ( size_t i = 0 ; i <= h ; ++i )
+ {
+ varray<T, N> s1(s);
+ typename std::list<T>::iterator it = l.begin();
+ std::advance(it, n);
+ s1.insert(s1.begin() + i, l.begin(), it);
+ BOOST_CHECK(s1.size() == h+n);
+ for ( size_t j = 0 ; j < i ; ++j )
+ BOOST_CHECK(s1[j] == T(j));
+ for ( size_t j = 0 ; j < n ; ++j )
+ BOOST_CHECK(s1[j+i] == T(100 + j));
+ for ( size_t j = 0 ; j < h-i ; ++j )
+ BOOST_CHECK(s1[j+i+n] == T(j+i));
+ }
+ }
+}
+
+int test_main(int, char* [])
+{
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_ctor_ndc<int, 10>();
+ test_ctor_ndc<value_ndc, 10>();
+ test_ctor_ndc<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_ctor_nc<int, 10>(5);
+ test_ctor_nc<value_nc, 10>(5);
+ test_ctor_nc<counting_value, 10>(5);
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_ctor_nd<int, 10>(5, 1);
+ test_ctor_nd<value_nd, 10>(5, value_nd(1));
+ test_ctor_nd<counting_value, 10>(5, counting_value(1));
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_resize_nc<int, 10>(5);
+ test_resize_nc<value_nc, 10>(5);
+ test_resize_nc<counting_value, 10>(5);
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_resize_nd<int, 10>(5, 1);
+ test_resize_nd<value_nd, 10>(5, value_nd(1));
+ test_resize_nd<counting_value, 10>(5, counting_value(1));
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_push_back_nd<int, 10>();
+ test_push_back_nd<value_nd, 10>();
+ test_push_back_nd<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_pop_back_nd<int, 10>();
+ test_pop_back_nd<value_nd, 10>();
+ test_pop_back_nd<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_copy_and_assign_nd<int, 10>(1);
+ test_copy_and_assign_nd<value_nd, 10>(value_nd(1));
+ test_copy_and_assign_nd<counting_value, 10>(counting_value(1));
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_iterators_nd<int, 10>();
+ test_iterators_nd<value_nd, 10>();
+ test_iterators_nd<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_erase_nd<int, 10>();
+ test_erase_nd<value_nd, 10>();
+ test_erase_nd<counting_value, 10>();
+ BOOST_CHECK(counting_value::count() == 0);
+
+ test_insert_nd<int, 10>(50);
+ test_insert_nd<value_nd, 10>(value_nd(50));
+ test_insert_nd<counting_value, 10>(counting_value(50));
+ BOOST_CHECK(counting_value::count() == 0);
+
+ return 0;
+}
Copied: branches/release/libs/geometry/index/test/varray_test.hpp (from r84886, trunk/libs/geometry/index/test/varray_test.hpp)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/release/libs/geometry/index/test/varray_test.hpp 2013-06-23 16:59:55 EDT (Sun, 23 Jun 2013) (r84889, copy of r84886, trunk/libs/geometry/index/test/varray_test.hpp)
@@ -0,0 +1,97 @@
+// Boost.Geometry.Index varray
+// Unit Test
+
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2012-2013 Andrew Hundt.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_INDEX_TEST_VARRAY_TEST_HPP
+#define BOOST_GEOMETRY_INDEX_TEST_VARRAY_TEST_HPP
+
+#include <boost/geometry/index/detail/varray.hpp>
+
+#include <boost/shared_ptr.hpp>
+#include "movable.hpp"
+
+class value_ndc
+{
+public:
+ explicit value_ndc(size_t a) : aa(a) {}
+ ~value_ndc() {}
+ bool operator==(value_ndc const& v) const { return aa == v.aa; }
+ bool operator<(value_ndc const& v) const { return aa < v.aa; }
+private:
+ value_ndc(value_ndc const&) {}
+ value_ndc & operator=(value_ndc const&) { return *this; }
+ size_t aa;
+};
+
+class value_nd
+{
+public:
+ explicit value_nd(size_t a) : aa(a) {}
+ ~value_nd() {}
+ bool operator==(value_nd const& v) const { return aa == v.aa; }
+ bool operator<(value_nd const& v) const { return aa < v.aa; }
+private:
+ size_t aa;
+};
+
+class value_nc
+{
+public:
+ explicit value_nc(size_t a = 0) : aa(a) {}
+ ~value_nc() {}
+ bool operator==(value_nc const& v) const { return aa == v.aa; }
+ bool operator<(value_nc const& v) const { return aa < v.aa; }
+private:
+ value_nc(value_nc const&) {}
+ value_nc & operator=(value_ndc const&) { return *this; }
+ size_t aa;
+};
+
+class counting_value
+{
+ BOOST_COPYABLE_AND_MOVABLE(counting_value)
+
+public:
+ explicit counting_value(size_t a = 0, size_t b = 0) : aa(a), bb(b) { ++c(); }
+ counting_value(counting_value const& v) : aa(v.aa), bb(v.bb) { ++c(); }
+ counting_value(BOOST_RV_REF(counting_value) p) : aa(p.aa), bb(p.bb) { p.aa = 0; p.bb = 0; ++c(); } // Move constructor
+ counting_value& operator=(BOOST_RV_REF(counting_value) p) { aa = p.aa; p.aa = 0; bb = p.bb; p.bb = 0; return *this; } // Move assignment
+ counting_value& operator=(BOOST_COPY_ASSIGN_REF(counting_value) p) { aa = p.aa; bb = p.bb; return *this; } // Copy assignment
+ ~counting_value() { --c(); }
+ bool operator==(counting_value const& v) const { return aa == v.aa && bb == v.bb; }
+ bool operator<(counting_value const& v) const { return aa < v.aa || ( aa == v.aa && bb < v.bb ); }
+ static size_t count() { return c(); }
+
+private:
+ static size_t & c() { static size_t co = 0; return co; }
+ size_t aa, bb;
+};
+
+namespace boost {
+
+template <>
+struct has_nothrow_move<counting_value>
+{
+ static const bool value = true;
+};
+
+}
+
+class shptr_value
+{
+ typedef boost::shared_ptr<size_t> Ptr;
+public:
+ explicit shptr_value(size_t a = 0) : m_ptr(new size_t(a)) {}
+ bool operator==(shptr_value const& v) const { return *m_ptr == *(v.m_ptr); }
+ bool operator<(shptr_value const& v) const { return *m_ptr < *(v.m_ptr); }
+private:
+ boost::shared_ptr<size_t> m_ptr;
+};
+
+#endif // BOOST_GEOMETRY_INDEX_TEST_VARRAY_TEST_HPP
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk