| // Boost.Geometry Index |
| // |
| // Throwing objects implementation |
| // |
| // Copyright (c) 2011-2014 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_THROWING_HPP |
| #define BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP |
| |
| // value |
| |
| struct throwing_value_copy_exception : public std::exception |
| { |
| const char * what() const throw() { return "value copy failed."; } |
| }; |
| |
| struct throwing_value |
| { |
| explicit throwing_value(int v = 0) |
| : value(v) |
| {} |
| |
| bool operator==(throwing_value const& v) const |
| { |
| return value == v.value; |
| } |
| |
| throwing_value(throwing_value const& v) |
| { |
| throw_if_required(); |
| |
| value = v.value; |
| } |
| |
| throwing_value & operator=(throwing_value const& v) |
| { |
| throw_if_required(); |
| |
| value = v.value; |
| return *this; |
| } |
| |
| void throw_if_required() |
| { |
| // throw if counter meets max count |
| if ( get_max_calls_ref() <= get_calls_counter_ref() ) |
| throw throwing_value_copy_exception(); |
| else |
| ++get_calls_counter_ref(); |
| } |
| |
| static void reset_calls_counter() { get_calls_counter_ref() = 0; } |
| static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; } |
| |
| static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; } |
| static size_t & get_max_calls_ref() { static size_t mc = (std::numeric_limits<size_t>::max)(); return mc; } |
| |
| int value; |
| }; |
| |
| namespace generate { |
| template <typename T, typename C> |
| struct value< std::pair<bg::model::point<T, 2, C>, throwing_value> > |
| { |
| typedef bg::model::point<T, 2, C> P; |
| typedef std::pair<P, throwing_value> R; |
| static R apply(int x, int y) |
| { |
| return std::make_pair(P(x, y), throwing_value(x + y * 100)); |
| } |
| }; |
| } // namespace generate |
| |
| #include <boost/geometry/index/detail/varray.hpp> |
| |
| struct throwing_varray_exception : public std::exception |
| { |
| const char * what() const throw() { return "static vector exception."; } |
| }; |
| |
| struct throwing_varray_settings |
| { |
| static void throw_if_required() |
| { |
| // throw if counter meets max count |
| if ( get_max_calls_ref() <= get_calls_counter_ref() ) |
| throw throwing_varray_exception(); |
| else |
| ++get_calls_counter_ref(); |
| } |
| |
| static void reset_calls_counter() { get_calls_counter_ref() = 0; } |
| static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; } |
| |
| static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; } |
| static size_t & get_max_calls_ref() { static size_t mc = (std::numeric_limits<size_t>::max)(); return mc; } |
| }; |
| |
| template <typename Element, size_t Capacity> |
| class throwing_varray |
| : public boost::geometry::index::detail::varray<Element, Capacity> |
| { |
| typedef boost::geometry::index::detail::varray<Element, Capacity> container; |
| |
| public: |
| typedef typename container::value_type value_type; |
| typedef typename container::size_type size_type; |
| typedef typename container::iterator iterator; |
| typedef typename container::const_iterator const_iterator; |
| typedef typename container::reverse_iterator reverse_iterator; |
| typedef typename container::const_reverse_iterator const_reverse_iterator; |
| typedef typename container::reference reference; |
| typedef typename container::const_reference const_reference; |
| |
| inline throwing_varray() {} |
| |
| template <typename It> |
| inline throwing_varray(It first, It last) |
| : container(first, last) |
| {} |
| |
| inline void resize(size_type s) |
| { |
| throwing_varray_settings::throw_if_required(); |
| 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(); |
| container::push_back(v); |
| } |
| }; |
| |
| // elements derived type trait |
| |
| namespace boost { namespace geometry { namespace index { |
| |
| namespace detail { namespace rtree { |
| |
| template <typename OldValue, size_t N, typename NewValue> |
| struct container_from_elements_type<throwing_varray<OldValue, N>, NewValue> |
| { |
| typedef throwing_varray<NewValue, N> type; |
| }; |
| |
| }} // namespace detail::rtree |
| |
| }}} // namespace boost::geometry::index |
| |
| #endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP |