diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index de44f08d7..bba0bc35e 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -297,7 +297,7 @@ struct buffered_piece_collection { typename buffer_occupation_info::turn_vector_type const& turns = it->second.turns; bool blocked = false; - for (int i = 0; i < turns.size(); i++) + for (std::size_t i = 0; i < turns.size(); i++) { if (m_turns[turns[i].turn_index].blocked()) { @@ -307,7 +307,7 @@ struct buffered_piece_collection } if (blocked) { - for (int i = 0; i < turns.size(); i++) + for (std::size_t i = 0; i < turns.size(); i++) { m_turns[turns[i].turn_index].count_on_occupied++; } @@ -320,7 +320,7 @@ struct buffered_piece_collection it != occupation_map.end(); ++it) { typename buffer_occupation_info::turn_vector_type const& turns = it->second.turns; - for (int i = 0; i < turns.size(); i++) + for (std::size_t i = 0; i < turns.size(); i++) { m_turns[turns[i].turn_index].selectable_start = false; } diff --git a/include/boost/geometry/algorithms/detail/occupation_info.hpp b/include/boost/geometry/algorithms/detail/occupation_info.hpp index dd42519b4..92c07006f 100644 --- a/include/boost/geometry/algorithms/detail/occupation_info.hpp +++ b/include/boost/geometry/algorithms/detail/occupation_info.hpp @@ -132,8 +132,8 @@ template inline void move_index(Pieces const& pieces, int& index, int& piece_index, int direction) { BOOST_ASSERT(direction == 1 || direction == -1); - BOOST_ASSERT(piece_index >= 0 && piece_index < boost::size(pieces)); - BOOST_ASSERT(index >= 0 && index < boost::size(pieces[piece_index].robust_ring)); + BOOST_ASSERT(piece_index >= 0 && piece_index < static_cast(boost::size(pieces)) ); + BOOST_ASSERT(index >= 0 && index < static_cast(boost::size(pieces[piece_index].robust_ring))); index += direction; if (direction == -1 && index < 0) @@ -145,10 +145,11 @@ inline void move_index(Pieces const& pieces, int& index, int& piece_index, int d } index = boost::size(pieces[piece_index].robust_ring) - 1; } - if (direction == 1 && index >= boost::size(pieces[piece_index].robust_ring)) + if (direction == 1 + && index >= static_cast(boost::size(pieces[piece_index].robust_ring))) { piece_index++; - if (piece_index >= boost::size(pieces)) + if (piece_index >= static_cast(boost::size(pieces))) { piece_index = 0; } diff --git a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp index f7d48fa95..d44db17ad 100644 --- a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -15,6 +20,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -108,7 +115,11 @@ inline void clean_closing_dups_and_spikes(Range& range, } typedef typename boost::range_iterator::type iterator_type; - const bool closed = geometry::closure::value == geometry::closed; + static bool const closed = geometry::closure::value == geometry::closed; + +// TODO: the following algorithm could be rewritten to first look for spikes +// and then erase some number of points from the beginning of the Range + bool found = false; do { @@ -125,13 +136,13 @@ inline void clean_closing_dups_and_spikes(Range& range, // considered as a spike w.r.t. the last segment) if (point_is_spike_or_equal(*second, *ultimate, *first, robust_policy)) { - range.erase(first); + range::erase(range, first); if (closed) { // Remove closing last point - traits::resize::apply(range, boost::size(range) - 1); + range::resize(range, boost::size(range) - 1); // Add new closing point - traits::push_back::apply(range, *boost::begin(range)); + range::push_back(range, range::front(range)); } found = true; } diff --git a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp index 9c984f0b8..9f4dd218d 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #ifdef BOOST_GEOMETRY_DEBUG_ENRICH # include @@ -77,6 +76,7 @@ template typename TurnPoints, typename Indexed, typename Geometry1, typename Geometry2, + typename RobustPolicy, bool Reverse1, bool Reverse2, typename Strategy > @@ -85,11 +85,13 @@ struct sort_on_segment_and_ratio inline sort_on_segment_and_ratio(TurnPoints const& turn_points , Geometry1 const& geometry1 , Geometry2 const& geometry2 + , RobustPolicy const& robust_policy , Strategy const& strategy , bool* clustered) : m_turn_points(turn_points) , m_geometry1(geometry1) , m_geometry2(geometry2) + , m_robust_policy(robust_policy) , m_strategy(strategy) , m_clustered(clustered) { @@ -100,25 +102,26 @@ private : TurnPoints const& m_turn_points; Geometry1 const& m_geometry1; Geometry2 const& m_geometry2; + RobustPolicy const& m_robust_policy; Strategy const& m_strategy; mutable bool* m_clustered; - typedef model::point - < - typename detail::robust_type - < - typename select_coordinate_type::type - >::type, - geometry::dimension::value, - typename geometry::coordinate_system::type - > robust_point_type; + typedef typename geometry::point_type::type point_type; + typedef typename geometry::robust_point_type + < + point_type, + RobustPolicy + >::type robust_point_type; + // TODO: this function is shared with handle_tangencies + // The one in handle_tangencies will go as soon as we have + // reliable "cluster_info" (using occupation_map, get_left_turns) inline void get_situation_map(Indexed const& left, Indexed const& right, robust_point_type& pi_rob, robust_point_type& pj_rob, robust_point_type& ri_rob, robust_point_type& rj_rob, robust_point_type& si_rob, robust_point_type& sj_rob) const { - typename geometry::point_type::type pi, pj, ri, rj, si, sj; + point_type pi, pj, ri, rj, si, sj; geometry::copy_segment_points(m_geometry1, m_geometry2, left.subject.seg_id, @@ -129,8 +132,13 @@ private : geometry::copy_segment_points(m_geometry1, m_geometry2, right.subject.other_id, si, sj); - detail::zoom_to_robust(pi, pj, ri, rj, si, sj, - pi_rob, pj_rob, ri_rob, rj_rob, si_rob, sj_rob); + + geometry::recalculate(pi_rob, pi, m_robust_policy); + geometry::recalculate(pj_rob, pj, m_robust_policy); + geometry::recalculate(ri_rob, ri, m_robust_policy); + geometry::recalculate(rj_rob, rj, m_robust_policy); + geometry::recalculate(si_rob, si, m_robust_policy); + geometry::recalculate(sj_rob, sj, m_robust_policy); } inline bool consider_relative_order(Indexed const& left, @@ -162,6 +170,9 @@ public : { // First check "real" intersection (crosses) // -> distance zero due to precision, solve it by sorting + // TODO: reconsider this. Using integer maths, this will + // ALWAYS return 0 because either fractions are different, or + // the (currently calculated) relative-order is identical if (m_turn_points[left.index].method == method_crosses && m_turn_points[right.index].method == method_crosses) { @@ -171,8 +182,6 @@ public : // If that is not the case, cluster it later on. // Indicate that this is necessary. *m_clustered = true; - - return left.subject.fraction < right.subject.fraction; } } return sl == sr @@ -235,9 +244,10 @@ inline void enrich_sort(Container& operations, TurnPoints, IndexType, Geometry1, Geometry2, + RobustPolicy, Reverse1, Reverse2, Strategy - >(turn_points, geometry1, geometry2, strategy, &clustered)); + >(turn_points, geometry1, geometry2, robust_policy, strategy, &clustered)); // DONT'T discard xx / (for union) ix / ii / (for intersection) ux / uu here // It would give way to "lonely" ui turn points, traveling all diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp index 92d162032..9bb828498 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_tangencies.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #if defined(BOOST_GEOMETRY_DEBUG_HANDLE_TANGENCIES) #include @@ -71,16 +70,13 @@ private : typedef typename Indexed::type turn_operation_type; typedef typename geometry::point_type::type point_type; - typedef model::point + typedef typename geometry::robust_point_type < - typename detail::robust_type - < - typename select_coordinate_type::type - >::type, - geometry::dimension::value, - typename geometry::coordinate_system::type - > robust_point_type; + point_type, + RobustPolicy + >::type robust_point_type; + // TODO: this function is shared with enrich_intersection_points // Still called by #case_102_multi, #case_107_multi // #case_recursive_boxes_3 inline void get_situation_map(Indexed const& left, Indexed const& right, @@ -88,7 +84,6 @@ private : robust_point_type& ri_rob, robust_point_type& rj_rob, robust_point_type& si_rob, robust_point_type& sj_rob) const { - typedef typename geometry::point_type::type point_type; point_type pi, pj, ri, rj, si, sj; geometry::copy_segment_points(m_geometry1, m_geometry2, diff --git a/include/boost/geometry/algorithms/detail/zoom_to_robust.hpp b/include/boost/geometry/algorithms/detail/zoom_to_robust.hpp deleted file mode 100644 index ac78a200b..000000000 --- a/include/boost/geometry/algorithms/detail/zoom_to_robust.hpp +++ /dev/null @@ -1,180 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2013 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2013 Bruno Lalande, Paris, France. -// Copyright (c) 2013 Mateusz Loskot, London, UK. -// Copyright (c) 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_ALGORITHMS_DETAIL_ZOOM_TO_ROBUST_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ZOOM_TO_ROBUST_HPP - - -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -namespace boost { namespace geometry -{ - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - - -template -struct zoom_to_robust -{ - template - < - typename Geometry1, typename Geometry2, typename Geometry3, - typename Geometry4, typename Geometry5, typename Geometry6, - typename GeometryOut - > - static inline void apply(Geometry1 const& g1, Geometry2 const& g2, Geometry3 const& g3, - Geometry4 const& g4, Geometry5 const& g5, Geometry6 const& g6, - GeometryOut& og1, GeometryOut& og2, GeometryOut& og3, - GeometryOut& og4, GeometryOut& og5, GeometryOut& og6) - { - // By default, just convert these geometries (until now: points or maybe segments) - geometry::convert(g1, og1); - geometry::convert(g2, og2); - geometry::convert(g3, og3); - geometry::convert(g4, og4); - geometry::convert(g5, og5); - geometry::convert(g6, og6); - } -}; - -template <> -struct zoom_to_robust -{ - template - < - typename Geometry1, typename Geometry2, typename Geometry3, - typename Geometry4, typename Geometry5, typename Geometry6, - typename GeometryOut - > - static inline void apply(Geometry1 const& g1, Geometry2 const& g2, Geometry3 const& g3, - Geometry4 const& g4, Geometry5 const& g5, Geometry6 const& g6, - GeometryOut& og1, GeometryOut& og2, GeometryOut& og3, - GeometryOut& og4, GeometryOut& og5, GeometryOut& og6) - { - typedef typename point_type::type point1_type; - - // Get the envelop of inputs - model::box env; - geometry::assign_inverse(env); - geometry::expand(env, g1); - geometry::expand(env, g2); - geometry::expand(env, g3); - geometry::expand(env, g4); - geometry::expand(env, g5); - geometry::expand(env, g6); - - // Scale this to integer-range - typename geometry::coordinate_type::type diff = detail::get_max_size(env); - double range = 1000000000.0; // Define a large range to get precise integer coordinates - double factor = double(boost::long_long_type(range / double(diff))); - - // Assign input/output minimal points - point1_type min_point1; - detail::assign_point_from_index<0>(env, min_point1); - - typedef typename point_type::type point2_type; - point2_type min_point2; - assign_values(min_point2, boost::long_long_type(-range/2.0), boost::long_long_type(-range/2.0)); - - detail::robust_policy strategy(min_point1, min_point2, factor); - - geometry::recalculate(og1, g1, strategy); - geometry::recalculate(og2, g2, strategy); - geometry::recalculate(og3, g3, strategy); - geometry::recalculate(og4, g4, strategy); - geometry::recalculate(og5, g5, strategy); - geometry::recalculate(og6, g6, strategy); - } -}; - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - -#ifndef DOXYGEN_NO_DETAIL -namespace detail -{ - - -template -inline void zoom_to_robust(Geometry1 const& g1a, Geometry1 const& g1b, Geometry2& g2a, Geometry2& g2b) -{ - typedef typename point_type::type point1_type; - typedef typename point_type::type point2_type; - - point1_type min_point1; - point2_type min_point2; - - // Get the envelop of inputs - model::box env; - geometry::envelope(g1a, env); - geometry::expand(env, g1b); - - // Scale this to integer-range - typename coordinate_type::type diff = detail::get_max_size(env); - double range = 1000000000.0; // Define a large range to get precise integer coordinates - double factor = range / diff; - - // Assign input/output minimal points - detail::assign_point_from_index<0>(env, min_point1); - assign_values(min_point2, boost::long_long_type(-range/2.0), boost::long_long_type(-range/2.0)); - - detail::robust_policy strategy(min_point1, min_point2, factor); - geometry::recalculate(g2a, g1a, strategy); - geometry::recalculate(g2b, g1b, strategy); -} - -template -< - typename Geometry1, typename Geometry2, typename Geometry3, - typename Geometry4, typename Geometry5, typename Geometry6, - typename GeometryOut -> -void zoom_to_robust(Geometry1 const& g1, Geometry2 const& g2, Geometry3 const& g3, - Geometry4 const& g4, Geometry5 const& g5, Geometry6 const& g6, - GeometryOut& og1, GeometryOut& og2, GeometryOut& og3, - GeometryOut& og4, GeometryOut& og5, GeometryOut& og6) -{ - // Make FP robust (so dispatch to true), so float and double - // Other types as int, boost::rational, or ttmath are considered to be already robust - dispatch::zoom_to_robust - < - typename boost::is_floating_point - < - typename geometry::coordinate_type::type - >::type - >::apply(g1, g2, g3, g4, g5, g6, og1, og2, og3, og4, og5, og6); -} - -} // namespace detail -#endif // DOXYGEN_NO_DETAIL - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ZOOM_TO_ROBUST_HPP diff --git a/include/boost/geometry/policies/robustness/robust_point_type.hpp b/include/boost/geometry/policies/robustness/robust_point_type.hpp index 35f719865..25639227f 100644 --- a/include/boost/geometry/policies/robustness/robust_point_type.hpp +++ b/include/boost/geometry/policies/robustness/robust_point_type.hpp @@ -12,14 +12,16 @@ #ifndef BOOST_GEOMETRY_POLICIES_ROBUSTNESS_ROBUST_POINT_TYPE_HPP #define BOOST_GEOMETRY_POLICIES_ROBUSTNESS_ROBUST_POINT_TYPE_HPP -#include - namespace boost { namespace geometry { // Meta-function to typedef a robust point type for a policy template -struct robust_point_type {}; //: not_implemented<> {}; +struct robust_point_type +{ + // By default, the point itself is the robust type + typedef Point type; +}; }} // namespace boost::geometry diff --git a/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp b/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp index 8a830e3a5..9fd7a22b6 100644 --- a/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp +++ b/include/boost/geometry/strategies/agnostic/buffer_distance_symmetric.hpp @@ -29,7 +29,7 @@ public : template inline CoordinateType apply(Point const& , Point const& , - buffer_side_selector side) const + buffer_side_selector ) const { return m_distance; } diff --git a/include/boost/geometry/util/range.hpp b/include/boost/geometry/util/range.hpp index 986aba660..949d99df9 100644 --- a/include/boost/geometry/util/range.hpp +++ b/include/boost/geometry/util/range.hpp @@ -14,6 +14,9 @@ #ifndef BOOST_GEOMETRY_UTIL_RANGE_HPP #define BOOST_GEOMETRY_UTIL_RANGE_HPP +#include + +#include #include #include #include @@ -21,6 +24,8 @@ #include #include +#include + namespace boost { namespace geometry { namespace range { // NOTE: For SinglePassRanges at could iterate over all elements until the i-th element is met. @@ -105,6 +110,158 @@ back(BidirectionalRange & rng) return *(--boost::end(rng)); } + +/*! +\brief Short utility to conveniently clear a mutable range. + It uses traits::clear<>. +\ingroup utility +*/ +template +inline void clear(Range & rng) +{ + // NOTE: this trait is probably not needed since it could be implemented using resize() + geometry::traits::clear::apply(rng); +} + +/*! +\brief Short utility to conveniently insert a new element at the end of a mutable range. + It uses boost::geometry::traits::push_back<>. +\ingroup utility +*/ +template +inline void push_back(Range & rng, + typename boost::range_value::type const& value) +{ + geometry::traits::push_back::apply(rng, value); +} + +/*! +\brief Short utility to conveniently resize a mutable range. + It uses boost::geometry::traits::resize<>. +\ingroup utility +*/ +template +inline void resize(Range & rng, + typename boost::range_size::type new_size) +{ + geometry::traits::resize::apply(rng, new_size); +} + + +/*! +\brief Short utility to conveniently remove an element from the back of a mutable range. + It uses resize(). +\ingroup utility +*/ +template +inline void pop_back(Range & rng) +{ + BOOST_ASSERT(!boost::empty(rng)); + range::resize(rng, boost::size(rng) - 1); +} + +/*! +\brief Short utility to conveniently remove an element from a mutable range. + It uses std::copy() and resize(). Version taking mutable iterators. +\ingroup utility +*/ +template +inline typename boost::range_iterator::type +erase(Range & rng, + typename boost::range_iterator::type it) +{ + BOOST_ASSERT(!boost::empty(rng)); + BOOST_ASSERT(it != boost::end(rng)); + + typename boost::range_iterator::type + next = it; + ++next; + + std::copy(next, boost::end(rng), it); + range::resize(rng, boost::size(rng) - 1); + + // NOTE: assuming that resize() doesn't invalidate the iterators + return it; +} + +/*! +\brief Short utility to conveniently remove an element from a mutable range. + It uses std::copy() and resize(). Version taking non-mutable iterators. +\ingroup utility +*/ +template +inline typename boost::range_iterator::type +erase(Range & rng, + typename boost::range_iterator::type cit) +{ + BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept )); + + typename boost::range_iterator::type + it = boost::begin(rng) + + std::distance(boost::const_begin(rng), cit); + + erase(rng, it); + + // NOTE: assuming that resize() doesn't invalidate the iterators + return cit; +} + +/*! +\brief Short utility to conveniently remove a range of elements from a mutable range. + It uses std::copy() and resize(). Version taking mutable iterators. +\ingroup utility +*/ +template +inline typename boost::range_iterator::type +erase(Range & rng, + typename boost::range_iterator::type first, + typename boost::range_iterator::type last) +{ + typename std::iterator_traits + < + typename boost::range_iterator::type + >::difference_type const diff = std::distance(first, last); + BOOST_ASSERT(diff >= 0); + + std::size_t const count = static_cast(diff); + BOOST_ASSERT(count <= boost::size(rng)); + + if ( count > 0 ) + { + std::copy(last, boost::end(rng), first); + range::resize(rng, boost::size(rng) - count); + } + + // NOTE: assuming that resize() doesn't invalidate the iterators + return first; +} + +/*! +\brief Short utility to conveniently remove a range of elements from a mutable range. + It uses std::copy() and resize(). Version taking non-mutable iterators. +\ingroup utility +*/ +template +inline typename boost::range_iterator::type +erase(Range & rng, + typename boost::range_iterator::type cfirst, + typename boost::range_iterator::type clast) +{ + BOOST_RANGE_CONCEPT_ASSERT(( boost::RandomAccessRangeConcept )); + + typename boost::range_iterator::type + first = boost::begin(rng) + + std::distance(boost::const_begin(rng), cfirst); + typename boost::range_iterator::type + last = boost::begin(rng) + + std::distance(boost::const_begin(rng), clast); + + erase(rng, first, last); + + // NOTE: assuming that resize() doesn't invalidate the iterators + return cfirst; +} + }}} // namespace boost::geometry::range #endif // BOOST_GEOMETRY_UTIL_RANGE_HPP diff --git a/test/algorithms/buffer/multi_polygon_buffer.cpp b/test/algorithms/buffer/multi_polygon_buffer.cpp index fc9511969..7afd55b82 100644 --- a/test/algorithms/buffer/multi_polygon_buffer.cpp +++ b/test/algorithms/buffer/multi_polygon_buffer.cpp @@ -311,9 +311,7 @@ void test_all() test_one("rt_p6", rt_p6, 18.4853, 1.0); test_one("rt_p7", rt_p7, 26.2279, 1.0); test_one("rt_p8", rt_p8, 29.0563, 1.0); -#if !defined(_MSC_VER) test_one("rt_p9", rt_p9, 26.1421, 1.0); -#endif test_one("rt_p10", rt_p10, 23.3995, 1.0); test_one("rt_p11", rt_p11, 28.7426, 1.0); diff --git a/test/algorithms/buffer/test_buffer.hpp b/test/algorithms/buffer/test_buffer.hpp index 83aded00e..c517a8756 100644 --- a/test/algorithms/buffer/test_buffer.hpp +++ b/test/algorithms/buffer/test_buffer.hpp @@ -323,9 +323,6 @@ void test_buffer(std::string const& caseid, Geometry const& geometry, typedef typename bg::coordinate_type::type coordinate_type; typedef typename bg::point_type::type point_type; - typedef bg::strategy::buffer::distance_asymmetric distance; - - typedef typename bg::ring_type::type ring_type; typedef typename bg::tag::type tag; // TODO use something different here: @@ -509,8 +506,6 @@ void test_one(std::string const& caseid, std::string const& wkt, Geometry g; bg::read_wkt(wkt, g); - typedef typename bg::point_type::type point_type; - #ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS std::cout diff --git a/test/algorithms/difference.cpp b/test/algorithms/difference.cpp index 139c5c147..6f83aef4a 100644 --- a/test/algorithms/difference.cpp +++ b/test/algorithms/difference.cpp @@ -98,7 +98,6 @@ void test_all() test_areal_linear(); - test_one("simplex_normal", simplex_normal[0], simplex_normal[1], 3, 12, 2.52636706856656, @@ -327,29 +326,20 @@ void test_all() 1, 11, 3370866.2295081965, 1, 5, 384.2295081964694, 0.01); -#ifdef _MSC_VER - // 2011-07-02 + // 2011-07-02 / 2014-06-19 // Interesting FP-precision case. // sql server gives: 6.62295817619452E-05 // PostGIS gives: 0.0 (no output) - // Boost.Geometry gives results depending on FP-type, and compiler, and operating system. - // For double, it is zero (skipped). On gcc/Linux, for float either. - // Because we cannot predict this, we only test for MSVC - if (boost::is_same::value -#if defined(HAVE_TTMATH) - || boost::is_same::value -#endif - ) - { - test_one("ggl_list_20110627_phillip", - ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1], - if_typed_tt(1, 0), -1, - if_typed_tt(0.0000000000001105367, 0.0), - 1, -1, 3577.40960816756, - 0.01 - ); - } -#endif + // Boost.Geometry gave results depending on FP-type, and compiler, and operating system. + // Since rescaling to integer results are equal w.r.t. compiler/FP type, + // however, some long spikes are still generated in the resulting difference + test_one("ggl_list_20110627_phillip", + ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1], + 1, -1, + if_typed_tt(0.0000000000001105367, 0.00021401892), + 1, -1, 3577.40960816756, + 0.01 + ); // Ticket 8310, one should be completely subtracted from the other. test_one("ticket_8310a", diff --git a/test/util/Jamfile.v2 b/test/util/Jamfile.v2 index 7fbf827d0..bfb647dc7 100644 --- a/test/util/Jamfile.v2 +++ b/test/util/Jamfile.v2 @@ -18,6 +18,7 @@ test-suite boost-geometry-util [ run calculation_type.cpp ] [ run for_each_coordinate.cpp ] [ run math_sqrt.cpp ] + [ run range.cpp ] [ run rational.cpp ] [ run select_most_precise.cpp ] [ run write_dsv.cpp ] diff --git a/test/util/range.cpp b/test/util/range.cpp new file mode 100644 index 000000000..579c59f57 --- /dev/null +++ b/test/util/range.cpp @@ -0,0 +1,143 @@ +// Boost.Geometry +// Unit Test + +// Copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// 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) + + +#include + +#include +#include + +namespace bgt { + +template +struct beginner +{ + template + typename boost::range_iterator::type + operator()(Range & rng) + { + return boost::begin(rng); + } +}; +template <> +struct beginner +{ + template + typename boost::range_iterator::type + operator()(Range & rng) + { + return boost::const_begin(rng); + } +}; + +template +struct ender +{ + template + typename boost::range_iterator::type + operator()(Range & rng) + { + return boost::end(rng); + } +}; +template <> +struct ender +{ + template + typename boost::range_iterator::type + operator()(Range & rng) + { + return boost::const_end(rng); + } +}; + +} // namespace bgt + +template +void test_all() +{ + namespace bgr = bg::range; + + bgt::beginner begin; + bgt::ender end; + + std::vector v; + for (int i = 0 ; i < 20 ; ++i) + { + bgr::push_back(v, i); + } + + for (int i = 0 ; i < 20 ; ++i) + { + BOOST_CHECK(bgr::at(v, i) == i); + } + + BOOST_CHECK(bgr::front(v) == 0); + BOOST_CHECK(bgr::back(v) == 19); + + BOOST_CHECK(boost::size(v) == 20); // [0,19] + bgr::resize(v, 15); + BOOST_CHECK(boost::size(v) == 15); // [0,14] + BOOST_CHECK(bgr::back(v) == 14); + + bgr::pop_back(v); + BOOST_CHECK(boost::size(v) == 14); // [0,13] + BOOST_CHECK(bgr::back(v) == 13); + + bgr::erase(v, end(v) - 1); + BOOST_CHECK(boost::size(v) == 13); // [0,12] + BOOST_CHECK(bgr::back(v) == 12); + + bgr::erase(v, end(v) - 3, end(v)); + BOOST_CHECK(boost::size(v) == 10); // [0,9] + BOOST_CHECK(bgr::back(v) == 9); + + bgr::erase(v, begin(v) + 2); + BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9} + BOOST_CHECK(bgr::at(v, 1) == 1); + BOOST_CHECK(bgr::at(v, 2) == 3); + BOOST_CHECK(bgr::back(v) == 9); + + bgr::erase(v, begin(v) + 2, begin(v) + 2); + BOOST_CHECK(boost::size(v) == 9); // {0,1,3..9} + BOOST_CHECK(bgr::at(v, 1) == 1); + BOOST_CHECK(bgr::at(v, 2) == 3); + BOOST_CHECK(bgr::back(v) == 9); + + bgr::erase(v, begin(v) + 2, begin(v) + 5); + BOOST_CHECK(boost::size(v) == 6); // {0,1,6..9} + BOOST_CHECK(bgr::at(v, 1) == 1); + BOOST_CHECK(bgr::at(v, 2) == 6); + BOOST_CHECK(bgr::back(v) == 9); + + bgr::erase(v, begin(v)); + BOOST_CHECK(boost::size(v) == 5); // {1,6..9} + BOOST_CHECK(bgr::at(v, 0) == 1); + BOOST_CHECK(bgr::at(v, 1) == 6); + BOOST_CHECK(bgr::back(v) == 9); + + bgr::erase(v, begin(v), begin(v) + 3); + BOOST_CHECK(boost::size(v) == 2); // {8,9} + BOOST_CHECK(bgr::at(v, 0) == 8); + BOOST_CHECK(bgr::at(v, 1) == 9); + BOOST_CHECK(bgr::back(v) == 9); + + bgr::erase(v, begin(v), end(v)); + BOOST_CHECK(boost::size(v) == 0); +} + +int test_main(int, char* []) +{ + test_all(); + test_all(); + + return 0; +}