Compare commits

...

15 Commits

Author SHA1 Message Date
2a0b753691 Use Azure mirrors of Ubuntu .deb repositories in containers.
This reduces the likelihood of spurious CI failures caused by DDoS filters
being triggered by massive numbers of concurrent CI jobs.
2025-06-13 03:48:03 +03:00
0087a426d9 Added new gcc and clang jobs to GitHub Actions. 2025-06-13 03:47:38 +03:00
c409288ff5 Removed windows-2019 GitHub Actions jobs.
The windows-2019 image is deprecated and is about to be removed.
2025-06-13 03:45:12 +03:00
01ac4e1a47 Disable operator_brackets_proxy assignment if reference is not assignable.
Use SFINAE to disable operator_brackets_proxy assignment operator is reference
is not assignable from the assignment argument. Also fix the iterator type
in std::declval in noexcept specification.
2025-06-09 12:01:39 +03:00
e968c3312b Forward dereferencing operators in operator_brackets_proxy.
This allows for expressions like it[n]->foo() and (*it[n]).foo() to compile.
2025-06-09 04:58:45 +03:00
da00617e56 Use perfect forwarding in assignment to operator_brackets_proxy.
Also apply noexcept markup to all of the proxy operators.
2025-06-09 04:58:27 +03:00
7c77e52509 Always use operator_brackets_proxy in iterator_facade.
This avoids returning a copy of the value from operator[], which can
be unexpected by users wanting to obtain an address of the value
referenced by the iterator.

We still want to return a proxy instead of the iterator's reference
since the iterator may be holding the value internally, and the iterator
gets destroyed after returning from operator[], so the returned
reference would be dangling.

Closes https://github.com/boostorg/iterator/issues/61.
2025-06-09 03:22:08 +03:00
256004a446 Remove gcc 4.8 and 4.9 GitHub Actions jobs.
These compilers don't provide std::is_trivially_copyable type trait,
which is now required.
2025-06-09 02:53:18 +03:00
7e3e9a584e Replace is_copy_constructible+is_trivial with is_trivially_copyable.
For the purpose of selecting operator[] result type, we don't care
whether the value type is trivially default-constructible. So, in order
to avoid using the deprecated in C++26 is_trivial, use is_trivially_copyable
instead of is_copy_constructible+is_trivial.

Closes https://github.com/boostorg/iterator/issues/93.
2025-06-09 02:36:26 +03:00
3767696513 Removed legacy MinGW32 AppVeyor CI job.
Boost.Regex develop no longer builds on legacy MinGW32 due to missing
definitions of std::mutex etc.
2025-05-25 03:57:17 +03:00
1372e9afb6 Fix filter_iterator copy/converting constructor.
The constructed iterator would have an invalid end iterator because of
a typo in storage initialization.

Fixes https://github.com/boostorg/iterator/issues/92.
2025-05-24 23:19:45 +03:00
6428e552e4 Nonessential. 2025-04-23 02:55:50 +03:00
766c881f9a Removed usage of obsolete ubuntu-20.04 GHA image. 2025-04-19 18:36:04 +03:00
c2b846c57d Added a test for filter_iterator converting constructor. 2025-04-02 00:13:07 +03:00
1a7996ebd0 Fixed compilation of filter_iterator conversion constructor.
The constructor would attempt to access a private member of the source
iterator, which could have a different type and therefore have that
member inaccessible. Also, the storage forwarding constructor had incorrect
types used in the forwarding expressions, which caused further compilation
errors.

Fixes https://github.com/boostorg/iterator/issues/90.
2025-04-02 00:09:36 +03:00
7 changed files with 140 additions and 133 deletions

View File

