Add C++14-style std::make_unique 'polyfill' for C++11
std::make_unique is a very useful part of the new C++ smart pointers ecosystem, as it allows one to dispense entirely with "new" and also provides exception safety in some cases when creating temporary variables. It also allows more concise code by avoiding repetition of the type: std::make_unique<TYPE>( args ); vs std::unique_ptr<TYPE>( new TYPE( args ) ); This commit adds a "polyfill" to provide std::make_unique when C++11 is enabled. The implementation is that submitted to the C++ committee, and is essentially how it is done in GCC for C++14. The intention is to allow KiCad to use this implementation when using C++11 and when C++14 or greater is a requirement, to remove this code and use the compiler implementation.
This commit is contained in:
parent
7863e70181
commit
89fe9d378c
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include <atomic>
|
||||
|
||||
// C++11 "polyfill" for the C++14 std::make_unique function
|
||||
#include "make_unique.h"
|
||||
|
||||
class wxAboutDialogInfo;
|
||||
class SEARCH_STACK;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file make_unique.h
|
||||
* @brief Implementation of std::make_unique for pre C++14 compilation
|
||||
* environments
|
||||
*/
|
||||
|
||||
#ifndef MAKE_UNIQUE_H
|
||||
#define MAKE_UNIQUE_H
|
||||
|
||||
// Define std::make_unique if the compiler is C++11, but not C++14
|
||||
// (which provides this itself)
|
||||
// When C++14 support is a KiCad pre-requisite, this entire file
|
||||
// can be removed.
|
||||
#if __cplusplus == 201103L
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
// It's a bit naughty to add things to std::, but the point is to
|
||||
// "polyfill" this function in only if std:: doesn't have it
|
||||
//
|
||||
// This implementation is the one proposed by Stephan T. Lavavej
|
||||
// in N3656: https://isocpp.org/files/papers/N3656.txt
|
||||
// This is more or less exactly how it is implemented in GCC (e.g. 6.3.1)
|
||||
// when C++14 is enabled.
|
||||
namespace std
|
||||
{
|
||||
template<class T> struct _Unique_if {
|
||||
typedef unique_ptr<T> _Single_object;
|
||||
};
|
||||
|
||||
template<class T> struct _Unique_if<T[]> {
|
||||
typedef unique_ptr<T[]> _Unknown_bound;
|
||||
};
|
||||
|
||||
template<class T, size_t N> struct _Unique_if<T[N]> {
|
||||
typedef void _Known_bound;
|
||||
};
|
||||
|
||||
/// std::make_unique for single objects
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Single_object
|
||||
make_unique(Args&&... args) {
|
||||
return unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
/// std::make_unique for arrays of unknown bound
|
||||
template<class T>
|
||||
typename _Unique_if<T>::_Unknown_bound
|
||||
make_unique(size_t n) {
|
||||
typedef typename remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new U[n]());
|
||||
}
|
||||
|
||||
/// Disable std::make_unique for arrays of known bound
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Known_bound
|
||||
make_unique(Args&&...) = delete;
|
||||
}
|
||||
|
||||
#endif // __cplusplus == 201103L
|
||||
|
||||
#endif // WXSTRUCT_H_
|
Loading…
Reference in New Issue