/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Helper to enable inplace construction and destruction of objects #ifndef CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H #define CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H #pragma once // Inspired by the boost inplace/typed_inplace factory, written by // Fernando Luis Cacciola Carballal and Tobias Schwinger // // See // http://www.boost.org/doc/libs/1_42_0/libs/utility/in_place_factories.html // for a detailed description // class CInplaceFactory0 { public: explicit CInplaceFactory0() {} template void* apply(void* address) const { return new(address) T(); } template void* apply(void* address, std::size_t n) const { for (char* next = address = this->template apply(address); !!--n; ) { this->template apply(next = next + sizeof(T)); } return address; } }; template < typename Arg0 > class CInplaceFactory1 { Arg0& m_Arg0; public: explicit CInplaceFactory1(Arg0& arg) : m_Arg0(arg) {} template void* apply(void* address) const { return new(address) T(m_Arg0); } template void* apply(void* address, std::size_t n) const { for (char* next = address = this->template apply(address); !!--n; ) { this->template apply(next = next + sizeof(T)); } return address; } }; template < typename Arg0, typename Arg1 > class CInplaceFactory2 { Arg0& m_Arg0; Arg1& m_Arg1; public: explicit CInplaceFactory2(Arg0& arg0, Arg1& arg1) : m_Arg0(arg0) , m_Arg1(arg1) {} template void* apply(void* address) const { return new(address) T( m_Arg0, m_Arg1); } template void* apply(void* address, std::size_t n) const { for (char* next = address = this->template apply(address); !!--n; ) { this->template apply(next = next + sizeof(T)); } return address; } }; template < typename Arg0, typename Arg1, typename Arg2 > class CInplaceFactory3 { Arg0& m_Arg0; Arg1& m_Arg1; Arg2& m_Arg2; public: explicit CInplaceFactory3(Arg0& arg0, Arg1& arg1, Arg2& arg2) : m_Arg0(arg0) , m_Arg1(arg1) , m_Arg2(arg2) {} template void* apply(void* address) const { return new(address) T( m_Arg0, m_Arg1, m_Arg2); } template void* apply(void* address, std::size_t n) const { for (char* next = address = this->template apply(address); !!--n; ) { this->template apply(next = next + sizeof(T)); } return address; } }; template < typename Arg0, typename Arg1, typename Arg2, typename Arg3 > class CInplaceFactory4 { Arg0& m_Arg0; Arg1& m_Arg1; Arg2& m_Arg2; Arg3& m_Arg3; public: explicit CInplaceFactory4(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3) : m_Arg0(arg0) , m_Arg1(arg1) , m_Arg2(arg2) , m_Arg3(arg3) {} template void* apply(void* address) const { return new(address) T( m_Arg0, m_Arg1, m_Arg2, m_Arg3); } template void* apply(void* address, std::size_t n) const { for (char* next = address = this->template apply(address); !!--n; ) { this->template apply(next = next + sizeof(T)); } return address; } }; template < typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4 > class CInplaceFactory5 { Arg0& m_Arg0; Arg1& m_Arg1; Arg2& m_Arg2; Arg3& m_Arg3; Arg4& m_Arg4; public: explicit CInplaceFactory5(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4) : m_Arg0(arg0) , m_Arg1(arg1) , m_Arg2(arg2) , m_Arg3(arg3) , m_Arg4(arg4) {} template void* apply(void* address) const { return new(address) T( m_Arg0, m_Arg1, m_Arg2, m_Arg3, m_Arg4); } template void* apply(void* address, std::size_t n) const { for (char* next = address = this->template apply(address); !!--n; ) { this->template apply(next = next + sizeof(T)); } return address; } }; inline CInplaceFactory0 InplaceFactory() { return CInplaceFactory0(); } template < typename Arg0 > inline CInplaceFactory1 InplaceFactory(Arg0& arg0) { return CInplaceFactory1(arg0); } template < typename Arg0, typename Arg1 > inline CInplaceFactory2 InplaceFactory(Arg0& arg0, Arg1& arg1) { return CInplaceFactory2(arg0, arg1); } template < typename Arg0, typename Arg1, typename Arg2 > inline CInplaceFactory3 InplaceFactory(Arg0& arg0, Arg1& arg1, Arg2& arg2) { return CInplaceFactory3 (arg0, arg1, arg2); } template < typename Arg0, typename Arg1, typename Arg2, typename Arg3 > inline CInplaceFactory4 InplaceFactory( Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3) { return CInplaceFactory4(arg0, arg1, arg2, arg3); } template < typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4 > inline CInplaceFactory5 InplaceFactory( Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4) { return CInplaceFactory5(arg0, arg1, arg2, arg3, arg4); } #endif // CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H