/* * 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 */ #pragma once #include #include #include /////////////////////////////////////////////////////////////////////////////// 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 struct placement_output { public: static_assert (std::is_pointer_v); 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 placement_output& operator= (ValueT &&val) { new (m_cursor) bare_type (std::forward (val)); return *this; } private: using bare_type = std::remove_pointer_t; PointerT m_cursor; }; template placement_output (PointerT) -> placement_output>; }