1 // Boost.Geometry Index 2 // 3 // Throwing objects implementation 4 // 5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. 6 // 7 // Use, modification and distribution is subject to the Boost Software License, 8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 #ifndef BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP 12 #define BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP 13 14 // value 15 16 struct throwing_value_copy_exception : public std::exception 17 { whatthrowing_value_copy_exception18 const char * what() const throw() { return "value copy failed."; } 19 }; 20 21 struct throwing_value 22 { throwing_valuethrowing_value23 explicit throwing_value(int v = 0) 24 : value(v) 25 {} 26 operator ==throwing_value27 bool operator==(throwing_value const& v) const 28 { 29 return value == v.value; 30 } 31 throwing_valuethrowing_value32 throwing_value(throwing_value const& v) 33 { 34 throw_if_required(); 35 36 value = v.value; 37 } 38 operator =throwing_value39 throwing_value & operator=(throwing_value const& v) 40 { 41 throw_if_required(); 42 43 value = v.value; 44 return *this; 45 } 46 throw_if_requiredthrowing_value47 void throw_if_required() 48 { 49 // throw if counter meets max count 50 if ( get_max_calls_ref() <= get_calls_counter_ref() ) 51 throw throwing_value_copy_exception(); 52 else 53 ++get_calls_counter_ref(); 54 } 55 reset_calls_counterthrowing_value56 static void reset_calls_counter() { get_calls_counter_ref() = 0; } set_max_callsthrowing_value57 static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; } 58 get_calls_counter_refthrowing_value59 static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; } get_max_calls_refthrowing_value60 static size_t & get_max_calls_ref() { static size_t mc = (std::numeric_limits<size_t>::max)(); return mc; } 61 62 int value; 63 }; 64 65 namespace generate { 66 template <typename T, typename C> 67 struct value< std::pair<bg::model::point<T, 2, C>, throwing_value> > 68 { 69 typedef bg::model::point<T, 2, C> P; 70 typedef std::pair<P, throwing_value> R; applygenerate::value71 static R apply(int x, int y) 72 { 73 return std::make_pair(P(x, y), throwing_value(x + y * 100)); 74 } 75 }; 76 } // namespace generate 77 78 #include <boost/geometry/index/detail/varray.hpp> 79 80 struct throwing_varray_exception : public std::exception 81 { whatthrowing_varray_exception82 const char * what() const throw() { return "static vector exception."; } 83 }; 84 85 struct throwing_varray_settings 86 { throw_if_requiredthrowing_varray_settings87 static void throw_if_required() 88 { 89 // throw if counter meets max count 90 if ( get_max_calls_ref() <= get_calls_counter_ref() ) 91 throw throwing_varray_exception(); 92 else 93 ++get_calls_counter_ref(); 94 } 95 reset_calls_counterthrowing_varray_settings96 static void reset_calls_counter() { get_calls_counter_ref() = 0; } set_max_callsthrowing_varray_settings97 static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; } 98 get_calls_counter_refthrowing_varray_settings99 static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; } get_max_calls_refthrowing_varray_settings100 static size_t & get_max_calls_ref() { static size_t mc = (std::numeric_limits<size_t>::max)(); return mc; } 101 }; 102 103 template <typename Element, size_t Capacity> 104 class throwing_varray 105 : public boost::geometry::index::detail::varray<Element, Capacity> 106 { 107 typedef boost::geometry::index::detail::varray<Element, Capacity> container; 108 109 public: 110 typedef typename container::value_type value_type; 111 typedef typename container::size_type size_type; 112 typedef typename container::iterator iterator; 113 typedef typename container::const_iterator const_iterator; 114 typedef typename container::reverse_iterator reverse_iterator; 115 typedef typename container::const_reverse_iterator const_reverse_iterator; 116 typedef typename container::reference reference; 117 typedef typename container::const_reference const_reference; 118 throwing_varray()119 inline throwing_varray() {} 120 121 template <typename It> throwing_varray(It first,It last)122 inline throwing_varray(It first, It last) 123 : container(first, last) 124 {} 125 throwing_varray(size_type s)126 inline throwing_varray(size_type s) 127 { 128 throwing_varray_settings::throw_if_required(); 129 container::resize(s); 130 } 131 resize(size_type s)132 inline void resize(size_type s) 133 { 134 throwing_varray_settings::throw_if_required(); 135 container::resize(s); 136 } 137 reserve(size_type s)138 inline void reserve(size_type s) 139 { 140 throwing_varray_settings::throw_if_required(); 141 container::reserve(s); 142 } 143 push_back(Element const & v)144 void push_back(Element const& v) 145 { 146 throwing_varray_settings::throw_if_required(); 147 container::push_back(v); 148 } 149 }; 150 151 // elements derived type trait 152 153 namespace boost { namespace geometry { namespace index { 154 155 namespace detail { namespace rtree { 156 157 template <typename OldValue, size_t N, typename NewValue> 158 struct container_from_elements_type<throwing_varray<OldValue, N>, NewValue> 159 { 160 typedef throwing_varray<NewValue, N> type; 161 }; 162 163 }} // namespace detail::rtree 164 165 }}} // namespace boost::geometry::index 166 167 #endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP 168