test_throwing.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #ifndef BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP
  11. #define BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP
  12. // value
  13. struct throwing_value_copy_exception : public std::exception
  14. {
  15. const char * what() const throw() { return "value copy failed."; }
  16. };
  17. struct throwing_value
  18. {
  19. explicit throwing_value(int v = 0)
  20. : value(v)
  21. {}
  22. bool operator==(throwing_value const& v) const
  23. {
  24. return value == v.value;
  25. }
  26. throwing_value(throwing_value const& v)
  27. {
  28. throw_if_required();
  29. value = v.value;
  30. }
  31. throwing_value & operator=(throwing_value const& v)
  32. {
  33. throw_if_required();
  34. value = v.value;
  35. return *this;
  36. }
  37. void throw_if_required()
  38. {
  39. // throw if counter meets max count
  40. if ( get_max_calls_ref() <= get_calls_counter_ref() )
  41. throw throwing_value_copy_exception();
  42. else
  43. ++get_calls_counter_ref();
  44. }
  45. static void reset_calls_counter() { get_calls_counter_ref() = 0; }
  46. static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; }
  47. static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; }
  48. static size_t & get_max_calls_ref() { static size_t mc = (std::numeric_limits<size_t>::max)(); return mc; }
  49. int value;
  50. };
  51. namespace generate {
  52. template <typename T, typename C>
  53. struct value< std::pair<bg::model::point<T, 2, C>, throwing_value> >
  54. {
  55. typedef bg::model::point<T, 2, C> P;
  56. typedef std::pair<P, throwing_value> R;
  57. static R apply(int x, int y)
  58. {
  59. return std::make_pair(P(x, y), throwing_value(x + y * 100));
  60. }
  61. };
  62. } // namespace generate
  63. #include <boost/geometry/index/detail/varray.hpp>
  64. struct throwing_varray_exception : public std::exception
  65. {
  66. const char * what() const throw() { return "static vector exception."; }
  67. };
  68. struct throwing_varray_settings
  69. {
  70. static void throw_if_required()
  71. {
  72. // throw if counter meets max count
  73. if ( get_max_calls_ref() <= get_calls_counter_ref() )
  74. throw throwing_varray_exception();
  75. else
  76. ++get_calls_counter_ref();
  77. }
  78. static void reset_calls_counter() { get_calls_counter_ref() = 0; }
  79. static void set_max_calls(size_t mc) { get_max_calls_ref() = mc; }
  80. static size_t & get_calls_counter_ref() { static size_t cc = 0; return cc; }
  81. static size_t & get_max_calls_ref() { static size_t mc = (std::numeric_limits<size_t>::max)(); return mc; }
  82. };
  83. template <typename Element, size_t Capacity>
  84. class throwing_varray
  85. : public boost::geometry::index::detail::varray<Element, Capacity>
  86. {
  87. typedef boost::geometry::index::detail::varray<Element, Capacity> container;
  88. public:
  89. typedef typename container::value_type value_type;
  90. typedef typename container::size_type size_type;
  91. typedef typename container::iterator iterator;
  92. typedef typename container::const_iterator const_iterator;
  93. typedef typename container::reverse_iterator reverse_iterator;
  94. typedef typename container::const_reverse_iterator const_reverse_iterator;
  95. typedef typename container::reference reference;
  96. typedef typename container::const_reference const_reference;
  97. inline throwing_varray() {}
  98. template <typename It>
  99. inline throwing_varray(It first, It last)
  100. : container(first, last)
  101. {}
  102. inline throwing_varray(size_type s)
  103. {
  104. throwing_varray_settings::throw_if_required();
  105. container::resize(s);
  106. }
  107. inline void resize(size_type s)
  108. {
  109. throwing_varray_settings::throw_if_required();
  110. container::resize(s);
  111. }
  112. inline void reserve(size_type s)
  113. {
  114. throwing_varray_settings::throw_if_required();
  115. container::reserve(s);
  116. }
  117. void push_back(Element const& v)
  118. {
  119. throwing_varray_settings::throw_if_required();
  120. container::push_back(v);
  121. }
  122. };
  123. // elements derived type trait
  124. namespace boost { namespace geometry { namespace index {
  125. namespace detail { namespace rtree {
  126. template <typename OldValue, size_t N, typename NewValue>
  127. struct container_from_elements_type<throwing_varray<OldValue, N>, NewValue>
  128. {
  129. typedef throwing_varray<NewValue, N> type;
  130. };
  131. }} // namespace detail::rtree
  132. }}} // namespace boost::geometry::index
  133. #endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP