Add get_allocator_pointer

This commit is contained in:
Glen Fernandes
2021-12-15 22:40:41 -05:00
parent 8f40bff2f6
commit 6716193d9c
4 changed files with 279 additions and 2 deletions

View File

@ -1,5 +1,5 @@
////
Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com)
Copyright 2019-2021 Glen Joseph Fernandes (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@ -85,6 +85,11 @@ namespace boost {
template<class T, class A>
std::unique_ptr<remove_extent_t<T>[], alloc_noinit_deleter<T, A>>
allocate_unique_noinit(const A& a);
template<class T, class U, class A>
allocator_pointer_t<allocator_rebind_t<A, remove_cv_t<remove_extent_t<T>>>>
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A>>& p) noexcept;
}
```
@ -269,6 +274,18 @@ Returns:: A `std::unique_ptr` to a sequence of `extent_v<T>`
default-initialized objects of type `remove_extent_t<T>`.
Example:: `auto p = allocate_unique_noinit<double[1024]>(a);`
```
template<class T, class U, class A>
allocator_pointer_t<allocator_rebind_t<A, remove_cv_t<remove_extent_t<T>>>>
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A>>& p) noexcept;
```
[none]
* {blank}
+
Returns:: The allocator pointer to the allocation.
Example:: `auto r = boost::get_allocator_ptr(p.release());`
## Deleter
Class template `alloc_deleter` is the deleter used by the `allocate_unique`

View File

@ -1,5 +1,5 @@
/*
Copyright 2019 Glen Joseph Fernandes
Copyright 2019-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@ -477,6 +477,15 @@ allocate_unique(const A& alloc,
return c.release();
}
template<class T, class U, class A>
inline typename allocator_pointer<typename allocator_rebind<A,
typename detail::sp_alloc_value<T>::type>::type>::type
get_allocator_pointer(const std::unique_ptr<T,
alloc_deleter<U, A> >& p) BOOST_NOEXCEPT
{
return p.get().ptr();
}
} /* boost */
#endif

View File

@ -352,6 +352,7 @@ run allocate_unique_noinit_test.cpp ;
run allocate_unique_test.cpp ;
run allocate_unique_throws_test.cpp ;
run allocate_unique_value_test.cpp ;
run get_allocator_pointer_test.cpp ;
run sp_guides_test.cpp ;
run sp_guides_test2.cpp ;

View File

@ -0,0 +1,250 @@
/*
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (!defined(BOOST_LIBSTDCXX_VERSION) || \
BOOST_LIBSTDCXX_VERSION >= 46000) && \
!defined(BOOST_NO_CXX11_SMART_PTR)
#include <boost/smart_ptr/allocate_unique.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
class point {
public:
point()
: state_()
, ptr_() { }
point(int count, T* value)
: state_(count)
, ptr_(value) { }
operator bool() const {
return static_cast<bool>(ptr_);
}
T* operator->() const {
return ptr_;
}
int state() const {
return state_;
}
private:
int state_;
T* ptr_;
};
template<class T = void>
class creator {
public:
typedef T value_type;
typedef point<T> pointer;
typedef std::ptrdiff_t difference_type;
creator()
: state_() { }
explicit creator(int value)
: state_(value) { }
template<class U>
creator(const creator<U>& other)
: state_(other.state()) { }
pointer allocate(std::size_t size) {
return pointer(state_,
static_cast<T*>(::operator new(sizeof(T) * size)));
}
void deallocate(pointer ptr, std::size_t) {
::operator delete(ptr.operator->());
}
int state() const {
return state_;
}
private:
int state_;
};
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
int main()
{
{
std::unique_ptr<int,
boost::alloc_deleter<int, creator<> > > result =
boost::allocate_unique<int>(creator<>(1));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 1);
}
{
std::unique_ptr<const int,
boost::alloc_deleter<const int, creator<> > > result =
boost::allocate_unique<const int>(creator<>(2));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 2);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[], creator<> > > result =
boost::allocate_unique<int[]>(creator<>(3), 3);
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 3);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[3], creator<> > > result =
boost::allocate_unique<int[3]>(creator<>(4));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 4);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[][2], creator<> > > result =
boost::allocate_unique<int[][2]>(creator<>(5), 2);
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 5);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[2][2], creator<> > > result =
boost::allocate_unique<int[2][2]>(creator<>(6));
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 6);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[], creator<> > > result =
boost::allocate_unique<const int[]>(creator<>(7), 3);
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 7);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[3], creator<> > > result =
boost::allocate_unique<const int[3]>(creator<>(8));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 8);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[][2], creator<> > > result =
boost::allocate_unique<const int[][2]>(creator<>(9), 2);
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 9);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[2][2], creator<> > > result =
boost::allocate_unique<const int[2][2]>(creator<>(10));
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 10);
}
{
std::unique_ptr<int,
boost::alloc_deleter<int,
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int>(creator<>(11));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 11);
}
{
std::unique_ptr<const int,
boost::alloc_deleter<const int,
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int>(creator<>(12));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 12);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int[]>(creator<>(13), 3);
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 13);
}
{
std::unique_ptr<int[],
boost::alloc_deleter<int[3],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int[3]>(creator<>(14));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 14);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int[][2]>(creator<>(15), 2);
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 15);
}
{
std::unique_ptr<int[][2],
boost::alloc_deleter<int[2][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<int[2][2]>(creator<>(16));
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 16);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[]>(creator<>(17), 3);
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 17);
}
{
std::unique_ptr<const int[],
boost::alloc_deleter<const int[3],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[3]>(creator<>(18));
point<int> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 18);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[][2]>(creator<>(19), 2);
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 19);
}
{
std::unique_ptr<const int[][2],
boost::alloc_deleter<const int[2][2],
boost::noinit_adaptor<creator<> > > > result =
boost::allocate_unique_noinit<const int[2][2]>(creator<>(20));
point<int[2]> ptr = boost::get_allocator_pointer(result);
BOOST_TEST_EQ(ptr.state(), 20);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif