59 lines
1.7 KiB
C++
59 lines
1.7 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* Copyright 2021, Danny Robson <danny@nerdcruft.net>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <iterator>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace cruft::iterator {
|
|
/// An output iterator that calls placement new on a supplied pointer
|
|
/// during assignment.
|
|
///
|
|
/// This simplifies usage of uninitialised arrays with STL algorithms.
|
|
template <typename PointerT>
|
|
struct placement_output {
|
|
public:
|
|
static_assert (std::is_pointer_v<PointerT>);
|
|
|
|
using iterator_category = std::output_iterator_tag;
|
|
using value_type = void;
|
|
using difference_type = void;
|
|
using pointer = void;
|
|
using reference = void;
|
|
|
|
placement_output (PointerT _cursor)
|
|
: m_cursor (_cursor)
|
|
{ ; }
|
|
|
|
placement_output& operator++ () { ++m_cursor; return *this; }
|
|
placement_output& operator * () { return *this; }
|
|
placement_output& operator-> () { return this; }
|
|
|
|
template <typename ValueT>
|
|
placement_output&
|
|
operator= (ValueT &&val)
|
|
{
|
|
new (m_cursor) bare_type (std::forward<ValueT> (val));
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
using bare_type = std::remove_pointer_t<PointerT>;
|
|
|
|
PointerT m_cursor;
|
|
};
|
|
|
|
|
|
template <typename PointerT>
|
|
placement_output (PointerT) -> placement_output<std::remove_reference_t<PointerT>>;
|
|
}
|