forked from Mirrors/openclonk
Add emulation of C++14's std::make_unique
Unlike std::make_shared, std::make_unique was unfortunately missing from C++11. It's a useful utility though. Technically, declaring a new name in the std namespace is undefined, but the other way to make make_unique available to all callers regardless of C++ version, putting it into a distinct utility namespace and importing the declaration from std if available, makes for more ugly code.stable-6.1
parent
e5e5665294
commit
db295b8678
|
@ -89,6 +89,8 @@ REQUIRE_CXX_SOURCE_COMPILES("#include <memory>\nint main() { std::unique_ptr<int
|
|||
CHECK_CXX_SOURCE_COMPILES("void f(struct D&&); int main() { return 0; }" HAVE_RVALUE_REF)
|
||||
CHECK_CXX_SOURCE_COMPILES("int main() { void *d = nullptr; }" HAVE_NULLPTR)
|
||||
CHECK_CXX_SOURCE_COMPILES("int main() { static_assert(true, \"\"); }" HAVE_STATIC_ASSERT)
|
||||
CHECK_CXX_SOURCE_COMPILES("#include <memory>\nint main() { auto a = std::make_unique<int>(0); }" HAVE_MAKE_UNIQUE)
|
||||
CHECK_CXX_SOURCE_COMPILES("template<class... T> class C; int main() { return 0; }" HAVE_VARIADIC_TEMPLATES)
|
||||
|
||||
# g++'s libstdc++ doesn't properly support <regex> until 4.9.
|
||||
# They ship a header that declares functions, but they don't ship an
|
||||
|
@ -1031,6 +1033,7 @@ src/platform/StdSchedulerPoll.cpp
|
|||
src/platform/StdScheduler.h
|
||||
src/platform/C4TimeMilliseconds.cpp
|
||||
src/platform/C4TimeMilliseconds.h
|
||||
src/platform/make_unique.h
|
||||
src/zlib/gzio.c
|
||||
src/zlib/gzio.h
|
||||
src/zlib/zutil.h
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#cmakedefine HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if your stdlib has std::make_unique */
|
||||
#cmakedefine HAVE_MAKE_UNIQUE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#cmakedefine HAVE_MEMORY_H 1
|
||||
|
||||
|
@ -100,6 +103,9 @@
|
|||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if your compiler supports variadic templates */
|
||||
#cmakedefine HAVE_VARIADIC_TEMPLATES 1
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
#cmakedefine HAVE_VASPRINTF 1
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@ typedef ptrdiff_t ssize_t;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// std::make_unique
|
||||
#include "platform/make_unique.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// Allow checks for correct printf-usage
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2015, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
#ifndef INC_make_unique
|
||||
#define INC_make_unique
|
||||
|
||||
#include "config.h"
|
||||
|
||||
// C++14 std::make_unique
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#ifndef HAVE_MAKE_UNIQUE
|
||||
namespace detail {
|
||||
template<class T>
|
||||
typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, std::unique_ptr<T>>::type
|
||||
make_unique(size_t n)
|
||||
{
|
||||
return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
|
||||
}
|
||||
|
||||
#ifdef HAVE_VARIADIC_TEMPLATES
|
||||
template<class T, class ...Args>
|
||||
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
|
||||
make_unique(Args &&...args)
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
#else
|
||||
// We have to emulate variadic templates with preprocessor trickery.
|
||||
// Create a number of overloaded functions that handle this just like the
|
||||
// one function above. Works for up to _VARIADIC_MAX constructor arguments
|
||||
// (if you need more than 5, define that macro before including this header).
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
// This is the same macro that the MSVC STL also uses when it has to emulate
|
||||
// variadic templates, so it should work fine for our purposes
|
||||
#ifndef _VARIADIC_MAX
|
||||
#define _VARIADIC_MAX 5
|
||||
#endif
|
||||
|
||||
#define MAKE_UNIQUE_FORWARDER(z, n, unused) std::forward<Arg ## n>(arg ## n)
|
||||
#define MAKE_UNIQUE_MAKER(z, n, unused) \
|
||||
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class Arg)> \
|
||||
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type make_unique(BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, &&arg)) \
|
||||
{ \
|
||||
return std::unique_ptr<T>(new T(BOOST_PP_ENUM(n, MAKE_UNIQUE_FORWARDER, unused))); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(_VARIADIC_MAX), MAKE_UNIQUE_MAKER, unused)
|
||||
#undef MAKE_UNIQUE_MAKER
|
||||
#undef MAKE_UNIQUE_FORWARDER
|
||||
#endif
|
||||
}
|
||||
namespace std { using ::detail::make_unique; }
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue