diff --git a/include/boost/container/adaptive_pool.hpp b/include/boost/container/adaptive_pool.hpp
index a6a89fa..f620e6a 100644
--- a/include/boost/container/adaptive_pool.hpp
+++ b/include/boost/container/adaptive_pool.hpp
@@ -150,11 +150,13 @@ class adaptive_pool
//!Returns the number of elements that could be allocated.
//!Never throws
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return size_type(-1)/(2u*sizeof(T)); }
//!Allocate memory for an array of count elements.
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate(size_type count, const void * = 0)
{
if(BOOST_UNLIKELY(count > size_type(-1)/(2u*sizeof(T))))
@@ -187,6 +189,7 @@ class adaptive_pool
}
}
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocation_command(allocation_type command,
size_type limit_size,
size_type &prefer_in_recvd_out_size,
@@ -206,6 +209,7 @@ class adaptive_pool
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate_one()
{
typedef dtl::shared_adaptive_node_pool
@@ -317,11 +321,13 @@ class adaptive_pool
//!An allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
@@ -466,11 +472,13 @@ class private_adaptive_pool
//!Returns the number of elements that could be allocated.
//!Never throws
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return size_type(-1)/(2u*sizeof(T)); }
//!Allocate memory for an array of count elements.
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate(size_type count, const void * = 0)
{
if(BOOST_UNLIKELY(count > size_type(-1)/(2u*sizeof(T))))
@@ -497,6 +505,7 @@ class private_adaptive_pool
}
}
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocation_command(allocation_type command,
size_type limit_size,
size_type &prefer_in_recvd_out_size,
@@ -516,6 +525,7 @@ class private_adaptive_pool
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate_one()
{
return (pointer)m_pool.allocate_node();
@@ -583,11 +593,13 @@ class private_adaptive_pool
//!An allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator==(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator!=(const private_adaptive_pool &, const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
diff --git a/include/boost/container/allocator.hpp b/include/boost/container/allocator.hpp
index ddb96be..da19e0b 100644
--- a/include/boost/container/allocator.hpp
+++ b/include/boost/container/allocator.hpp
@@ -197,7 +197,7 @@ class allocator
//!Returns the maximum number of elements that could be allocated.
//!Never throws
- inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return size_type(-1)/(2u*sizeof(T)); }
//!Swaps two allocators, does nothing
diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp
index 7aad7b1..f32a3d0 100644
--- a/include/boost/container/allocator_traits.hpp
+++ b/include/boost/container/allocator_traits.hpp
@@ -423,6 +423,7 @@ struct allocator_traits
//! Returns: a.allocate(n)
//!
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline static pointer allocate(Allocator &a, size_type n)
{ return a.allocate(n); }
@@ -434,6 +435,7 @@ struct allocator_traits
//! Effects: calls a.allocate(n, p) if that call is well-formed;
//! otherwise, invokes a.allocate(n)
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline static pointer allocate(Allocator &a, size_type n, const_void_pointer p)
{
const bool value = boost::container::dtl::
@@ -458,6 +460,7 @@ struct allocator_traits
//! Returns: a.max_size() if that expression is well-formed; otherwise,
//! numeric_limits::max().
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
{
const bool value = allocator_traits_detail::has_max_size::value;
diff --git a/include/boost/container/new_allocator.hpp b/include/boost/container/new_allocator.hpp
index e6cbf71..464a7b7 100644
--- a/include/boost/container/new_allocator.hpp
+++ b/include/boost/container/new_allocator.hpp
@@ -151,6 +151,7 @@ class new_allocator
//!Allocates memory for an array of count elements.
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate(size_type count)
{
return dtl::operator_new_allocate(count);
@@ -165,6 +166,7 @@ class new_allocator
//!Returns the maximum number of elements that could be allocated.
//!Never throws
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return std::size_t(-1)/(2*sizeof(T)); }
@@ -175,11 +177,13 @@ class new_allocator
//!An new_allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An new_allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
};
diff --git a/include/boost/container/node_allocator.hpp b/include/boost/container/node_allocator.hpp
index 14c3754..71b178b 100644
--- a/include/boost/container/node_allocator.hpp
+++ b/include/boost/container/node_allocator.hpp
@@ -137,11 +137,13 @@ class node_allocator
//!Returns the number of elements that could be allocated.
//!Never throws
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
size_type max_size() const
{ return size_type(-1)/sizeof(T); }
//!Allocate memory for an array of count elements.
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate(size_type count, const void * = 0)
{
if(BOOST_UNLIKELY(count > this->max_size()))
@@ -186,6 +188,7 @@ class node_allocator
singleton_t::instance().deallocate_free_blocks();
}
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocation_command
(allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
@@ -198,6 +201,7 @@ class node_allocator
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_CONTAINER_STATIC_ASSERT(( Version > 1 ));
@@ -207,6 +211,7 @@ class node_allocator
//!Allocates just one object. Memory allocated with this function
//!must be deallocated only with deallocate_one().
//!Throws bad_alloc if there is no enough memory
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
pointer allocate_one()
{
BOOST_CONTAINER_STATIC_ASSERT(( Version > 1 ));
@@ -307,11 +312,13 @@ class node_allocator
//!An allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator==(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
diff --git a/include/boost/container/pmr/memory_resource.hpp b/include/boost/container/pmr/memory_resource.hpp
index 3eabc3e..5ca9196 100644
--- a/include/boost/container/pmr/memory_resource.hpp
+++ b/include/boost/container/pmr/memory_resource.hpp
@@ -62,11 +62,13 @@ class BOOST_CONTAINER_NOVTABLE memory_resource
//! Returns:
//! `&a == &b || a.is_equal(b)`.
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return &a == &b || a.is_equal(b); }
//! Returns:
//! !(a == b).
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return !(a == b); }
diff --git a/include/boost/container/pmr/monotonic_buffer_resource.hpp b/include/boost/container/pmr/monotonic_buffer_resource.hpp
index a52bbf8..c5e1c93 100644
--- a/include/boost/container/pmr/monotonic_buffer_resource.hpp
+++ b/include/boost/container/pmr/monotonic_buffer_resource.hpp
@@ -112,6 +112,7 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource
~monotonic_buffer_resource() BOOST_OVERRIDE;
//! Effects: `upstream_resource()->deallocate()` as necessary to release all allocated memory.
+ //! Resets *this to its initial state at construction.
//! [Note: memory is released back to `upstream_resource()` even if some blocks that were allocated
//! from this have not been deallocated from this. - end note]
void release() BOOST_NOEXCEPT;
diff --git a/include/boost/container/pmr/polymorphic_allocator.hpp b/include/boost/container/pmr/polymorphic_allocator.hpp
index e2ac7c4..cad9de2 100644
--- a/include/boost/container/pmr/polymorphic_allocator.hpp
+++ b/include/boost/container/pmr/polymorphic_allocator.hpp
@@ -78,7 +78,7 @@ class polymorphic_allocator
//! Returns: Equivalent to
//! `static_cast(m_resource->allocate(n * sizeof(T), alignof(T)))`.
- T* allocate(size_t n)
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD T* allocate(size_t n)
{ return static_cast(m_resource->allocate(n*sizeof(T), ::boost::move_detail::alignment_of::value)); }
//! Requires: p was allocated from a memory resource, x, equal to *m_resource,
diff --git a/include/boost/container/scoped_allocator.hpp b/include/boost/container/scoped_allocator.hpp
index 90e3406..0e51036 100644
--- a/include/boost/container/scoped_allocator.hpp
+++ b/include/boost/container/scoped_allocator.hpp
@@ -734,6 +734,7 @@ class scoped_allocator_adaptor
//! Returns:
//! allocator_traits:: max_size(outer_allocator()).
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return outer_traits_type::max_size(this->outer_allocator()); }
@@ -748,11 +749,13 @@ class scoped_allocator_adaptor
//! Returns:
//! allocator_traits::allocate(outer_allocator(), n).
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline pointer allocate(size_type n)
{ return outer_traits_type::allocate(this->outer_allocator(), n); }
//! Returns:
//! allocator_traits::allocate(outer_allocator(), n, hint).
+ BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline pointer allocate(size_type n, const_void_pointer hint)
{ return outer_traits_type::allocate(this->outer_allocator(), n, hint); }
@@ -880,6 +883,7 @@ struct scoped_allocator_operator_equal
/// @endcond
template
+BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline bool operator==(const scoped_allocator_adaptor& a
,const scoped_allocator_adaptor& b)
{
@@ -894,6 +898,7 @@ inline bool operator==(const scoped_allocator_adaptor
+BOOST_CONTAINER_ATTRIBUTE_NODISCARD
inline bool operator!=(const scoped_allocator_adaptor& a
,const scoped_allocator_adaptor& b)
{ return !(a == b); }
diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp
index 89cd714..e4ffc03 100644
--- a/test/allocator_traits_test.cpp
+++ b/test/allocator_traits_test.cpp
@@ -320,27 +320,36 @@ int main()
CAlloc c_alloc;
SAlloc s_alloc;
- //allocate
- CAllocTraits::allocate(c_alloc, 1);
- BOOST_TEST(c_alloc.allocate_called());
+ //allocate/deallocate
+ {
+ CAllocTraits::pointer p = CAllocTraits::allocate(c_alloc, 1);
+ BOOST_TEST(c_alloc.allocate_called());
- SAllocTraits::allocate(s_alloc, 1);
- BOOST_TEST(s_alloc.allocate_called());
+ CAllocTraits::deallocate(c_alloc, p, 1);
+ BOOST_TEST(c_alloc.deallocate_called());
+ }
+ {
+ SAllocTraits::pointer p = SAllocTraits::allocate(s_alloc, 1);
+ BOOST_TEST(s_alloc.allocate_called());
- //deallocate
- CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1);
- BOOST_TEST(c_alloc.deallocate_called());
-
- SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1);
- BOOST_TEST(s_alloc.deallocate_called());
+ SAllocTraits::deallocate(s_alloc, p, 1);
+ BOOST_TEST(s_alloc.deallocate_called());
+ }
//allocate with hint
- CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
- BOOST_TEST(c_alloc.allocate_hint_called());
-
- s_alloc.allocate_called_ = false;
- SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
- BOOST_TEST(s_alloc.allocate_called());
+ {
+ CAllocTraits::pointer p = CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
+ BOOST_TEST(c_alloc.allocate_hint_called());
+ CAllocTraits::deallocate(c_alloc, p, 1);
+ BOOST_TEST(c_alloc.deallocate_called());
+ }
+ {
+ s_alloc.allocate_called_ = false;
+ SAllocTraits::pointer p = SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
+ BOOST_TEST(s_alloc.allocate_called());
+ SAllocTraits::deallocate(s_alloc, p, 1);
+ BOOST_TEST(s_alloc.deallocate_called());
+ }
//destroy
float dummy;
@@ -350,7 +359,7 @@ int main()
SAllocTraits::destroy(s_alloc, &dummy);
//max_size
- CAllocTraits::max_size(c_alloc);
+ BOOST_TEST(0 != CAllocTraits::max_size(c_alloc));
BOOST_TEST(c_alloc.max_size_called());
BOOST_TEST(SAllocTraits::size_type(-1)/sizeof(SAllocTraits::value_type) == SAllocTraits::max_size(s_alloc));
diff --git a/test/global_resource_test.cpp b/test/global_resource_test.cpp
index 8535e09..0230d55 100644
--- a/test/global_resource_test.cpp
+++ b/test/global_resource_test.cpp
@@ -24,7 +24,7 @@ using namespace boost::container::pmr;
#pragma warning (disable : 4290)
#endif
-#if __cplusplus >= 201103L
+#if BOOST_CXX_VERSION >= 201103L
#define BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER
#define BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER noexcept
#else
@@ -71,7 +71,7 @@ void test_new_delete_resource()
#if !defined(BOOST_CONTAINER_DYNAMIC_LINKING) //No new delete replacement possible new_delete is a DLL
BOOST_TEST(memcount == allocation_count);
#endif
- void *addr = mr->allocate(16, 1);
+ void *const addr = mr->allocate(16, 1);
#if !defined(BOOST_CONTAINER_DYNAMIC_LINKING) //No new delete replacement possible new_delete is a DLL
BOOST_TEST((allocation_count - memcount) == 1);
#endif
@@ -90,8 +90,9 @@ void test_null_memory_resource()
#if !defined(BOOST_NO_EXCEPTIONS)
bool bad_allocexception_thrown = false;
+ void *p = 0;
BOOST_CONTAINER_TRY{
- mr->allocate(1, 1);
+ p = mr->allocate(1, 1);
}
BOOST_CONTAINER_CATCH(std::bad_alloc&) {
bad_allocexception_thrown = true;
@@ -101,6 +102,8 @@ void test_null_memory_resource()
BOOST_CONTAINER_CATCH_END
BOOST_TEST(bad_allocexception_thrown == true);
+ if(p)
+ mr->deallocate(p, 1, 1);
#endif //BOOST_NO_EXCEPTIONS
}
diff --git a/test/memory_resource_test.cpp b/test/memory_resource_test.cpp
index aad394a..0695b78 100644
--- a/test/memory_resource_test.cpp
+++ b/test/memory_resource_test.cpp
@@ -26,10 +26,11 @@ void test_allocate()
BOOST_TEST(d.do_allocate_bytes == 0);
BOOST_TEST(d.do_allocate_alignment == 0);
- mr.allocate(2, 4);
+ void *const p = mr.allocate(2, 4);
BOOST_TEST(d.do_allocate_called == true);
BOOST_TEST(d.do_allocate_bytes == 2);
BOOST_TEST(d.do_allocate_alignment == 4);
+ mr.deallocate(p, 2, 4);
}
void test_deallocate()
diff --git a/test/monotonic_buffer_resource_test.cpp b/test/monotonic_buffer_resource_test.cpp
index 4923e24..33e3a7b 100644
--- a/test/monotonic_buffer_resource_test.cpp
+++ b/test/monotonic_buffer_resource_test.cpp
@@ -431,8 +431,10 @@ void test_release()
memory_resource &mr = monr;
BOOST_TEST(monr.remaining_storage(1u) == sizeof(buf));
//Allocate all remaining storage
- mr.allocate(monr.remaining_storage(1u), 1u);
+ const std::size_t sz = monr.remaining_storage(1u);
+ void *const p = mr.allocate(sz, 1u);
BOOST_TEST(monr.current_buffer() == ((char*)&buf + sizeof(buf)));
+ mr.deallocate(p, sz, 1u);
//No new allocation should have occurred
BOOST_TEST(monr.remaining_storage(1u) == 0u);
//Release and check memory was released and the original buffer is back
diff --git a/test/polymorphic_allocator_test.cpp b/test/polymorphic_allocator_test.cpp
index 36f99c8..f66d143 100644
--- a/test/polymorphic_allocator_test.cpp
+++ b/test/polymorphic_allocator_test.cpp
@@ -55,12 +55,13 @@ void test_allocate()
polymorphic_allocator p(&d);
d.reset();
d.do_allocate_return = &dummy;
- p.allocate(2);
+ int *const ptr = p.allocate(2);
BOOST_TEST(d.do_allocate_called == true);
BOOST_TEST(d.do_allocate_return == &dummy);
//It shall allocate 2*sizeof(int), alignment_of
BOOST_TEST(d.do_allocate_bytes == 2*sizeof(int));
BOOST_TEST(d.do_allocate_alignment == dtl::alignment_of::value);
+ p.deallocate(ptr, 2); //To make [[nodiscard]] happy
}
void test_deallocate()