Skip to content

Commit e3d38f0

Browse files
committed
Prohibit default construction of function_output_iterator on function pointers.
Default-constructed function_output_iterator with function pointers is unusable and previously would have contained an uninitialized function pointer. Disable the default constructor using SFINAE to prevent misuse. Also reformat code.
1 parent 46512e4 commit e3d38f0

File tree

3 files changed

+68
-46
lines changed

3 files changed

+68
-46
lines changed

include/boost/iterator/function_output_iterator.hpp

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,69 +8,76 @@
88
// 27 Feb 2001 Jeremy Siek
99
// Initial checkin.
1010

11-
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
12-
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
11+
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
12+
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
1313

1414
#include <cstddef>
1515
#include <iterator>
1616
#include <type_traits>
1717

18-
#include <boost/config.hpp>
19-
2018
namespace boost {
2119
namespace iterators {
2220

23-
template <class UnaryFunction>
24-
class function_output_iterator {
25-
private:
26-
typedef function_output_iterator self;
27-
28-
class output_proxy {
21+
template< typename UnaryFunction >
22+
class function_output_iterator
23+
{
24+
private:
25+
class output_proxy
26+
{
2927
public:
30-
explicit output_proxy(UnaryFunction& f) BOOST_NOEXCEPT : m_f(f) { }
31-
32-
template <class T>
33-
34-
typename std::enable_if<
35-
!std::is_same< typename std::remove_cv< typename std::remove_reference< T >::type >::type, output_proxy >::value,
36-
output_proxy const&
37-
>::type operator=(T&& value) const {
38-
m_f(static_cast< T&& >(value));
39-
return *this;
40-
}
41-
42-
BOOST_DEFAULTED_FUNCTION(output_proxy(output_proxy const& that), BOOST_NOEXCEPT : m_f(that.m_f) {})
43-
BOOST_DELETED_FUNCTION(output_proxy& operator=(output_proxy const&))
28+
explicit output_proxy(UnaryFunction& f) noexcept :
29+
m_f(f)
30+
{}
31+
32+
template< typename T >
33+
typename std::enable_if<
34+
!std::is_same< typename std::remove_cv< typename std::remove_reference< T >::type >::type, output_proxy >::value,
35+
output_proxy const&
36+
>::type operator=(T&& value) const
37+
{
38+
m_f(static_cast< T&& >(value));
39+
return *this;
40+
}
41+
42+
output_proxy(output_proxy const& that) = default;
43+
output_proxy& operator=(output_proxy const&) = delete;
4444

4545
private:
46-
UnaryFunction& m_f;
46+
UnaryFunction& m_f;
4747
};
4848

49-
public:
50-
typedef std::output_iterator_tag iterator_category;
51-
typedef void value_type;
52-
typedef std::ptrdiff_t difference_type;
53-
typedef void pointer;
54-
typedef void reference;
55-
56-
explicit function_output_iterator() {}
57-
58-
explicit function_output_iterator(const UnaryFunction& f)
59-
: m_f(f) {}
49+
public:
50+
using iterator_category = std::output_iterator_tag;
51+
using value_type = void;
52+
using difference_type = std::ptrdiff_t;
53+
using pointer = void;
54+
using reference = void;
55+
56+
template<
57+
bool Requires = std::is_class< UnaryFunction >::value,
58+
typename = typename std::enable_if< Requires >::type
59+
>
60+
function_output_iterator() :
61+
m_f()
62+
{}
63+
64+
explicit function_output_iterator(UnaryFunction const& f) :
65+
m_f(f)
66+
{}
6067

6168
output_proxy operator*() { return output_proxy(m_f); }
62-
self& operator++() { return *this; }
63-
self& operator++(int) { return *this; }
69+
function_output_iterator& operator++() { return *this; }
70+
function_output_iterator& operator++(int) { return *this; }
6471

65-
private:
72+
private:
6673
UnaryFunction m_f;
67-
};
74+
};
6875

69-
template <class UnaryFunction>
70-
inline function_output_iterator<UnaryFunction>
71-
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
72-
return function_output_iterator<UnaryFunction>(f);
73-
}
76+
template< typename UnaryFunction >
77+
inline function_output_iterator< UnaryFunction > make_function_output_iterator(UnaryFunction const& f = UnaryFunction())
78+
{
79+
return function_output_iterator< UnaryFunction >(f);
80+
}
7481

7582
} // namespace iterators
7683

@@ -79,4 +86,4 @@ using iterators::make_function_output_iterator;
7986

8087
} // namespace boost
8188

82-
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
89+
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_

test/Jamfile.v2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ test-suite iterator
5858
[ run function_input_iterator_test.cpp ]
5959
[ run function_output_iterator_test.cpp ]
6060
[ compile-fail function_output_iterator_cf.cpp ]
61+
[ compile-fail function_output_iterator_def_ctor_cf.cpp ]
6162

6263
[ run generator_iterator_test.cpp ]
6364

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2025 (c) Andrey Semashev
2+
// Distributed under the Boost Software License Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#include <boost/iterator/function_output_iterator.hpp>
7+
8+
int main()
9+
{
10+
boost::iterators::function_output_iterator< void (*)(int) > it;
11+
(void)it;
12+
13+
return 0;
14+
}

0 commit comments

Comments
 (0)