@ -33,18 +33,6 @@ jobs:
matrix:
include:
# Linux, gcc
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "11,14,1z"
os: ubuntu-latest
@ -71,12 +59,14 @@ jobs:
- g++-8
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:20.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "11,14,17,20"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:20.04
install:
- g++-10
- toolset: gcc-11
@ -99,6 +89,12 @@ jobs:
os: ubuntu-24.04
install:
- g++-14
- toolset: gcc-15
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- g++-15
- name: UBSAN
toolset: gcc-13
cxxstd: "11,14,17,20,23"
@ -185,13 +181,15 @@ jobs:
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,20"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-10
- toolset: clang
@ -263,22 +261,22 @@ jobs:
os: ubuntu-24.04
install:
- clang-19
sources:
- "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-19
compiler: clang++-20
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
os: ubuntu-latest
container: ubuntu:25.04
install:
- clang-19
- libc++-19-dev
- libc++abi-19-dev
sources:
- "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- clang-20
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- clang-20
- libc++-20-dev
- libc++abi-20-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
@ -307,7 +305,7 @@ jobs:
- name: CMake tests
cmake_tests: 1
os: ubuntu-20.04
os: ubuntu-24.04
timeout-minutes: 20
runs-on: ${{matrix.os}}
@ -326,6 +324,22 @@ jobs:
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
# Use Azure APT mirrors in containers to avoid HTTP errors due to DDoS filters triggered by lots of CI jobs launching concurrently.
# Note that not all Ubuntu versions support "mirror+file:..." URIs in APT sources, so just use Azure mirrors exclusively.
# Note also that on recent Ubuntu versions DEB822 format is used for source files.
APT_SOURCES=()
if [ -d "/etc/apt/sources.list.d" ]
then
readarray -t APT_SOURCES < <(find "/etc/apt/sources.list.d" -type f -name '*.sources' -print)
fi
if [ -f "/etc/apt/sources.list" ]
then
APT_SOURCES+=("/etc/apt/sources.list")
fi
if [ "${#APT_SOURCES[@]}" -gt 0 ]
then
sed -i -E -e 's!([^ ]+) (http|https)://(archive|security)\.ubuntu\.com/ubuntu[^ ]*(.*)!\1 http://azure.archive.ubuntu.com/ubuntu/\4!' "${APT_SOURCES[@]}"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
then
@ -545,14 +559,6 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
@ -562,9 +568,9 @@ jobs:
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "11,14,17,2a"
cxxstd: "11,14,17,20,23"
addrmd: 64
os: windows-2019
os: windows-2022
timeout-minutes: 20
runs-on: ${{matrix.os}}

View File

@ -43,10 +43,6 @@ environment:
CXXSTD: 11,14,1z
ADDPATH: C:\cygwin64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 11,14,1z
ADDPATH: C:\mingw\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 11,14,1z
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;

View File

@ -46,6 +46,9 @@ class filter_iterator :
{
friend class iterator_core_access;
template< typename, typename >
friend class filter_iterator;
private:
using super_t = detail::filter_iterator_base_t< Predicate, Iterator >;
@ -75,7 +78,7 @@ private:
template< typename Pred, typename Iter >
storage(Pred&& pred, Iter&& end) :
predicate_base(boost::empty_init_t{}, static_cast< Predicate&& >(pred)), m_end(static_cast< Iterator&& >(end))
predicate_base(boost::empty_init_t{}, static_cast< Pred&& >(pred)), m_end(static_cast< Iter&& >(end))
{
}
@ -101,7 +104,7 @@ public:
template< typename OtherIterator, typename = enable_if_convertible_t< OtherIterator, Iterator > >
filter_iterator(filter_iterator< Predicate, OtherIterator > const& t) :
super_t(t.base()), m_storage(t.m_storage.predicate(), m_storage.m_end)
super_t(t.base()), m_storage(t.m_storage.predicate(), t.m_storage.m_end)
{}
Predicate predicate() const { return m_storage.predicate(); }

View File

@ -9,6 +9,7 @@
#include <cstddef>
#include <memory>
#include <utility>
#include <type_traits>
#include <boost/config.hpp>
@ -346,63 +347,52 @@ class operator_brackets_proxy
// Iterator is actually an iterator_facade, so we do not have to
// go through iterator_traits to access the traits.
using reference = typename Iterator::reference;
using value_type = typename Iterator::value_type;
public:
operator_brackets_proxy(Iterator const& iter) :
explicit operator_brackets_proxy(Iterator const& iter) noexcept(std::is_nothrow_copy_constructible< Iterator >::value) :
m_iter(iter)
{}
operator reference() const
operator reference() const noexcept(noexcept(*std::declval< Iterator const& >()))
{
return *m_iter;
}
operator_brackets_proxy& operator=(value_type const& val)
template< typename T >
typename std::enable_if<
detail::conjunction<
detail::negation<
std::is_same<
operator_brackets_proxy< Iterator >,
typename std::remove_cv< typename std::remove_reference< T >::type >::type
>
>,
std::is_assignable< reference, T&& >
>::value,
operator_brackets_proxy&
>::type operator= (T&& val) noexcept(noexcept(*std::declval< Iterator& >() = std::declval< T&& >()))
{
*m_iter = val;
*m_iter = static_cast< T&& >(val);
return *this;
}
// Provides it[n]->foo(). Leverages chaining of operator->.
reference operator->() const noexcept(noexcept(*std::declval< Iterator const& >()))
{
return *m_iter;
}
// Provides (*it[n]).foo()
template< typename Ref = reference, typename Result = decltype(*std::declval< Ref >()) >
Result operator*() const noexcept(noexcept(**std::declval< Iterator const& >()))
{
return **m_iter;
}
private:
Iterator m_iter;
};
// A metafunction that determines whether operator[] must return a
// proxy, or whether it can simply return a copy of the value_type.
template< typename ValueType, typename Reference >
struct use_operator_brackets_proxy :
public detail::negation<
detail::conjunction<
std::is_copy_constructible< ValueType >,
std::is_trivial< ValueType >,
iterator_writability_disabled< ValueType, Reference >
>
>
{};
template< typename Iterator, typename Value, typename Reference >
struct operator_brackets_result
{
using type = typename std::conditional<
use_operator_brackets_proxy<Value, Reference>::value,
operator_brackets_proxy<Iterator>,
Value
>::type;
};
template< typename Iterator >
inline operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, std::true_type)
{
return operator_brackets_proxy< Iterator >(iter);
}
template< typename Iterator >
inline typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, std::false_type)
{
return *iter;
}
// A binary metafunction class that always returns bool.
template< typename Iterator1, typename Iterator2 >
using always_bool_t = bool;
@ -679,13 +669,9 @@ public:
using difference_type = typename base_type::difference_type;
public:
typename boost::iterators::detail::operator_brackets_result< Derived, Value, reference >::type
operator[](difference_type n) const
operator_brackets_proxy< Derived > operator[](difference_type n) const
{
return boost::iterators::detail::make_operator_brackets_result< Derived >(
this->derived() + n,
std::integral_constant< bool, boost::iterators::detail::use_operator_brackets_proxy< Value, Reference >::value >{}
);
return operator_brackets_proxy< Derived >(this->derived() + n);
}
Derived& operator+=(difference_type n)

