// Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test // Copyright (c) 2015, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #ifndef GEOMETRY_TEST_TEST_GEOMETRIES_COPY_ON_DEREFERENCE_GEOMETRIES_HPP #define GEOMETRY_TEST_TEST_GEOMETRIES_COPY_ON_DEREFERENCE_GEOMETRIES_HPP #include #include #include #include #include #include template class copy_on_dereference_iterator : public boost::iterator_facade < copy_on_dereference_iterator, typename std::iterator_traits::value_type, boost::random_access_traversal_tag, typename std::iterator_traits::value_type, typename std::iterator_traits::difference_type > { private: typedef boost::iterator_facade < copy_on_dereference_iterator, typename std::iterator_traits::value_type, boost::random_access_traversal_tag, typename std::iterator_traits::value_type, typename std::iterator_traits::difference_type > base_type; public: typedef typename base_type::reference reference; typedef typename base_type::difference_type difference_type; copy_on_dereference_iterator() {} copy_on_dereference_iterator(RandomAccessIterator it) : m_it(it) {} template copy_on_dereference_iterator (copy_on_dereference_iterator const& other) : m_it(other.m_it) {} private: friend class boost::iterator_core_access; template friend class copy_on_dereference_iterator; inline reference dereference() const { return *m_it; } inline void increment() { ++m_it; } inline void decrement() { --m_it; } inline void advance(difference_type n) { m_it += n; } template inline bool equal(copy_on_dereference_iterator const& other) const { return m_it == other.m_it; } template inline difference_type distance_to(copy_on_dereference_iterator const& other) const { return std::distance(m_it, other.m_it); } private: RandomAccessIterator m_it; }; template class range_copy_on_dereference : private std::vector { private: typedef std::vector base_type; public: typedef typename base_type::size_type size_type; typedef copy_on_dereference_iterator < typename base_type::const_iterator > const_iterator; typedef const_iterator iterator; inline iterator begin() { return iterator(base_type::begin()); } inline iterator end() { return iterator(base_type::end()); } inline const_iterator begin() const { return const_iterator(base_type::begin()); } inline const_iterator end() const { return const_iterator(base_type::end()); } inline void clear() { base_type::clear(); } inline void push_back(Value const& value) { base_type::push_back(value); } inline void resize(std::size_t n) { base_type::resize(n); } inline size_type size() const { return base_type::size(); } }; template struct multipoint_copy_on_dereference : range_copy_on_dereference {}; template struct linestring_copy_on_dereference : range_copy_on_dereference {}; namespace boost { namespace geometry { namespace traits { template struct tag< multipoint_copy_on_dereference > { typedef multi_point_tag type; }; template struct tag< linestring_copy_on_dereference > { typedef linestring_tag type; }; } // namespace traits }} // namespace boost::geometry #endif // GEOMETRY_TEST_TEST_GEOMETRIES_COPY_ON_DEREFERENCE_GEOMETRIES_HPP