1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * Copyright (C) 2016 Kernkonzept GmbH.
4 * Author(s): Philipp Eppelt <philipp.eppelt@kernkonzept.com>
5 *
6 * This file is distributed under the terms of the GNU General Public
7 * License, version 2. Please see the COPYING-GPL-2 file for details.
8 *
9 * As a special exception, you may use this file as part of a free software
10 * library without restriction. Specifically, if other files instantiate
11 * templates or use macros or inline functions from this file, or you compile
12 * this file and link it with other files to produce an executable, this
13 * file does not by itself cause the resulting executable to be covered by
14 * the GNU General Public License. This exception does not however
15 * invalidate any other reasons why the executable file might be covered by
16 * the GNU General Public License.
17 */
18#pragma once
19
20#include <memory>
21#include <utility>
22
23namespace std { namespace L4 {
24
25template <typename T>
26struct _Make_unique
27{ using __single = ::std::unique_ptr<T>; };
28
29template <typename T>
30struct _Make_unique<T[]>
31{ using __array = ::std::unique_ptr<T[]>; };
32
33template <typename T, size_t SIZE>
34struct _Make_unique<T[SIZE]>
35{ struct __invalid { }; };
36
37/// Create an object of type `T` and return it inside a std::unique_ptr.
38template <typename T, typename... Args>
39inline typename _Make_unique<T>::__single
40make_unique(Args &&... args)
41{
42  return ::std::unique_ptr<T>(new T(::std::forward<Args>(args)...));
43}
44
45/// Allocate an array of type `T` and return it inside a std::unique_ptr.
46template <typename T>
47inline typename _Make_unique<T>::__array
48make_unique(std::size_t size)
49{
50  return ::std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
51}
52
53/// Disable std::make_unqiue for arrays of known bound.
54template <typename T, typename... Args>
55inline typename _Make_unique<T>::__invalid
56make_unique(Args &&...) = delete;
57}} // namespace L4, namespace std
58