Add make_unique for arrays and objects

This commit is contained in:
Glen Fernandes
2014-01-28 03:58:51 -08:00
parent 87e5debdc2
commit 7806737b52
13 changed files with 732 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP
#include <memory>
namespace boost {
namespace detail {
template<typename T>
struct up_if_array;
template<typename T>
struct up_if_array<T[]> {
typedef std::unique_ptr<T[]> type;
};
}
}
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
#define BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP
#include <memory>
namespace boost {
namespace detail {
template<typename T>
struct up_if_not_array {
typedef std::unique_ptr<T> type;
};
template<typename T>
struct up_if_not_array<T[]> {
};
template<typename T, std::size_t N>
struct up_if_not_array<T[N]> {
};
}
}
#endif

View File

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
#include <boost/smart_ptr/make_unique_array.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
#endif

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP
#include <boost/smart_ptr/detail/up_if_array.hpp>
#include <boost/smart_ptr/detail/array_traits.hpp>
namespace boost {
template<typename T>
inline typename boost::detail::up_if_array<T>::type
make_unique(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type U;
return std::unique_ptr<T>(new U[size]());
}
template<typename T>
inline typename boost::detail::up_if_array<T>::type
make_unique_noinit(std::size_t size) {
typedef typename boost::detail::array_inner<T>::type U;
return std::unique_ptr<T>(new U[size]);
}
}
#endif

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP
#define BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/up_if_not_array.hpp>
namespace boost {
template<typename T>
inline typename boost::detail::up_if_not_array<T>::type
make_unique() {
return std::unique_ptr<T>(new T());
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename T, typename... Args>
inline typename boost::detail::up_if_not_array<T>::type
make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
#endif
template<typename T>
inline typename boost::detail::up_if_not_array<T>::type
make_unique_noinit() {
return std::unique_ptr<T>(new T);
}
}
#endif

View File

@@ -148,5 +148,13 @@ import testing ;
[ run allocate_shared_array_esft_test.cpp ]
[ run allocate_shared_array_noinit_test.cpp ]
[ run allocate_shared_array_value_test.cpp ]
[ run make_unique_test.cpp ]
[ run make_unique_args_test.cpp ]
[ run make_unique_noinit_test.cpp ]
[ run make_unique_throws_test.cpp ]
[ run make_unique_array_test.cpp ]
[ run make_unique_array_noinit_test.cpp ]
[ run make_unique_array_throws_test.cpp ]
;
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class type {
public:
static unsigned int instances;
explicit type(int v1 = 0,
int v2 = 0,
int v3 = 0,
int v4 = 0,
int v5 = 0,
int v6 = 0,
int v7 = 0,
int v8 = 0,
int v9 = 0)
: sum(v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9) {
instances++;
}
~type() {
instances--;
}
const int sum;
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type> a1 = boost::make_unique<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 0);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3, 4);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6, 7);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6, 7, 8);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
a1.reset();
BOOST_TEST(type::instances == 0);
}
{
std::unique_ptr<const type> a1 = boost::make_unique<type>(1, 2, 3, 4, 5, 6, 7, 8, 9);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
BOOST_TEST(a1->sum == 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#endif
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_array.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
{
std::unique_ptr<int[]> a1 = boost::make_unique_noinit<int[]>(3);
BOOST_TEST(a1.get() != 0);
}
{
std::unique_ptr<int[][2]> a1 = boost::make_unique_noinit<int[][2]>(2);
BOOST_TEST(a1.get() != 0);
}
{
std::unique_ptr<const int[]> a1 = boost::make_unique_noinit<const int[]>(3);
BOOST_TEST(a1.get() != 0);
}
{
std::unique_ptr<const int[][2]> a1 = boost::make_unique_noinit<const int[][2]>(2);
BOOST_TEST(a1.get() != 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[]> a1 = boost::make_unique_noinit<type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[][2]> a1 = boost::make_unique_noinit<type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[]> a1 = boost::make_unique_noinit<const type[]>(3);
const type* a2 = a1.get();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[][2]> a1 = boost::make_unique_noinit<const type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_array.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
{
std::unique_ptr<int[]> a1 = boost::make_unique<int[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0] == 0);
BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0);
}
{
std::unique_ptr<int[][2]> a1 = boost::make_unique<int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
{
std::unique_ptr<const int[]> a1 = boost::make_unique<const int[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0] == 0);
BOOST_TEST(a1[1] == 0);
BOOST_TEST(a1[2] == 0);
}
{
std::unique_ptr<const int[][2]> a1 = boost::make_unique<const int[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(a1[0][0] == 0);
BOOST_TEST(a1[0][1] == 0);
BOOST_TEST(a1[1][0] == 0);
BOOST_TEST(a1[1][1] == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[]> a1 = boost::make_unique<type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type[][2]> a1 = boost::make_unique<type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[]> a1 = boost::make_unique<const type[]>(3);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 3);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type[][2]> a1 = boost::make_unique<const type[][2]>(2);
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 4);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_array.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
if (instances == 5) {
throw true;
}
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
BOOST_TEST(type::instances == 0);
try {
boost::make_unique<type[]>(6);
BOOST_ERROR("make_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_unique<type[][2]>(3);
BOOST_ERROR("make_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_unique_noinit<type[]>(6);
BOOST_ERROR("make_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
try {
boost::make_unique_noinit<type[][2]>(3);
BOOST_ERROR("make_unique_noinit did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2012-2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
{
std::unique_ptr<int> a1 = boost::make_unique_noinit<int>();
BOOST_TEST(a1.get() != 0);
}
{
std::unique_ptr<const int> a1 = boost::make_unique_noinit<const int>();
BOOST_TEST(a1.get() != 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type> a1 = boost::make_unique_noinit<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type> a1 = boost::make_unique_noinit<const type>();
const type* a2 = a1.get();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}

65
test/make_unique_test.cpp Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
{
std::unique_ptr<int> a1 = boost::make_unique<int>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(*a1 == 0);
}
{
std::unique_ptr<const int> a1 = boost::make_unique<const int>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(*a1 == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<type> a1 = boost::make_unique<type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
BOOST_TEST(type::instances == 0);
{
std::unique_ptr<const type> a1 = boost::make_unique<const type>();
BOOST_TEST(a1.get() != 0);
BOOST_TEST(type::instances == 1);
a1.reset();
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2014 Glen Joseph Fernandes
* glenfe at live dot com
*
* Distributed under the Boost Software License,
* Version 1.0. (See accompanying file LICENSE_1_0.txt
* or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/smart_ptr/make_unique_object.hpp>
class type {
public:
static unsigned int instances;
explicit type() {
if (instances == 0) {
throw true;
}
instances++;
}
~type() {
instances--;
}
private:
type(const type&);
type& operator=(const type&);
};
unsigned int type::instances = 0;
int main() {
#if !defined(BOOST_NO_CXX11_SMART_PTR)
BOOST_TEST(type::instances == 0);
try {
boost::make_unique<type>();
BOOST_ERROR("make_unique did not throw");
} catch (...) {
BOOST_TEST(type::instances == 0);
}
#endif
return boost::report_errors();
}