diff DEPENDENCIES/generic/include/boost/geometry/index/rtree.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/geometry/index/rtree.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,1786 @@
+// Boost.Geometry Index
+//
+// R-tree implementation
+//
+// Copyright (c) 2008 Federico J. Fernandez.
+// 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_RTREE_HPP
+#define BOOST_GEOMETRY_INDEX_RTREE_HPP
+
+#include <algorithm>
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/move/move.hpp>
+
+#include <boost/geometry/geometry.hpp>
+
+#include <boost/geometry/index/detail/config_begin.hpp>
+
+#include <boost/geometry/index/detail/assert.hpp>
+#include <boost/geometry/index/detail/exception.hpp>
+
+#include <boost/geometry/index/detail/rtree/options.hpp>
+
+#include <boost/geometry/index/indexable.hpp>
+#include <boost/geometry/index/equal_to.hpp>
+
+#include <boost/geometry/index/detail/translator.hpp>
+
+#include <boost/geometry/index/predicates.hpp>
+#include <boost/geometry/index/distance_predicates.hpp>
+#include <boost/geometry/index/detail/rtree/adaptors.hpp>
+
+#include <boost/geometry/index/detail/meta.hpp>
+#include <boost/geometry/index/detail/utilities.hpp>
+#include <boost/geometry/index/detail/rtree/node/node.hpp>
+
+#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
+
+#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/spatial_query.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/distance_query.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/count.hpp>
+#include <boost/geometry/index/detail/rtree/visitors/children_box.hpp>
+
+#include <boost/geometry/index/detail/rtree/linear/linear.hpp>
+#include <boost/geometry/index/detail/rtree/quadratic/quadratic.hpp>
+#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>
+
+#include <boost/geometry/index/detail/rtree/query_iterators.hpp>
+
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+// serialization
+#include <boost/geometry/index/detail/serialization.hpp>
+#endif
+
+// TODO change the name to bounding_tree
+
+/*!
+\defgroup rtree_functions R-tree free functions (boost::geometry::index::)
+*/
+
+namespace boost { namespace geometry { namespace index {
+
+/*!
+\brief The R-tree spatial index.
+
+This is self-balancing spatial index capable to store various types of Values and balancing algorithms.
+
+\par Parameters
+The user must pass a type defining the Parameters which will
+be used in rtree creation process. This type is used e.g. to specify balancing algorithm
+with specific parameters like min and max number of elements in node.
+
+\par
+Predefined algorithms with compile-time parameters are:
+\li <tt>boost::geometry::index::linear</tt>,
+ \li <tt>boost::geometry::index::quadratic</tt>,
+ \li <tt>boost::geometry::index::rstar</tt>.
+
+\par
+Predefined algorithms with run-time parameters are:
+ \li \c boost::geometry::index::dynamic_linear,
+ \li \c boost::geometry::index::dynamic_quadratic,
+ \li \c boost::geometry::index::dynamic_rstar.
+
+\par IndexableGetter
+The object of IndexableGetter type translates from Value to Indexable each time r-tree requires it. Which means that this
+operation is done for each Value access. Therefore the IndexableGetter should return the Indexable by
+const reference instead of a value. Default one can translate all types adapted to Point
+or Box concepts (called Indexables). It also handles <tt>std::pair<Indexable, T></tt> and
+<tt>boost::tuple<Indexable, ...></tt>. For example, if <tt>std::pair<Box, int></tt> is stored in the
+container, the default IndexableGetter translates from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
+
+\par EqualTo
+The object of EqualTo type compares Values and returns <tt>true</tt> if they're equal. It's similar to <tt>std::equal_to<></tt>.
+The default EqualTo returns the result of <tt>boost::geometry::equals()</tt> for types adapted to some Geometry concept
+defined in Boost.Geometry and the result of operator= for other types. Components of Pairs and Tuples are compared left-to-right.
+
+\tparam Value           The type of objects stored in the container.
+\tparam Parameters      Compile-time parameters.
+\tparam IndexableGetter The function object extracting Indexable from Value.
+\tparam EqualTo         The function object comparing objects of type Value.
+\tparam Allocator       The allocator used to allocate/deallocate memory, construct/destroy nodes and Values.
+*/
+template <
+    typename Value,
+    typename Parameters,
+    typename IndexableGetter = index::indexable<Value>,
+    typename EqualTo = index::equal_to<Value>,
+    typename Allocator = std::allocator<Value>
+>
+class rtree
+{
+    BOOST_COPYABLE_AND_MOVABLE(rtree)
+
+public:
+    /*! \brief The type of Value stored in the container. */
+    typedef Value value_type;
+    /*! \brief R-tree parameters type. */
+    typedef Parameters parameters_type;
+    /*! \brief The function object extracting Indexable from Value. */
+    typedef IndexableGetter indexable_getter;
+    /*! \brief The function object comparing objects of type Value. */
+    typedef EqualTo value_equal;
+    /*! \brief The type of allocator used by the container. */
+    typedef Allocator allocator_type;
+
+    // TODO: SHOULD THIS TYPE BE REMOVED?
+    /*! \brief The Indexable type to which Value is translated. */
+    typedef typename index::detail::indexable_type<
+        detail::translator<IndexableGetter, EqualTo>
+    >::type indexable_type;
+
+    /*! \brief The Box type used by the R-tree. */
+    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;
+
+private:
+
+    typedef detail::translator<IndexableGetter, EqualTo> translator_type;
+
+    typedef bounds_type box_type;
+    typedef typename detail::rtree::options_type<Parameters>::type options_type;
+    typedef typename options_type::node_tag node_tag;
+    typedef detail::rtree::allocators<allocator_type, value_type, typename options_type::parameters_type, box_type, node_tag> allocators_type;
+
+    typedef typename detail::rtree::node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type node;
+    typedef typename detail::rtree::internal_node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type internal_node;
+    typedef typename detail::rtree::leaf<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type leaf;
+
+    typedef typename allocators_type::node_pointer node_pointer;
+    typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
+    typedef detail::rtree::node_auto_ptr<value_type, options_type, translator_type, box_type, allocators_type> node_auto_ptr;
+
+    friend class detail::rtree::utilities::view<rtree>;
+#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+    friend class detail::rtree::private_view<rtree>;
+    friend class detail::rtree::const_private_view<rtree>;
+#endif
+
+public:
+
+    /*! \brief Type of reference to Value. */
+    typedef typename allocators_type::reference reference;
+    /*! \brief Type of reference to const Value. */
+    typedef typename allocators_type::const_reference const_reference;
+    /*! \brief Type of pointer to Value. */
+    typedef typename allocators_type::pointer pointer;
+    /*! \brief Type of pointer to const Value. */
+    typedef typename allocators_type::const_pointer const_pointer;
+    /*! \brief Type of difference type. */
+    typedef typename allocators_type::difference_type difference_type;
+    /*! \brief Unsigned integral type used by the container. */
+    typedef typename allocators_type::size_type size_type;
+
+    /*! \brief Type of const query iterator. */
+    typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
+
+public:
+
+    /*!
+    \brief The constructor.
+
+    \param parameters   The parameters object.
+    \param getter       The function object extracting Indexable from Value.
+    \param equal        The function object comparing Values.
+
+    \par Throws
+    If allocator default constructor throws.
+    */
+    inline explicit rtree(parameters_type const& parameters = parameters_type(),
+                          indexable_getter const& getter = indexable_getter(),
+                          value_equal const& equal = value_equal())
+        : m_members(getter, equal, parameters)
+    {}
+
+    /*!
+    \brief The constructor.
+
+    \param parameters   The parameters object.
+    \param getter       The function object extracting Indexable from Value.
+    \param equal        The function object comparing Values.
+    \param allocator    The allocator object.
+
+    \par Throws
+    If allocator copy constructor throws.
+    */
+    inline rtree(parameters_type const& parameters,
+                 indexable_getter const& getter,
+                 value_equal const& equal,
+                 allocator_type const& allocator)
+        : m_members(getter, equal, parameters, allocator)
+    {}
+
+    /*!
+    \brief The constructor.
+
+    The tree is created using packing algorithm.
+
+    \param first        The beginning of the range of Values.
+    \param last         The end of the range of Values.
+    \param parameters   The parameters object.
+    \param getter       The function object extracting Indexable from Value.
+    \param equal        The function object comparing Values.
+    \param allocator    The allocator object.
+
+    \par Throws
+    \li If allocator copy constructor throws.
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+    */
+    template<typename Iterator>
+    inline rtree(Iterator first, Iterator last,
+                 parameters_type const& parameters = parameters_type(),
+                 indexable_getter const& getter = indexable_getter(),
+                 value_equal const& equal = value_equal(),
+                 allocator_type const& allocator = allocator_type())
+        : m_members(getter, equal, parameters, allocator)
+    {
+        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;
+    }
+
+    /*!
+    \brief The constructor.
+
+    The tree is created using packing algorithm.
+
+    \param rng          The range of Values.
+    \param parameters   The parameters object.
+    \param getter       The function object extracting Indexable from Value.
+    \param equal        The function object comparing Values.
+    \param allocator    The allocator object.
+
+    \par Throws
+    \li If allocator copy constructor throws.
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+    */
+    template<typename Range>
+    inline explicit rtree(Range const& rng,
+                          parameters_type const& parameters = parameters_type(),
+                          indexable_getter const& getter = indexable_getter(),
+                          value_equal const& equal = value_equal(),
+                          allocator_type const& allocator = allocator_type())
+        : m_members(getter, equal, parameters, allocator)
+    {
+        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;
+    }
+
+    /*!
+    \brief The destructor.
+
+    \par Throws
+    Nothing.
+    */
+    inline ~rtree()
+    {
+        this->raw_destroy(*this);
+    }
+
+    /*!
+    \brief  The copy constructor.
+
+    It uses parameters, translator and allocator from the source tree.
+
+    \param src          The rtree which content will be copied.
+
+    \par Throws
+    \li If allocator copy constructor throws.
+    \li If Value copy constructor throws.
+    \li If allocation throws or returns invalid value.
+    */
+    inline rtree(rtree const& src)
+        : m_members(src.m_members.indexable_getter(),
+                    src.m_members.equal_to(),
+                    src.m_members.parameters(),
+                    allocator_traits_type::select_on_container_copy_construction(src.get_allocator()))
+    {
+        this->raw_copy(src, *this, false);
+    }
+
+    /*!
+    \brief The copy constructor.
+
+    It uses Parameters and translator from the source tree.
+
+    \param src          The rtree which content will be copied.
+    \param allocator    The allocator which will be used.
+
+    \par Throws
+    \li If allocator copy constructor throws.
+    \li If Value copy constructor throws.
+    \li If allocation throws or returns invalid value.
+    */
+    inline rtree(rtree const& src, allocator_type const& allocator)
+        : m_members(src.m_members.indexable_getter(),
+                    src.m_members.equal_to(),
+                    src.m_members.parameters(), allocator)
+    {
+        this->raw_copy(src, *this, false);
+    }
+
+    /*!
+    \brief The moving constructor.
+
+    It uses parameters, translator and allocator from the source tree.
+
+    \param src          The rtree which content will be moved.
+
+    \par Throws
+    Nothing.
+    */
+    inline rtree(BOOST_RV_REF(rtree) src)
+        : m_members(src.m_members.indexable_getter(),
+                    src.m_members.equal_to(),
+                    src.m_members.parameters(),
+                    boost::move(src.m_members.allocators()))
+    {
+        boost::swap(m_members.values_count, src.m_members.values_count);
+        boost::swap(m_members.leafs_level, src.m_members.leafs_level);
+        boost::swap(m_members.root, src.m_members.root);
+    }
+
+    /*!
+    \brief The moving constructor.
+
+    It uses parameters and translator from the source tree.
+
+    \param src          The rtree which content will be moved.
+    \param allocator    The allocator.
+
+    \par Throws
+    \li If allocator copy constructor throws.
+    \li If Value copy constructor throws (only if allocators aren't equal).
+    \li If allocation throws or returns invalid value (only if allocators aren't equal).
+    */
+    inline rtree(BOOST_RV_REF(rtree) src, allocator_type const& allocator)
+        : m_members(src.m_members.indexable_getter(),
+                    src.m_members.equal_to(),
+                    src.m_members.parameters(),
+                    allocator)
+    {
+        if ( src.m_members.allocators() == allocator )
+        {
+            boost::swap(m_members.values_count, src.m_members.values_count);
+            boost::swap(m_members.leafs_level, src.m_members.leafs_level);
+            boost::swap(m_members.root, src.m_members.root);
+        }
+        else
+        {
+            this->raw_copy(src, *this, false);
+        }
+    }
+
+    /*!
+    \brief The assignment operator.
+
+    It uses parameters and translator from the source tree.
+
+    \param src          The rtree which content will be copied.
+
+    \par Throws
+    \li If Value copy constructor throws.
+    \li If allocation throws.
+    \li If allocation throws or returns invalid value.
+    */
+    inline rtree & operator=(BOOST_COPY_ASSIGN_REF(rtree) src)
+    {
+        if ( &src != this )
+        {
+            allocators_type & this_allocs = m_members.allocators();
+            allocators_type const& src_allocs = src.m_members.allocators();
+
+            // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
+            // (allocators stored as base classes of members_holder)
+            // copying them changes values_count, in this case it doesn't cause errors since data must be copied
+            
+            typedef boost::mpl::bool_<
+                allocator_traits_type::propagate_on_container_copy_assignment::value
+            > propagate;
+            
+            if ( propagate::value && !(this_allocs == src_allocs) )
+                this->raw_destroy(*this);
+            detail::assign_cond(this_allocs, src_allocs, propagate());
+
+            // It uses m_allocators
+            this->raw_copy(src, *this, true);
+        }
+
+        return *this;
+    }
+
+    /*!
+    \brief The moving assignment.
+
+    It uses parameters and translator from the source tree.
+
+    \param src          The rtree which content will be moved.
+
+    \par Throws
+    Only if allocators aren't equal.
+    \li If Value copy constructor throws.
+    \li If allocation throws or returns invalid value.
+    */
+    inline rtree & operator=(BOOST_RV_REF(rtree) src)
+    {
+        if ( &src != this )
+        {
+            allocators_type & this_allocs = m_members.allocators();
+            allocators_type & src_allocs = src.m_members.allocators();
+            
+            if ( this_allocs == src_allocs )
+            {
+                this->raw_destroy(*this);
+
+                m_members.indexable_getter() = src.m_members.indexable_getter();
+                m_members.equal_to() = src.m_members.equal_to();
+                m_members.parameters() = src.m_members.parameters();
+
+                boost::swap(m_members.values_count, src.m_members.values_count);
+                boost::swap(m_members.leafs_level, src.m_members.leafs_level);
+                boost::swap(m_members.root, src.m_members.root);
+
+                // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
+                // (allocators stored as base classes of members_holder)
+                // moving them changes values_count
+                
+                typedef boost::mpl::bool_<
+                    allocator_traits_type::propagate_on_container_move_assignment::value
+                > propagate;
+                detail::move_cond(this_allocs, src_allocs, propagate());
+            }
+            else
+            {
+// TODO - shouldn't here propagate_on_container_copy_assignment be checked like in operator=(const&)?
+
+                // It uses m_allocators
+                this->raw_copy(src, *this, true);
+            }
+        }
+
+        return *this;
+    }
+
+    /*!
+    \brief Swaps contents of two rtrees.
+
+    Parameters, translator and allocators are swapped as well.
+
+    \param other    The rtree which content will be swapped with this rtree content.
+
+    \par Throws
+    If allocators swap throws.
+    */
+    void swap(rtree & other)
+    {
+        boost::swap(m_members.indexable_getter(), other.m_members.indexable_getter());
+        boost::swap(m_members.equal_to(), other.m_members.equal_to());
+        boost::swap(m_members.parameters(), other.m_members.parameters());
+        
+        // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
+        // (allocators stored as base classes of members_holder)
+        // swapping them changes values_count
+        
+        typedef boost::mpl::bool_<
+            allocator_traits_type::propagate_on_container_swap::value
+        > propagate;
+        detail::swap_cond(m_members.allocators(), other.m_members.allocators(), propagate());
+
+        boost::swap(m_members.values_count, other.m_members.values_count);
+        boost::swap(m_members.leafs_level, other.m_members.leafs_level);
+        boost::swap(m_members.root, other.m_members.root);
+    }
+
+    /*!
+    \brief Insert a value to the index.
+
+    \param value    The value which will be stored in the container.
+
+    \par Throws
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+
+    \warning
+    This operation only guarantees that there will be no memory leaks.
+    After an exception is thrown the R-tree may be left in an inconsistent state,
+    elements must not be inserted or removed. Other operations are allowed however
+    some of them may return invalid data.
+    */
+    inline void insert(value_type const& value)
+    {
+        if ( !m_members.root )
+            this->raw_create();
+
+        this->raw_insert(value);
+    }
+
+    /*!
+    \brief Insert a range of values to the index.
+
+    \param first    The beginning of the range of values.
+    \param last     The end of the range of values.
+
+    \par Throws
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+
+    \warning
+    This operation only guarantees that there will be no memory leaks.
+    After an exception is thrown the R-tree may be left in an inconsistent state,
+    elements must not be inserted or removed. Other operations are allowed however
+    some of them may return invalid data.
+    */
+    template <typename Iterator>
+    inline void insert(Iterator first, Iterator last)
+    {
+        if ( !m_members.root )
+            this->raw_create();
+
+        for ( ; first != last ; ++first )
+            this->raw_insert(*first);
+    }
+
+    /*!
+    \brief Insert a range of values to the index.
+
+    \param rng      The range of values.
+
+    \par Throws
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+
+    \warning
+    This operation only guarantees that there will be no memory leaks.
+    After an exception is thrown the R-tree may be left in an inconsistent state,
+    elements must not be inserted or removed. Other operations are allowed however
+    some of them may return invalid data.
+    */
+    template <typename Range>
+    inline void insert(Range const& rng)
+    {
+        BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
+
+        if ( !m_members.root )
+            this->raw_create();
+
+        typedef typename boost::range_const_iterator<Range>::type It;
+        for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
+            this->raw_insert(*it);
+    }
+
+    /*!
+    \brief Remove a value from the container.
+
+    In contrast to the \c std::set or <tt>std::map erase()</tt> method
+    this method removes only one value from the container.
+
+    \param value    The value which will be removed from the container.
+
+    \return         1 if the value was removed, 0 otherwise.
+
+    \par Throws
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+
+    \warning
+    This operation only guarantees that there will be no memory leaks.
+    After an exception is thrown the R-tree may be left in an inconsistent state,
+    elements must not be inserted or removed. Other operations are allowed however
+    some of them may return invalid data.
+    */
+    inline size_type remove(value_type const& value)
+    {
+        return this->raw_remove(value);
+    }
+
+    /*!
+    \brief Remove a range of values from the container.
+
+    In contrast to the \c std::set or <tt>std::map erase()</tt> method
+    it doesn't take iterators pointing to values stored in this container. It removes values equal
+    to these passed as a range. Furthermore this method removes only one value for each one passed
+    in the range, not all equal values.
+
+    \param first    The beginning of the range of values.
+    \param last     The end of the range of values.
+
+    \return         The number of removed values.
+
+    \par Throws
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+
+    \warning
+    This operation only guarantees that there will be no memory leaks.
+    After an exception is thrown the R-tree may be left in an inconsistent state,
+    elements must not be inserted or removed. Other operations are allowed however
+    some of them may return invalid data.
+    */
+    template <typename Iterator>
+    inline size_type remove(Iterator first, Iterator last)
+    {
+        size_type result = 0;
+        for ( ; first != last ; ++first )
+            result += this->raw_remove(*first);
+        return result;
+    }
+
+    /*!
+    \brief Remove a range of values from the container.
+
+    In contrast to the \c std::set or <tt>std::map erase()</tt> method
+    it removes values equal to these passed as a range. Furthermore, this method removes only
+    one value for each one passed in the range, not all equal values.
+
+    \param rng      The range of values.
+
+    \return         The number of removed values.
+
+    \par Throws
+    \li If Value copy constructor or copy assignment throws.
+    \li If allocation throws or returns invalid value.
+
+    \warning
+    This operation only guarantees that there will be no memory leaks.
+    After an exception is thrown the R-tree may be left in an inconsistent state,
+    elements must not be inserted or removed. Other operations are allowed however
+    some of them may return invalid data.
+    */
+    template <typename Range>
+    inline size_type remove(Range const& rng)
+    {
+        BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));
+
+        size_type result = 0;
+        typedef typename boost::range_const_iterator<Range>::type It;
+        for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
+            result += this->raw_remove(*it);
+        return result;
+    }
+
+    /*!
+    \brief Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box.
+
+    This query function performs spatial and k-nearest neighbor searches. It allows to pass a set of predicates.
+    Values will be returned only if all predicates are met.
+
+    <b>Spatial predicates</b>
+    
+    Spatial predicates may be generated by one of the functions listed below:
+    \li \c boost::geometry::index::contains(),
+    \li \c boost::geometry::index::covered_by(),
+    \li \c boost::geometry::index::covers(),
+    \li \c boost::geometry::index::disjoint(),
+    \li \c boost::geometry::index::intersects(),
+    \li \c boost::geometry::index::overlaps(),
+    \li \c boost::geometry::index::within(),
+
+    It is possible to negate spatial predicates:
+    \li <tt>! boost::geometry::index::contains()</tt>,
+    \li <tt>! boost::geometry::index::covered_by()</tt>,
+    \li <tt>! boost::geometry::index::covers()</tt>,
+    \li <tt>! boost::geometry::index::disjoint()</tt>,
+    \li <tt>! boost::geometry::index::intersects()</tt>,
+    \li <tt>! boost::geometry::index::overlaps()</tt>,
+    \li <tt>! boost::geometry::index::within()</tt>
+
+    <b>Satisfies predicate</b>
+    
+    This is a special kind of predicate which allows to pass a user-defined function or function object which checks
+    if Value should be returned by the query. It's generated by:
+    \li \c boost::geometry::index::satisfies().
+
+    <b>Nearest predicate</b>
+
+    If the nearest predicate is passed a k-nearest neighbor search will be performed. This query will result
+    in returning k values to the output iterator. Only one nearest predicate may be passed to the query.
+    It may be generated by:
+    \li \c boost::geometry::index::nearest().
+        
+    <b>Connecting predicates</b>
+
+    Predicates may be passed together connected with \c operator&&().
+
+    \par Example
+    \verbatim
+    // return elements intersecting box
+    tree.query(bgi::intersects(box), std::back_inserter(result));
+    // return elements intersecting poly but not within box
+    tree.query(bgi::intersects(poly) && !bgi::within(box), std::back_inserter(result));
+    // return elements overlapping box and meeting my_fun unary predicate
+    tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
+    // return 5 elements nearest to pt and elements are intersecting box
+    tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+    \endverbatim
+
+    \par Throws
+    If Value copy constructor or copy assignment throws.
+    If predicates copy throws.
+
+    \warning
+    Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
+    
+    \param predicates   Predicates.
+    \param out_it       The output iterator, e.g. generated by std::back_inserter().
+
+    \return             The number of values found.
+    */
+    template <typename Predicates, typename OutIter>
+    size_type query(Predicates const& predicates, OutIter out_it) const
+    {
+        if ( !m_members.root )
+            return 0;
+
+        static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
+        static const bool is_distance_predicate = 0 < distance_predicates_count;
+        BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
+
+        return query_dispatch(predicates, out_it, boost::mpl::bool_<is_distance_predicate>());
+    }
+
+    /*!
+    \brief Returns the query iterator pointing at the begin of the query range.
+
+    This method returns the iterator which may be used to perform iterative queries. For the information
+    about the predicates which may be passed to this method see query().
+    
+    \par Example
+    \verbatim    
+    for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
+          it != tree.qend() ; ++it )
+    {
+        // do something with value
+        if ( has_enough_nearest_values() )
+            break;
+    }
+    \endverbatim
+
+    \par Throws
+    If predicates copy throws.
+    If allocation throws.
+
+    \param predicates   Predicates.
+    
+    \return             The iterator pointing at the begin of the query range.
+    */
+    template <typename Predicates>
+    const_query_iterator qbegin(Predicates const& predicates) const
+    {
+        return const_query_iterator(qbegin_(predicates));
+    }
+
+    /*!
+    \brief Returns the query iterator pointing at the end of the query range.
+
+    This method returns the iterator which may be used to check if the query has ended.
+    
+    \par Example
+    \verbatim    
+    for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
+          it != tree.qend() ; ++it )
+    {
+        // do something with value
+        if ( has_enough_nearest_values() )
+            break;
+    }
+    \endverbatim
+
+    \par Throws
+    Nothing
+    
+    \return             The iterator pointing at the end of the query range.
+    */
+    const_query_iterator qend() const
+    {
+        return const_query_iterator();
+    }
+
+#ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
+private:
+#endif
+    /*!
+    \brief Returns the query iterator pointing at the begin of the query range.
+
+    This method returns the iterator which may be used to perform iterative queries. For the information
+    about the predicates which may be passed to this method see query().
+    
+    The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
+    may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
+    returned by this method you may get the type e.g. by using C++11 decltype or Boost.Typeof library.
+    This iterator may be compared with iterators returned by both versions of qend() method.
+
+    \par Example
+    \verbatim
+    // Store the result in the container using std::copy() - it requires both iterators of the same type
+    std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+
+    // Store the result in the container using std::copy() and type-erased iterators
+    Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
+    Rtree::const_query_iterator last = tree.qend();
+    std::copy(first, last, std::back_inserter(result));
+
+    // Boost.Typeof
+    typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
+    for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+    {
+        // do something with value
+        if ( has_enough_nearest_values() )
+            break;
+    }
+    \endverbatim
+
+    \par Throws
+    If predicates copy throws.
+    If allocation throws.
+
+    \param predicates   Predicates.
+    
+    \return             The iterator pointing at the begin of the query range.
+    */
+    template <typename Predicates>
+    typename boost::mpl::if_c<
+        detail::predicates_count_distance<Predicates>::value == 0,
+        detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
+        detail::rtree::iterators::distance_query_iterator<
+            value_type, options_type, translator_type, box_type, allocators_type, Predicates,
+            detail::predicates_find_distance<Predicates>::value
+        >
+    >::type
+    qbegin_(Predicates const& predicates) const
+    {
+        static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
+        BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
+
+        typedef typename boost::mpl::if_c<
+            detail::predicates_count_distance<Predicates>::value == 0,
+            detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
+            detail::rtree::iterators::distance_query_iterator<
+                value_type, options_type, translator_type, box_type, allocators_type, Predicates,
+                detail::predicates_find_distance<Predicates>::value
+            >
+        >::type iterator_type;
+
+        if ( !m_members.root )
+            return iterator_type(m_members.translator(), predicates);
+
+        return iterator_type(m_members.root, m_members.translator(), predicates);
+    }
+
+    /*!
+    \brief Returns the query iterator pointing at the end of the query range.
+
+    This method returns the iterator which may be used to perform iterative queries. For the information
+    about the predicates which may be passed to this method see query().
+    
+    The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
+    may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
+    returned by this method you may get the type e.g. by using C++11 decltype or Boost.Typeof library.
+
+    The type of the iterator returned by this method is the same as the one returned by qbegin() to which
+    the same predicates were passed.
+
+    \par Example
+    \verbatim
+    // Store the result in the container using std::copy() - it requires both iterators of the same type
+    std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
+    \endverbatim
+
+    \par Throws
+    If predicates copy throws.
+
+    \param predicates   Predicates.
+    
+    \return             The iterator pointing at the end of the query range.
+    */
+    template <typename Predicates>
+    typename boost::mpl::if_c<
+        detail::predicates_count_distance<Predicates>::value == 0,
+        detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
+        detail::rtree::iterators::distance_query_iterator<
+            value_type, options_type, translator_type, box_type, allocators_type, Predicates,
+            detail::predicates_find_distance<Predicates>::value
+        >
+    >::type
+    qend_(Predicates const& predicates) const
+    {
+        static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
+        BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
+
+        typedef typename boost::mpl::if_c<
+            detail::predicates_count_distance<Predicates>::value == 0,
+            detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
+            detail::rtree::iterators::distance_query_iterator<
+                value_type, options_type, translator_type, box_type, allocators_type, Predicates,
+                detail::predicates_find_distance<Predicates>::value
+            >
+        >::type iterator_type;
+
+        return iterator_type(m_members.translator(), predicates);
+    }
+
+    /*!
+    \brief Returns the query iterator pointing at the end of the query range.
+
+    This method returns the iterator which may be compared with the iterator returned by qbegin() in order to
+    check if the query has ended.
+    
+    The type of the returned iterator is different than the type returned by qbegin() but the iterator of this type
+    may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator returned by this
+    method, which most certainly will be faster than the type-erased iterator, you may get the type
+    e.g. by using C++11 decltype or Boost.Typeof library.
+
+    The type of the iterator returned by this method is dfferent than the type returned by qbegin().
+
+    \par Example
+    \verbatim
+    // Store the result in the container using std::copy() and type-erased iterators
+    Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
+    Rtree::const_query_iterator last = tree.qend();
+    std::copy(first, last, std::back_inserter(result));
+
+    // Boost.Typeof
+    typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
+    for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
+    {
+        // do something with value
+        if ( has_enough_nearest_values() )
+            break;
+    }
+    \endverbatim
+
+    \par Throws
+    Nothing
+    
+    \return             The iterator pointing at the end of the query range.
+    */
+    detail::rtree::iterators::end_query_iterator<value_type, allocators_type>
+    qend_() const
+    {
+        return detail::rtree::iterators::end_query_iterator<value_type, allocators_type>();
+    }
+
+public:
+
+    /*!
+    \brief Returns the number of stored values.
+
+    \return         The number of stored values.
+
+    \par Throws
+    Nothing.
+    */
+    inline size_type size() const
+    {
+        return m_members.values_count;
+    }
+
+    /*!
+    \brief Query if the container is empty.
+
+    \return         true if the container is empty.
+
+    \par Throws
+    Nothing.
+    */
+    inline bool empty() const
+    {
+        return 0 == m_members.values_count;
+    }
+
+    /*!
+    \brief Removes all values stored in the container.
+
+    \par Throws
+    Nothing.
+    */
+    inline void clear()
+    {
+        this->raw_destroy(*this);
+    }
+
+    /*!
+    \brief Returns the box able to contain all values stored in the container.
+
+    Returns the box able to contain all values stored in the container.
+    If the container is empty the result of \c geometry::assign_inverse() is returned.
+
+    \return     The box able to contain all values stored in the container or an invalid box if
+                there are no values in the container.
+
+    \par Throws
+    Nothing.
+    */
+    inline bounds_type bounds() const
+    {
+        bounds_type result;
+        if ( !m_members.root )
+        {
+            geometry::assign_inverse(result);
+            return result;
+        }
+
+        detail::rtree::visitors::children_box<value_type, options_type, translator_type, box_type, allocators_type>
+            box_v(result, m_members.translator());
+        detail::rtree::apply_visitor(box_v, *m_members.root);
+
+        return result;
+    }
+
+    /*!
+    \brief Count Values or Indexables stored in the container.
+    
+    For indexable_type it returns the number of values which indexables equals the parameter.
+    For value_type it returns the number of values which equals the parameter.
+
+    \param vori The value or indexable which will be counted.
+
+    \return     The number of values found.
+
+    \par Throws
+    Nothing.
+    */
+    template <typename ValueOrIndexable>
+    size_type count(ValueOrIndexable const& vori) const
+    {
+        if ( !m_members.root )
+            return 0;
+
+        detail::rtree::visitors::count<ValueOrIndexable, value_type, options_type, translator_type, box_type, allocators_type>
+            count_v(vori, m_members.translator());
+
+        detail::rtree::apply_visitor(count_v, *m_members.root);
+
+        return count_v.found_count;
+    }
+
+    /*!
+    \brief Returns parameters.
+
+    \return     The parameters object.
+
+    \par Throws
+    Nothing.
+    */
+    inline parameters_type parameters() const
+    {
+        return m_members.parameters();
+    }
+
+    /*!
+    \brief Returns function retrieving Indexable from Value.
+
+    \return     The indexable_getter object.
+
+    \par Throws
+    Nothing.
+    */
+    indexable_getter indexable_get() const
+    {
+        return m_members.indexable_getter();
+    }
+
+    /*!
+    \brief Returns function comparing Values
+
+    \return     The value_equal function.
+
+    \par Throws
+    Nothing.
+    */
+    value_equal value_eq() const
+    {
+        return m_members.equal_to();
+    }
+
+    /*!
+    \brief Returns allocator used by the rtree.
+
+    \return     The allocator.
+
+    \par Throws
+    If allocator copy constructor throws.
+    */
+    allocator_type get_allocator() const
+    {
+        return m_members.allocators().allocator();
+    }
+
+private:
+
+    /*!
+    \brief Returns the translator object.
+
+    \return     The translator object.
+
+    \par Throws
+    Nothing.
+    */
+    inline translator_type translator() const
+    {
+        return m_members.translator();
+    }
+
+    /*!
+    \brief Apply a visitor to the nodes structure in order to perform some operator.
+
+    This function is not a part of the 'official' interface. However it makes
+    possible e.g. to pass a visitor drawing the tree structure.
+
+    \param visitor  The visitor object.
+
+    \par Throws
+    If Visitor::operator() throws.
+    */
+    template <typename Visitor>
+    inline void apply_visitor(Visitor & visitor) const
+    {
+        if ( m_members.root )
+            detail::rtree::apply_visitor(visitor, *m_members.root);
+    }
+
+    /*!
+    \brief Returns the depth of the R-tree.
+
+    This function is not a part of the 'official' interface.
+
+    \return     The depth of the R-tree.
+
+    \par Throws
+    Nothing.
+    */
+    inline size_type depth() const
+    {
+        return m_members.leafs_level;
+    }
+
+private:
+
+    /*!
+    \pre Root node must exist - m_root != 0.
+
+    \brief Insert a value to the index.
+
+    \param value    The value which will be stored in the container.
+
+    \par Exception-safety
+    basic
+    */
+    inline void raw_insert(value_type const& value)
+    {
+        BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
+        BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid");
+
+        detail::rtree::visitors::insert<
+            value_type,
+            value_type, options_type, translator_type, box_type, allocators_type,
+            typename options_type::insert_tag
+        > insert_v(m_members.root, m_members.leafs_level, value,
+                   m_members.parameters(), m_members.translator(), m_members.allocators());
+
+        detail::rtree::apply_visitor(insert_v, *m_members.root);
+
+// TODO
+// Think about this: If exception is thrown, may the root be removed?
+// Or it is just cleared?
+
+// TODO
+// If exception is thrown, m_values_count may be invalid
+        ++m_members.values_count;
+    }
+
+    /*!
+    \brief Remove the value from the container.
+
+    \param value    The value which will be removed from the container.
+
+    \par Exception-safety
+    basic
+    */
+    inline size_type raw_remove(value_type const& value)
+    {
+        // TODO: awulkiew - assert for correct value (indexable) ?
+        BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
+
+        detail::rtree::visitors::remove<
+            value_type, options_type, translator_type, box_type, allocators_type
+        > remove_v(m_members.root, m_members.leafs_level, value,
+                   m_members.parameters(), m_members.translator(), m_members.allocators());
+
+        detail::rtree::apply_visitor(remove_v, *m_members.root);
+
+        // If exception is thrown, m_values_count may be invalid
+
+        if ( remove_v.is_value_removed() )
+        {
+            BOOST_GEOMETRY_INDEX_ASSERT(0 < m_members.values_count, "unexpected state");
+
+            --m_members.values_count;
+
+            return 1;
+        }
+
+        return 0;
+    }
+
+    /*!
+    \brief Create an empty R-tree i.e. new empty root node and clear other attributes.
+
+    \par Exception-safety
+    strong
+    */
+    inline void raw_create()
+    {
+        BOOST_GEOMETRY_INDEX_ASSERT(0 == m_members.root, "the tree is already created");
+
+        m_members.root = detail::rtree::create_node<allocators_type, leaf>::apply(m_members.allocators()); // MAY THROW (N: alloc)
+        m_members.values_count = 0;
+        m_members.leafs_level = 0;
+    }
+
+    /*!
+    \brief Destroy the R-tree i.e. all nodes and clear attributes.
+
+    \param t    The container which is going to be destroyed.
+
+    \par Exception-safety
+    nothrow
+    */
+    inline void raw_destroy(rtree & t)
+    {
+        if ( t.m_members.root )
+        {
+            detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
+                del_v(t.m_members.root, t.m_members.allocators());
+            detail::rtree::apply_visitor(del_v, *t.m_members.root);
+
+            t.m_members.root = 0;
+        }
+        t.m_members.values_count = 0;
+        t.m_members.leafs_level = 0;
+    }
+
+    /*!
+    \brief Copy the R-tree i.e. whole nodes structure, values and other attributes.
+    It uses destination's allocators to create the new structure.
+
+    \param src                  The source R-tree.
+    \param dst                  The destination R-tree.
+    \param copy_tr_and_params   If true, translator and parameters will also be copied.
+
+    \par Exception-safety
+    strong
+    */
+    inline void raw_copy(rtree const& src, rtree & dst, bool copy_tr_and_params) const
+    {
+        detail::rtree::visitors::copy<value_type, options_type, translator_type, box_type, allocators_type>
+            copy_v(dst.m_members.allocators());
+
+        if ( src.m_members.root )
+            detail::rtree::apply_visitor(copy_v, *src.m_members.root);                      // MAY THROW (V, E: alloc, copy, N: alloc)
+
+        if ( copy_tr_and_params )
+        {
+            dst.m_members.indexable_getter() = src.m_members.indexable_getter();
+            dst.m_members.equal_to() = src.m_members.equal_to();
+            dst.m_members.parameters() = src.m_members.parameters();
+        }
+
+        // TODO use node_auto_ptr
+        if ( dst.m_members.root )
+        {
+            detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
+                del_v(dst.m_members.root, dst.m_members.allocators());
+            detail::rtree::apply_visitor(del_v, *dst.m_members.root);
+            dst.m_members.root = 0;
+        }
+
+        dst.m_members.root = copy_v.result;
+        dst.m_members.values_count = src.m_members.values_count;
+        dst.m_members.leafs_level = src.m_members.leafs_level;
+    }
+
+    /*!
+    \brief Return values meeting predicates.
+
+    \par Exception-safety
+    strong
+    */
+    template <typename Predicates, typename OutIter>
+    size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> const& /*is_distance_predicate*/) const
+    {
+        detail::rtree::visitors::spatial_query<value_type, options_type, translator_type, box_type, allocators_type, Predicates, OutIter>
+            find_v(m_members.translator(), predicates, out_it);
+
+        detail::rtree::apply_visitor(find_v, *m_members.root);
+
+        return find_v.found_count;
+    }
+
+    /*!
+    \brief Perform nearest neighbour search.
+
+    \par Exception-safety
+    strong
+    */
+    template <typename Predicates, typename OutIter>
+    size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_distance_predicate*/) const
+    {
+        static const unsigned distance_predicate_index = detail::predicates_find_distance<Predicates>::value;
+        detail::rtree::visitors::distance_query<
+            value_type,
+            options_type,
+            translator_type,
+            box_type,
+            allocators_type,
+            Predicates,
+            distance_predicate_index,
+            OutIter
+        > distance_v(m_members.parameters(), m_members.translator(), predicates, out_it);
+
+        detail::rtree::apply_visitor(distance_v, *m_members.root);
+
+        return distance_v.finish();
+    }
+
+    struct members_holder
+        : public translator_type
+        , public Parameters
+        , public allocators_type
+    {
+    private:
+        members_holder(members_holder const&);
+        members_holder & operator=(members_holder const&);
+
+    public:
+        template <typename IndGet, typename ValEq, typename Alloc>
+        members_holder(IndGet const& ind_get,
+                       ValEq const& val_eq,
+                       Parameters const& parameters,
+                       BOOST_FWD_REF(Alloc) alloc)
+            : translator_type(ind_get, val_eq)
+            , Parameters(parameters)
+            , allocators_type(boost::forward<Alloc>(alloc))
+            , values_count(0)
+            , leafs_level(0)
+            , root(0)
+        {}
+
+        template <typename IndGet, typename ValEq>
+        members_holder(IndGet const& ind_get,
+                       ValEq const& val_eq,
+                       Parameters const& parameters)
+            : translator_type(ind_get, val_eq)
+            , Parameters(parameters)
+            , allocators_type()
+            , values_count(0)
+            , leafs_level(0)
+            , root(0)
+        {}
+
+        translator_type const& translator() const { return *this; }
+
+        IndexableGetter const& indexable_getter() const { return *this; }
+        IndexableGetter & indexable_getter() { return *this; }
+        EqualTo const& equal_to() const { return *this; }
+        EqualTo & equal_to() { return *this; }
+        Parameters const& parameters() const { return *this; }
+        Parameters & parameters() { return *this; }
+        allocators_type const& allocators() const { return *this; }
+        allocators_type & allocators() { return *this; }
+
+        size_type values_count;
+        size_type leafs_level;
+        node_pointer root;
+    };
+
+    members_holder m_members;
+};
+
+/*!
+\brief Insert a value to the index.
+
+It calls <tt>rtree::insert(value_type const&)</tt>.
+
+\ingroup rtree_functions
+
+\param tree The spatial index.
+\param v    The value which will be stored in the index.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
+{
+    tree.insert(v);
+}
+
+/*!
+\brief Insert a range of values to the index.
+
+It calls <tt>rtree::insert(Iterator, Iterator)</tt>.
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+\param first    The beginning of the range of values.
+\param last     The end of the range of values.
+*/
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
+inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
+{
+    tree.insert(first, last);
+}
+
+/*!
+\brief Insert a range of values to the index.
+
+It calls <tt>rtree::insert(Range const&)</tt>.
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+\param rng      The range of values.
+*/
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
+inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
+{
+    tree.insert(rng);
+}
+
+/*!
+\brief Remove a value from the container.
+
+Remove a value from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
+this function removes only one value from the container.
+
+It calls <tt>rtree::remove(value_type const&)</tt>.
+
+\ingroup rtree_functions
+
+\param tree The spatial index.
+\param v    The value which will be removed from the index.
+
+\return     1 if value was removed, 0 otherwise.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
+remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Value const& v)
+{
+    return tree.remove(v);
+}
+
+/*!
+\brief Remove a range of values from the container.
+
+Remove a range of values from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
+it doesn't take iterators pointing to values stored in this container. It removes values equal
+to these passed as a range. Furthermore this function removes only one value for each one passed
+in the range, not all equal values.
+
+It calls <tt>rtree::remove(Iterator, Iterator)</tt>.
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+\param first    The beginning of the range of values.
+\param last     The end of the range of values.
+
+\return         The number of removed values.
+*/
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Iterator>
+inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
+remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Iterator first, Iterator last)
+{
+    return tree.remove(first, last);
+}
+
+/*!
+\brief Remove a range of values from the container.
+
+Remove a range of values from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
+it removes values equal to these passed as a range. Furthermore this method removes only
+one value for each one passed in the range, not all equal values.
+
+It calls <tt>rtree::remove(Range const&)</tt>.
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+\param rng      The range of values.
+
+\return         The number of removed values.
+*/
+template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator, typename Range>
+inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
+remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree, Range const& rng)
+{
+    return tree.remove(rng);
+}
+
+/*!
+\brief Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box.
+
+This query function performs spatial and k-nearest neighbor searches. It allows to pass a set of predicates.
+Values will be returned only if all predicates are met.
+
+<b>Spatial predicates</b>
+    
+Spatial predicates may be generated by one of the functions listed below:
+\li \c boost::geometry::index::contains(),
+\li \c boost::geometry::index::covered_by(),
+\li \c boost::geometry::index::covers(),
+\li \c boost::geometry::index::disjoint(),
+\li \c boost::geometry::index::intersects(),
+\li \c boost::geometry::index::overlaps(),
+\li \c boost::geometry::index::within(),
+
+It is possible to negate spatial predicates:
+\li <tt>! boost::geometry::index::contains()</tt>,
+\li <tt>! boost::geometry::index::covered_by()</tt>,
+\li <tt>! boost::geometry::index::covers()</tt>,
+\li <tt>! boost::geometry::index::disjoint()</tt>,
+\li <tt>! boost::geometry::index::intersects()</tt>,
+\li <tt>! boost::geometry::index::overlaps()</tt>,
+\li <tt>! boost::geometry::index::within()</tt>
+
+<b>Satisfies predicate</b>
+
+This is a special kind of predicate which allows to pass a user-defined function or function object which checks
+if Value should be returned by the query. It's generated by:
+\li \c boost::geometry::index::satisfies().
+
+<b>Nearest predicate</b>
+
+If the nearest predicate is passed a k-nearest neighbor search will be performed. This query will result
+in returning k values to the output iterator. Only one nearest predicate may be passed to the query.
+It may be generated by:
+\li \c boost::geometry::index::nearest().
+        
+<b>Connecting predicates</b>
+
+Predicates may be passed together connected with \c operator&&().
+
+\par Example
+\verbatim
+// return elements intersecting box
+bgi::query(tree, bgi::intersects(box), std::back_inserter(result));
+// return elements intersecting poly but not within box
+bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(result));
+// return elements overlapping box and meeting my_fun value predicate
+bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
+// return 5 elements nearest to pt and elements are intersecting box
+bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
+\endverbatim
+
+\par Throws
+If Value copy constructor or copy assignment throws.
+
+\warning
+Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
+
+\ingroup rtree_functions
+
+\param tree         The rtree.
+\param predicates   Predicates.
+\param out_it       The output iterator, e.g. generated by std::back_inserter().
+
+\return             The number of values found.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
+          typename Predicates, typename OutIter> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
+query(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
+      Predicates const& predicates,
+      OutIter out_it)
+{
+    return tree.query(predicates, out_it);
+}
+
+/*!
+\brief Returns the query iterator pointing at the begin of the query range.
+
+This method returns the iterator which may be used to perform iterative queries. For the information
+about the predicates which may be passed to this method see query().
+    
+\par Example
+\verbatim
+    
+for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
+        it != qend(tree) ; ++it )
+{
+    // do something with value
+    if ( has_enough_nearest_values() )
+        break;
+}
+\endverbatim
+
+\par Throws
+If predicates copy throws.
+If allocation throws.
+
+\ingroup rtree_functions
+
+\param tree         The rtree.
+\param predicates   Predicates.
+    
+\return             The iterator pointing at the begin of the query range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
+          typename Predicates> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
+qbegin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
+       Predicates const& predicates)
+{
+    return tree.qbegin(predicates);
+}
+
+/*!
+\brief Returns the query iterator pointing at the end of the query range.
+
+This method returns the iterator which may be used to check if the query has ended.
+    
+\par Example
+\verbatim
+    
+for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
+      it != qend(tree) ; ++it )
+{
+    // do something with value
+    if ( has_enough_nearest_values() )
+        break;
+}
+\endverbatim
+
+\par Throws
+Nothing
+
+\ingroup rtree_functions
+    
+\return             The iterator pointing at the end of the query range.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
+typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
+qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+    return tree.qend();
+}
+
+/*!
+\brief Remove all values from the index.
+
+It calls \c rtree::clear().
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline void clear(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree)
+{
+    return tree.clear();
+}
+
+/*!
+\brief Get the number of values stored in the index.
+
+It calls \c rtree::size().
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+
+\return         The number of values stored in the index.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline size_t size(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+    return tree.size();
+}
+
+/*!
+\brief Query if there are no values stored in the index.
+
+It calls \c rtree::empty().
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+
+\return         true if there are no values in the index.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline bool empty(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+    return tree.bounds();
+}
+
+/*!
+\brief Get the box containing all stored values or an invalid box if the index has no values.
+
+It calls \c rtree::envelope().
+
+\ingroup rtree_functions
+
+\param tree     The spatial index.
+
+\return         The box containing all stored values or an invalid box.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::bounds_type
+bounds(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
+{
+    return tree.bounds();
+}
+
+/*!
+\brief Exchanges the contents of the container with those of other.
+
+It calls \c rtree::swap().
+
+\ingroup rtree_functions
+
+\param l     The first rtree.
+\param r     The second rtree.
+*/
+template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
+inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & l,
+                 rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & r)
+{
+    return l.swap(r);
+}
+
+}}} // namespace boost::geometry::index
+
+#include <boost/geometry/index/detail/config_end.hpp>
+
+#endif // BOOST_GEOMETRY_INDEX_RTREE_HPP