You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
6.3 KiB
C++
311 lines
6.3 KiB
C++
/*
|
|
* 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<class T>
|
|
void* apply(void* address) const
|
|
{
|
|
return new(address) T();
|
|
}
|
|
|
|
template<class T>
|
|
void* apply(void* address, std::size_t n) const
|
|
{
|
|
for (char* next = address = this->template apply<T>(address); !!--n; )
|
|
{
|
|
this->template apply<T>(next = next + sizeof(T));
|
|
}
|
|
return address;
|
|
}
|
|
};
|
|
|
|
template < typename Arg0 >
|
|
class CInplaceFactory1
|
|
{
|
|
Arg0& m_Arg0;
|
|
|
|
public:
|
|
|
|
explicit CInplaceFactory1(Arg0& arg)
|
|
: m_Arg0(arg)
|
|
{}
|
|
|
|
template<class T>
|
|
void* apply(void* address) const
|
|
{
|
|
return new(address) T(m_Arg0);
|
|
}
|
|
|
|
template<class T>
|
|
void* apply(void* address, std::size_t n) const
|
|
{
|
|
for (char* next = address = this->template apply<T>(address); !!--n; )
|
|
{
|
|
this->template apply<T>(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<class T>
|
|
void* apply(void* address) const
|
|
{
|
|
return new(address) T(
|
|
m_Arg0,
|
|
m_Arg1);
|
|
}
|
|
|
|
template<class T>
|
|
void* apply(void* address, std::size_t n) const
|
|
{
|
|
for (char* next = address = this->template apply<T>(address); !!--n; )
|
|
{
|
|
this->template apply<T>(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<class T>
|
|
void* apply(void* address) const
|
|
{
|
|
return new(address) T(
|
|
m_Arg0,
|
|
m_Arg1,
|
|
m_Arg2);
|
|
}
|
|
|
|
template<class T>
|
|
void* apply(void* address, std::size_t n) const
|
|
{
|
|
for (char* next = address = this->template apply<T>(address); !!--n; )
|
|
{
|
|
this->template apply<T>(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<class T>
|
|
void* apply(void* address) const
|
|
{
|
|
return new(address) T(
|
|
m_Arg0,
|
|
m_Arg1,
|
|
m_Arg2,
|
|
m_Arg3);
|
|
}
|
|
|
|
template<class T>
|
|
void* apply(void* address, std::size_t n) const
|
|
{
|
|
for (char* next = address = this->template apply<T>(address); !!--n; )
|
|
{
|
|
this->template apply<T>(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<class T>
|
|
void* apply(void* address) const
|
|
{
|
|
return new(address) T(
|
|
m_Arg0,
|
|
m_Arg1,
|
|
m_Arg2,
|
|
m_Arg3,
|
|
m_Arg4);
|
|
}
|
|
|
|
template<class T>
|
|
void* apply(void* address, std::size_t n) const
|
|
{
|
|
for (char* next = address = this->template apply<T>(address); !!--n; )
|
|
{
|
|
this->template apply<T>(next = next + sizeof(T));
|
|
}
|
|
return address;
|
|
}
|
|
};
|
|
|
|
inline CInplaceFactory0 InplaceFactory()
|
|
{
|
|
return CInplaceFactory0();
|
|
}
|
|
|
|
template < typename Arg0 >
|
|
inline CInplaceFactory1<Arg0> InplaceFactory(Arg0& arg0)
|
|
{
|
|
return CInplaceFactory1<Arg0>(arg0);
|
|
}
|
|
|
|
template
|
|
<
|
|
typename Arg0,
|
|
typename Arg1
|
|
|
|
>
|
|
inline CInplaceFactory2<Arg0, Arg1> InplaceFactory(Arg0& arg0, Arg1& arg1)
|
|
{
|
|
return CInplaceFactory2<Arg0, Arg1>(arg0, arg1);
|
|
}
|
|
|
|
template
|
|
<
|
|
typename Arg0,
|
|
typename Arg1,
|
|
typename Arg2
|
|
>
|
|
inline CInplaceFactory3<Arg0, Arg1, Arg2> InplaceFactory(Arg0& arg0, Arg1& arg1, Arg2& arg2)
|
|
{
|
|
return CInplaceFactory3<Arg0, Arg1, Arg2> (arg0, arg1, arg2);
|
|
}
|
|
|
|
|
|
template
|
|
<
|
|
typename Arg0,
|
|
typename Arg1,
|
|
typename Arg2,
|
|
typename Arg3
|
|
>
|
|
inline CInplaceFactory4<Arg0, Arg1, Arg2, Arg3> InplaceFactory(
|
|
Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3)
|
|
{
|
|
return CInplaceFactory4<Arg0, Arg1, Arg2, Arg3>(arg0, arg1, arg2, arg3);
|
|
}
|
|
|
|
|
|
template
|
|
<
|
|
typename Arg0,
|
|
typename Arg1,
|
|
typename Arg2,
|
|
typename Arg3,
|
|
typename Arg4
|
|
>
|
|
inline CInplaceFactory5<Arg0, Arg1, Arg2, Arg3, Arg4> InplaceFactory(
|
|
Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4)
|
|
{
|
|
return CInplaceFactory5<Arg0, Arg1, Arg2, Arg3, Arg4>(arg0, arg1, arg2, arg3, arg4);
|
|
}
|
|
|
|
#endif // CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|