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.
This commit is contained in:
Andrey Semashev 2025-02-06 01:17:12 +03:00
parent fd1445140f
commit a91fc06bb4
3 changed files with 64 additions and 42 deletions

View File

@ -8,67 +8,74 @@
// 27 Feb 2001 Jeremy Siek // 27 Feb 2001 Jeremy Siek
// Initial checkin. // Initial checkin.
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP #ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP #define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
#include <type_traits> #include <type_traits>
#include <boost/config.hpp>
namespace boost { namespace boost {
namespace iterators { namespace iterators {
template <class UnaryFunction> template< typename UnaryFunction >
class function_output_iterator { class function_output_iterator
{
private: private:
typedef function_output_iterator self; class output_proxy
{
class output_proxy {
public: public:
explicit output_proxy(UnaryFunction& f) BOOST_NOEXCEPT : m_f(f) { } explicit output_proxy(UnaryFunction& f) noexcept :
m_f(f)
template <class T> {}
template< typename T >
typename std::enable_if< typename std::enable_if<
!std::is_same< typename std::remove_cv< typename std::remove_reference< T >::type >::type, output_proxy >::value, !std::is_same< typename std::remove_cv< typename std::remove_reference< T >::type >::type, output_proxy >::value,
output_proxy const& output_proxy const&
>::type operator=(T&& value) const { >::type operator=(T&& value) const
{
m_f(static_cast< T&& >(value)); m_f(static_cast< T&& >(value));
return *this; return *this;
} }
BOOST_DEFAULTED_FUNCTION(output_proxy(output_proxy const& that), BOOST_NOEXCEPT : m_f(that.m_f) {}) output_proxy(output_proxy const& that) = default;
BOOST_DELETED_FUNCTION(output_proxy& operator=(output_proxy const&)) output_proxy& operator=(output_proxy const&) = delete;
private: private:
UnaryFunction& m_f; UnaryFunction& m_f;
}; };
public: public:
typedef std::output_iterator_tag iterator_category; using iterator_category = std::output_iterator_tag;
typedef void value_type; using value_type = void;
typedef std::ptrdiff_t difference_type; using difference_type = std::ptrdiff_t;
typedef void pointer; using pointer = void;
typedef void reference; using reference = void;
explicit function_output_iterator() {} template<
bool Requires = std::is_class< UnaryFunction >::value,
typename = typename std::enable_if< Requires >::type
>
function_output_iterator() :
m_f()
{}
explicit function_output_iterator(const UnaryFunction& f) explicit function_output_iterator(UnaryFunction const& f) :
: m_f(f) {} m_f(f)
{}
output_proxy operator*() { return output_proxy(m_f); } output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; } function_output_iterator& operator++() { return *this; }
self& operator++(int) { return *this; } function_output_iterator& operator++(int) { return *this; }
private: private:
UnaryFunction m_f; UnaryFunction m_f;
}; };
template <class UnaryFunction> template< typename UnaryFunction >
inline function_output_iterator<UnaryFunction> inline function_output_iterator< UnaryFunction > make_function_output_iterator(UnaryFunction const& f = UnaryFunction())
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) { {
return function_output_iterator< UnaryFunction >(f); return function_output_iterator< UnaryFunction >(f);
} }
@ -79,4 +86,4 @@ using iterators::make_function_output_iterator;
} // namespace boost } // namespace boost
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP #endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_

View File

@ -58,6 +58,7 @@ test-suite iterator
[ run function_input_iterator_test.cpp ] [ run function_input_iterator_test.cpp ]
[ run function_output_iterator_test.cpp ] [ run function_output_iterator_test.cpp ]
[ compile-fail function_output_iterator_cf.cpp ] [ compile-fail function_output_iterator_cf.cpp ]
[ compile-fail function_output_iterator_def_ctor_cf.cpp ]
[ run generator_iterator_test.cpp ] [ run generator_iterator_test.cpp ]

View File

@ -0,0 +1,14 @@
// Copyright 2025 (c) Andrey Semashev
// 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)
#include <boost/iterator/function_output_iterator.hpp>
int main()
{
boost::iterators::function_output_iterator< void (*)(int) > it;
(void)it;
return 0;
}