Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / geometry / index / test / rtree / exceptions / test_throwing.hpp
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 {
18     const char * what() const throw() { return "value copy failed."; }
19 };
20
21 struct throwing_value
22 {
23     explicit throwing_value(int v = 0)
24         : value(v)
25     {}
26
27     bool operator==(throwing_value const& v) const
28     {
29         return value == v.value;
30     }
31
32     throwing_value(throwing_value const& v)
33     {
34         throw_if_required();
35
36         value = v.value;
37     }
38
39     throwing_value & operator=(throwing_value const& v)
40     {
41         throw_if_required();
42
43         value = v.value;
44         return *this;
45     }
46
47     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
56     static void reset_calls_counter() { get_calls_counter_ref() = 0; }
57     static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; }
58
59     static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; }
60     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;
71     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 {
82     const char * what() const throw() { return "static vector exception."; }
83 };
84
85 struct throwing_varray_settings
86 {
87     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
96     static void reset_calls_counter() { get_calls_counter_ref() = 0; }
97     static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; }
98
99     static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; }
100     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
119     inline throwing_varray() {}
120
121     template <typename It>
122     inline throwing_varray(It first, It last)
123         : container(first, last)
124     {}
125
126     inline void resize(size_type s)
127     {
128         throwing_varray_settings::throw_if_required();
129         container::resize(s);
130     }
131
132     inline void reserve(size_type s)
133     {
134         throwing_varray_settings::throw_if_required();
135         container::reserve(s);
136     }
137
138     void push_back(Element const& v)
139     {
140         throwing_varray_settings::throw_if_required();
141         container::push_back(v);
142     }
143 };
144
145 // elements derived type trait
146
147 namespace boost { namespace geometry { namespace index {
148
149 namespace detail { namespace rtree {
150
151 template <typename OldValue, size_t N, typename NewValue>
152 struct container_from_elements_type<throwing_varray<OldValue, N>, NewValue>
153 {
154     typedef throwing_varray<NewValue, N> type;
155 };
156
157 }} // namespace detail::rtree
158
159 }}} // namespace boost::geometry::index
160
161 #endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP