/** This file is a part of rexy's general purpose library Copyright (C) 2022 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef REXY_STORAGE_FOR_TPP #define REXY_STORAGE_FOR_TPP #include //forward, move namespace rexy{ template template constexpr storage_for::storage_for(Args&&... args)noexcept(std::is_nothrow_constructible::value){ new (m_storage) T(std::forward(args)...); m_dirty = 1; } template constexpr storage_for::storage_for(const_reference t)noexcept(std::is_nothrow_copy_constructible::value){ new (m_storage) T(t); m_dirty = 1; } template constexpr storage_for::storage_for(rvalue_reference t)noexcept(std::is_nothrow_move_constructible::value){ new (m_storage) T(std::move(t)); m_dirty = 1; } template constexpr storage_for::storage_for(const storage_for& s)noexcept(std::is_nothrow_copy_constructible::value){ new (m_storage) T(reinterpret_cast(s.m_storage)); m_dirty = 1; } template constexpr storage_for::storage_for(storage_for&& s)noexcept(std::is_nothrow_move_constructible::value){ new (m_storage) T(std::move(reinterpret_cast(&s.m_storage))); m_dirty = 1; } template constexpr storage_for::~storage_for(void)noexcept(std::is_nothrow_destructible::value){ if(m_dirty){ destroy(); } } template constexpr storage_for& storage_for::operator=(const storage_for& s)noexcept(std::is_nothrow_copy_assignable::value){ reinterpret_cast(m_storage) = static_cast(s); return *this; } template constexpr storage_for& storage_for::operator=(storage_for&& s)noexcept(std::is_nothrow_move_assignable::value){ reinterpret_cast(m_storage) = static_cast(std::move(s)); return *this; } template constexpr storage_for& storage_for::operator=(const_reference t)noexcept(std::is_nothrow_copy_assignable::value){ reinterpret_cast(m_storage) = t; return *this; } template constexpr storage_for& storage_for::operator=(rvalue_reference t)noexcept(std::is_nothrow_move_assignable::value){ reinterpret_cast(m_storage) = std::move(t); return *this; } template constexpr void storage_for::destroy(void)noexcept(std::is_nothrow_destructible::value){ reinterpret_cast(&m_storage)->~T(); m_dirty = 0; } template constexpr storage_for::operator reference(void)noexcept{ return reinterpret_cast(m_storage); } template constexpr storage_for::operator const_reference(void)const noexcept{ return m_storage; } template constexpr storage_for::operator rvalue_reference(void)&& noexcept{ return reinterpret_cast(std::move(m_storage)); } template constexpr auto storage_for::operator->(void)noexcept -> pointer{ return reinterpret_cast(&m_storage); } template constexpr auto storage_for::operator->(void)const noexcept -> const_pointer{ return reinterpret_cast(&m_storage); } template constexpr auto storage_for::operator*(void)noexcept -> reference{ return reinterpret_cast(m_storage); } template constexpr auto storage_for::operator*(void)const noexcept -> const_reference{ return reinterpret_cast(m_storage); } template constexpr bool storage_for::valid(void)const{ return m_dirty; } } #endif