diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0706aeb..d11edf8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,7 +22,6 @@ target_link_libraries(boost_iterator
Boost::fusion
Boost::mpl
Boost::optional
- Boost::smart_ptr
Boost::type_traits
Boost::utility
)
diff --git a/build.jam b/build.jam
index ecc77c7..5cdfb93 100644
--- a/build.jam
+++ b/build.jam
@@ -14,7 +14,6 @@ constant boost_dependencies :
/boost/fusion//boost_fusion
/boost/mpl//boost_mpl
/boost/optional//boost_optional
- /boost/smart_ptr//boost_smart_ptr
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility ;
diff --git a/doc/index.html b/doc/index.html
index 65973b4..ece73ae 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -140,7 +140,7 @@ sequence, rearranged according to some sequence of integer indices.
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's std::reverse_iterator.
shared_container_iterator: an iterator over elements of a container whose
-lifetime is maintained by a shared_ptr stored in the iterator.
+lifetime is maintained by a shared_ptr stored in the iterator.
transform_iterator (PDF): an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
diff --git a/doc/quickbook/shared_container_iterator.qbk b/doc/quickbook/shared_container_iterator.qbk
index b87678a..8e6463a 100644
--- a/doc/quickbook/shared_container_iterator.qbk
+++ b/doc/quickbook/shared_container_iterator.qbk
@@ -1,6 +1,6 @@
[section:shared_container Shared Container Iterator]
-Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
+Defined in header [@../../../boost/iterator/shared_container_iterator.hpp `boost/iterator/shared_container_iterator.hpp`].
The purpose of the shared container iterator is to attach the lifetime
of a container to the lifetime of its iterators. In other words, the
@@ -24,9 +24,22 @@ iterator.
[h2 Synopsis]
namespace boost {
+ namespace iterators {
template
class shared_container_iterator;
+ template
+ shared_container_iterator
+ make_shared_container_iterator(typename Container::iterator base,
+ std::shared_ptr const& container);
+
+ std::pair<
+ typename shared_container_iterator,
+ typename shared_container_iterator
+ >
+ make_shared_container_range(std::shared_ptr const& container);
+
+ // Backward compatibility with boost::shared_ptr
template
shared_container_iterator
make_shared_container_iterator(typename Container::iterator base,
@@ -38,6 +51,15 @@ iterator.
>
make_shared_container_range(boost::shared_ptr const& container);
}
+ }
+
+[note `shared_container_iterator` and its factory functions support both
+`std::shared_ptr` and `boost::shared_ptr` for a smart pointer that holds
+a shared reference to the container. However, the support for `boost::shared_ptr`
+comes at a cost of wrapping it in a `std::shared_ptr` internally. This means
+that when constructing the iterator from a `boost::shared_ptr`, the construction
+will have to allocate memory for `std::shared_ptr` shared state, which may
+potentially fail. It is recommended to use `std::shared_ptr` directly.]
[section:shared_container_type The Shared Container Iterator Type]
@@ -57,18 +79,17 @@ the underlying vector and thereby extend the container's lifetime.
[example_link shared_iterator_example1.cpp..`shared_iterator_example1.cpp`]:
- #include "shared_container_iterator.hpp"
- #include "boost/shared_ptr.hpp"
+ #include
#include
#include
#include
+ #include
- typedef boost::shared_container_iterator< std::vector > iterator;
+ using iterator = boost::iterators::shared_container_iterator< std::vector >;
- void set_range(iterator& i, iterator& end) {
-
- boost::shared_ptr< std::vector > ints(new std::vector());
+ void set_range(iterator& i, iterator& end) {
+ std::shared_ptr< std::vector > ints(new std::vector());
ints->push_back(0);
ints->push_back(1);
@@ -77,18 +98,17 @@ the underlying vector and thereby extend the container's lifetime.
ints->push_back(4);
ints->push_back(5);
- i = iterator(ints->begin(),ints);
- end = iterator(ints->end(),ints);
+ i = iterator(ints->begin(), ints);
+ end = iterator(ints->end(), ints);
}
int main() {
+ iterator i, end;
- iterator i,end;
+ set_range(i, end);
- set_range(i,end);
-
- std::copy(i,end,std::ostream_iterator(std::cout,","));
+ std::copy(i, end, std::ostream_iterator(std::cout, ","));
std::cout.put('\n');
return 0;
@@ -116,8 +136,12 @@ The `shared_container_iterator` type implements the member functions
and operators required of the
[@http://www.sgi.com/tech/stl/RandomAccessIterator.html Random Access
Iterator] concept, though only operations defined for the base
-iterator will be valid. In addition it has the following constructor:
+iterator will be valid. In addition it has the following constructors:
+ shared_container_iterator(Container::iterator const& it,
+ std::shared_ptr const& container)
+
+ // Backward compatibility with boost::shared_ptr
shared_container_iterator(Container::iterator const& it,
boost::shared_ptr const& container)
@@ -125,6 +149,12 @@ iterator will be valid. In addition it has the following constructor:
[section:shared_container_object_generator The Shared Container Iterator Object Generator]
+ template
+ shared_container_iterator
+ make_shared_container_iterator(Container::iterator base,
+ std::shared_ptr const& container)
+
+ // Backward compatibility with boost::shared_ptr
template
shared_container_iterator
make_shared_container_iterator(Container::iterator base,
@@ -142,25 +172,23 @@ uses `make_shared_container_iterator()` to create the iterators.
[example_link shared_iterator_example2.cpp..`shared_iterator_example2.cpp`]:
- #include "shared_container_iterator.hpp"
- #include "boost/shared_ptr.hpp"
+ #include
#include
#include
#include
#include
+ #include
template
- void print_range_nl (Iterator begin, Iterator end) {
- typedef typename std::iterator_traits::value_type val;
- std::copy(begin,end,std::ostream_iterator(std::cout,","));
+ void print_range_nl(Iterator begin, Iterator end) {
+ using val = typename std::iterator_traits::value_type;
+ std::copy(begin, end, std::ostream_iterator(std::cout, ","));
std::cout.put('\n');
}
-
int main() {
-
- typedef boost::shared_ptr< std::vector > ints_t;
+ using ints_t = std::shared_ptr< std::vector >;
{
ints_t ints(new std::vector());
@@ -171,12 +199,10 @@ uses `make_shared_container_iterator()` to create the iterators.
ints->push_back(4);
ints->push_back(5);
- print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
- boost::make_shared_container_iterator(ints->end(),ints));
+ print_range_nl(boost::iterators::make_shared_container_iterator(ints->begin(), ints),
+ boost::iterators::make_shared_container_iterator(ints->end(), ints));
}
-
-
return 0;
}
@@ -187,53 +213,61 @@ named. The output from this example is the same as the previous.
[section:shared_container_generator The Shared Container Iterator Range Generator]
+ template
+ std::pair<
+ shared_container_iterator,
+ shared_container_iterator
+ >
+ make_shared_container_range(std::shared_ptr const& container);
+
+ // Backward compatibility with boost::shared_ptr
template
std::pair<
shared_container_iterator,
shared_container_iterator
>
make_shared_container_range(boost::shared_ptr const& container);
- Class shared_container_iterator is meant primarily to return, using iterators, a range of values that we can guarantee will be alive as long as the iterators are. This is a convenience function to do just that. It is equivalent to
- std::make_pair(make_shared_container_iterator(container->begin(),container),
- make_shared_container_iterator(container->end(),container));
+
+Class `shared_container_iterator` is meant primarily to return, using iterators,
+a range of values that we can guarantee will be alive as long as the iterators are.
+This is a convenience function to do just that. It is functionally equivalent to this:
+
+ std::make_pair(make_shared_container_iterator(container->begin(), container),
+ make_shared_container_iterator(container->end(), container));
[h2 Example]
-In the following example, a range of values is returned as a pair of shared_container_iterator objects.
+In the following example, a range of values is returned as a pair of `shared_container_iterator` objects.
[example_link shared_iterator_example3.cpp..`shared_iterator_example3.cpp`]:
- #include "shared_container_iterator.hpp"
- #include "boost/shared_ptr.hpp"
- #include "boost/tuple/tuple.hpp" // for boost::tie
- #include // for std::copy
+ #include
+ #include // for std::copy
#include
#include
+ #include
+ #include // for std::tie
- typedef boost::shared_container_iterator< std::vector > iterator;
+ using iterator = boost::iterators::shared_container_iterator< std::vector >;
- std::pair
+ std::pair
return_range() {
- boost::shared_ptr< std::vector > range(new std::vector());
+ std::shared_ptr< std::vector > range(new std::vector());
range->push_back(0);
range->push_back(1);
range->push_back(2);
range->push_back(3);
range->push_back(4);
range->push_back(5);
- return boost::make_shared_container_range(range);
+ return boost::iterators::make_shared_container_range(range);
}
-
int main() {
-
-
iterator i,end;
+ std::tie(i, end) = return_range();
- boost::tie(i,end) = return_range();
-
- std::copy(i,end,std::ostream_iterator(std::cout,","));
+ std::copy(i, end, std::ostream_iterator(std::cout, ","));
std::cout.put('\n');
return 0;
diff --git a/include/boost/iterator/shared_container_iterator.hpp b/include/boost/iterator/shared_container_iterator.hpp
new file mode 100644
index 0000000..deffd05
--- /dev/null
+++ b/include/boost/iterator/shared_container_iterator.hpp
@@ -0,0 +1,117 @@
+// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
+// distribute this software is granted provided this copyright notice appears
+// in all copies. This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+
+// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
+
+#ifndef BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
+#define BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
+
+#include
+#include
+#include
+
+namespace boost {
+
+// For backward compatibility with boost::shared_ptr
+template< class T >
+class shared_ptr;
+
+namespace iterators {
+namespace detail {
+
+// Fake deleter that holds an instance of boost::shared_ptr and through it keeps the pointed object from deletion
+template< typename T >
+class shared_container_iterator_bsptr_holder
+{
+private:
+ boost::shared_ptr< T > m_ptr;
+
+public:
+ explicit shared_container_iterator_bsptr_holder(boost::shared_ptr< T > const& ptr) :
+ m_ptr(ptr)
+ {}
+
+ void operator()(T*) const noexcept {}
+};
+
+} // namespace detail
+
+template< typename Container >
+class shared_container_iterator :
+ public iterator_adaptor<
+ shared_container_iterator< Container >,
+ typename Container::iterator
+ >
+{
+private:
+ using super_t = iterator_adaptor<
+ shared_container_iterator< Container >,
+ typename Container::iterator
+ >;
+
+ using iterator_t = typename Container::iterator;
+ using container_ref_t = std::shared_ptr< Container >;
+
+public:
+ shared_container_iterator() = default;
+
+ shared_container_iterator(iterator_t const& x, container_ref_t const& c) :
+ super_t(x),
+ m_container_ref(c)
+ {}
+
+ // Constructor for backward compatibility with boost::shared_ptr
+ shared_container_iterator(iterator_t const& x, boost::shared_ptr< Container > const& c) :
+ super_t(x),
+ m_container_ref(c.get(), detail::shared_container_iterator_bsptr_holder< Container >(c))
+ {}
+
+private:
+ container_ref_t m_container_ref;
+};
+
+template< typename Container >
+inline shared_container_iterator< Container >
+make_shared_container_iterator(typename Container::iterator iter, std::shared_ptr< Container > const& container)
+{
+ return shared_container_iterator< Container >(iter, container);
+}
+
+template< typename Container >
+inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
+make_shared_container_range(std::shared_ptr< Container > const& container)
+{
+ return std::make_pair
+ (
+ iterators::make_shared_container_iterator(container->begin(), container),
+ iterators::make_shared_container_iterator(container->end(), container)
+ );
+}
+
+// Factory functions for backward compatibility with boost::shared_ptr
+template< typename Container >
+inline shared_container_iterator< Container >
+make_shared_container_iterator(typename Container::iterator iter, boost::shared_ptr< Container > const& container)
+{
+ return shared_container_iterator< Container >(iter, container);
+}
+
+template< typename Container >
+inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
+make_shared_container_range(boost::shared_ptr< Container > const& container)
+{
+ std::shared_ptr< Container > c(container.get(), detail::shared_container_iterator_bsptr_holder< Container >(container));
+ return iterators::make_shared_container_range(std::move(c));
+}
+
+} // namespace iterators
+
+using iterators::shared_container_iterator;
+using iterators::make_shared_container_iterator;
+using iterators::make_shared_container_range;
+
+} // namespace boost
+
+#endif // BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
diff --git a/include/boost/shared_container_iterator.hpp b/include/boost/shared_container_iterator.hpp
index 8adcaf7..907b2bb 100644
--- a/include/boost/shared_container_iterator.hpp
+++ b/include/boost/shared_container_iterator.hpp
@@ -1,69 +1,14 @@
-// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
-// distribute this software is granted provided this copyright notice appears
-// in all copies. This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-
-// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
+// (C) Copyright Andrey Semashev 2025.
+// Distributed under 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_SHARED_CONTAINER_ITERATOR_HPP
#define BOOST_SHARED_CONTAINER_ITERATOR_HPP
-#include "boost/iterator_adaptors.hpp"
-#include "boost/shared_ptr.hpp"
-#include
+// This is a deprecated header left for backward compatibility.
+// Please use instead.
-namespace boost {
-namespace iterators {
+#include
-template
-class shared_container_iterator : public iterator_adaptor<
- shared_container_iterator,
- typename Container::iterator> {
-
- typedef iterator_adaptor<
- shared_container_iterator,
- typename Container::iterator> super_t;
-
- typedef typename Container::iterator iterator_t;
- typedef boost::shared_ptr container_ref_t;
-
- container_ref_t container_ref;
-public:
- shared_container_iterator() { }
-
- shared_container_iterator(iterator_t const& x,container_ref_t const& c) :
- super_t(x), container_ref(c) { }
-
-
-};
-
-template
-inline shared_container_iterator
-make_shared_container_iterator(typename Container::iterator iter,
- boost::shared_ptr const& container) {
- typedef shared_container_iterator iterator;
- return iterator(iter,container);
-}
-
-
-
-template
-inline std::pair<
- shared_container_iterator,
- shared_container_iterator >
-make_shared_container_range(boost::shared_ptr const& container) {
- return
- std::make_pair(
- make_shared_container_iterator(container->begin(),container),
- make_shared_container_iterator(container->end(),container));
-}
-
-} // namespace iterators
-
-using iterators::shared_container_iterator;
-using iterators::make_shared_container_iterator;
-using iterators::make_shared_container_range;
-
-} // namespace boost
-
-#endif
+#endif // BOOST_SHARED_CONTAINER_ITERATOR_HPP
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index d89fb37..afd5dae 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -74,5 +74,5 @@ test-suite iterator
[ compile adl_test.cpp : /boost/array//boost_array ]
[ compile range_distance_compat_test.cpp : /boost/range//boost_range ]
- [ run shared_iterator_test.cpp ]
+ [ run shared_iterator_test.cpp : : : /boost/smart_ptr//boost_smart_ptr ]
;
diff --git a/test/shared_iterator_test.cpp b/test/shared_iterator_test.cpp
index a943d30..70fbd2c 100644
--- a/test/shared_iterator_test.cpp
+++ b/test/shared_iterator_test.cpp
@@ -14,12 +14,14 @@
//
-#include "boost/shared_container_iterator.hpp"
-#include "boost/shared_ptr.hpp"
+#include
+#include
#include
#include
+#include
-struct resource {
+struct resource
+{
static int count;
resource() { ++count; }
resource(resource const&) { ++count; }
@@ -27,20 +29,20 @@ struct resource {
};
int resource::count = 0;
-typedef std::vector resources_t;
+typedef std::vector< resource > resources_t;
typedef boost::shared_container_iterator< resources_t > iterator;
-
-void set_range(iterator& i, iterator& end) {
-
- boost::shared_ptr< resources_t > objs(new resources_t());
+template< typename SharedPtr >
+void set_range(iterator& i, iterator& end)
+{
+ SharedPtr objs(new resources_t());
for (int j = 0; j != 6; ++j)
objs->push_back(resource());
- i = iterator(objs->begin(),objs);
- end = iterator(objs->end(),objs);
+ i = iterator(objs->begin(), objs);
+ end = iterator(objs->end(), objs);
BOOST_TEST_EQ(resource::count, 6);
}
@@ -53,7 +55,18 @@ int main() {
iterator i;
{
iterator end;
- set_range(i,end);
+ set_range< boost::shared_ptr< resources_t > >(i, end);
+ BOOST_TEST_EQ(resource::count, 6);
+ }
+ BOOST_TEST_EQ(resource::count, 6);
+ }
+ BOOST_TEST_EQ(resource::count, 0);
+
+ {
+ iterator i;
+ {
+ iterator end;
+ set_range< std::shared_ptr< resources_t > >(i, end);
BOOST_TEST_EQ(resource::count, 6);
}
BOOST_TEST_EQ(resource::count, 6);
diff --git a/test/test_cmake/main.cpp b/test/test_cmake/main.cpp
index ea4f74d..aee9c10 100644
--- a/test/test_cmake/main.cpp
+++ b/test/test_cmake/main.cpp
@@ -7,7 +7,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -31,6 +30,7 @@
#include
#include
#include
+#include
#include
#include