View File

@ -57,7 +57,7 @@ private:
std::remove_reference< reference >
>;
public:
public:
using type = iterator_adaptor<
transform_iterator< UnaryFunc, Iterator, Reference, Value >,
Iterator,

View File

@ -36,13 +36,13 @@ int main()
// Concept checks
// Adapting old-style iterators
{
typedef boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> >;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> >;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
@ -50,39 +50,39 @@ int main()
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> >;
boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> >;
boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> >;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> >;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> >;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> >;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
@ -90,24 +90,24 @@ int main()
}
// Adapting new-style iterators
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::single_pass_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::single_pass_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
@ -117,12 +117,12 @@ int main()
}
#endif
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
@ -130,35 +130,35 @@ int main()
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
@ -167,12 +167,12 @@ int main()
#endif
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
@ -180,35 +180,35 @@ int main()
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
@ -222,7 +222,7 @@ int main()
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
typedef boost::filter_iterator<one_or_four, dummyT*> filter_iter;
using filter_iter = boost::filter_iterator<one_or_four, dummyT*>;
boost::bidirectional_readable_iterator_test(
filter_iter(one_or_four(), array, array+N)
@ -235,7 +235,13 @@ int main()
>::value,
"Filter interator must have a random_access_traversal_tag.");
//# endif
// Check that the iterator can be constructed from a different but compatible iterator
{
using const_filter_iter = boost::filter_iterator<one_or_four, const dummyT*>;
filter_iter mutable_it(one_or_four(), array+0, array+N);
const_filter_iter const_it(mutable_it);
(void)const_it;
}
// On compilers not supporting partial specialization, we can do more type
// deduction with deque iterators than with pointers... unless the library

View File

@ -189,6 +189,16 @@ main()
boost::const_nonconst_iterator_test(i, ++j);
}
// Test that operator_brackets_proxy forwards operator-> and operator*
{
dummyT* ptr_array[] = { array + 0, array + 1, array + 2,
array + 3, array + 4, array + 5 };
ptr_iterator<dummyT*> i(ptr_array);
BOOST_TEST_EQ(i[2]->foo(), 2);
BOOST_TEST_EQ((*i[2]).foo(), 2);
}
int test;
// Test the iterator_traits
{