mirror of
https://github.com/boostorg/container.git
synced 2026-07-05 12:10:46 +02:00
Added unchecked_push_back to vector/small_vector/static_vector
This commit is contained in:
+1
-1
@@ -1467,7 +1467,7 @@ collect them containers and build [*Boost.Container], a library targeted to a wi
|
||||
* Fixed bugs/issues:
|
||||
* [@https://github.com/boostorg/container/issues/334 GitHub #334: ['"Wrong overload resolution protection in implementation of P2363R5"]].
|
||||
|
||||
* Added [memberref boost::container::vector::unchecked_emplace_back unchecked_emplace_back] to [classref boost::container::vector vector],
|
||||
* Added `unchecked_emplace_back` and `unchecked_push_back` to [classref boost::container::vector vector],
|
||||
[classref boost::container::static_vector static_vector] and [classref boost::container::small_vector small_vector].
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -608,7 +608,35 @@ public:
|
||||
//!
|
||||
//! @par Complexity
|
||||
//! Constant O(1).
|
||||
void push_back(BOOST_RV_REF(value_type) value);
|
||||
void push_back(value_type &&value);
|
||||
|
||||
//! @pre <tt>size() < capacity()</tt>. Otherwise, the behavior is undefined.
|
||||
//!
|
||||
//! @brief Adds a copy of value at the end.
|
||||
//!
|
||||
//! @param value The value used to copy construct the new element.
|
||||
//!
|
||||
//! @par Throws
|
||||
//! @li If T's copy constructor throws.
|
||||
//! @li If \c throw_on_overflow<true> option is set and the container runs out of capacity.
|
||||
//!
|
||||
//! @par Complexity
|
||||
//! Constant O(1).
|
||||
void unchecked_push_back(value_type const& value);
|
||||
|
||||
//! @pre <tt>size() < capacity()</tt>. Otherwise, the behavior is undefined.
|
||||
//!
|
||||
//! @brief Moves value to the end.
|
||||
//!
|
||||
//! @param value The value to move construct the new element.
|
||||
//!
|
||||
//! @par Throws
|
||||
//! @li If T's move constructor throws.
|
||||
//! @li If \c throw_on_overflow<true> option is set and the container runs out of capacity.
|
||||
//!
|
||||
//! @par Complexity
|
||||
//! Constant O(1).
|
||||
void unchecked_push_back(value_type &&value);
|
||||
|
||||
//! @pre <tt>!empty()</tt>
|
||||
//!
|
||||
|
||||
@@ -1984,7 +1984,7 @@ private:
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension.
|
||||
template<class ...Args>
|
||||
inline reference unchecked_emplace_back(BOOST_FWD_REF(Args)...args)
|
||||
BOOST_CONTAINER_FORCEINLINE reference unchecked_emplace_back(BOOST_FWD_REF(Args)...args)
|
||||
{
|
||||
BOOST_ASSERT(this->size() < this->capacity());
|
||||
T* const p = this->priv_raw_end();
|
||||
@@ -2086,8 +2086,30 @@ private:
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
void push_back(T &&x);
|
||||
|
||||
//! <b>Requires</b>: Before the call to this function size() < capacity() must be true.
|
||||
//! Otherwise, the behavior is undefined.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts a copy of x at the end of the vector.
|
||||
//!
|
||||
//! <b>Throws</b>: If T's copy/move constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
void unchecked_push_back(const T &x);
|
||||
|
||||
//! <b>Requires</b>: Before the call to this function size() < capacity() must be true.
|
||||
//! Otherwise, the behavior is undefined.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a new element in the end of the vector
|
||||
//! and moves the resources of x to this new element.
|
||||
//!
|
||||
//! <b>Throws</b>: If T's copy/move constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
void unchecked_push_back(T &&x);
|
||||
#else
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
|
||||
BOOST_MOVE_CONVERSION_AWARE_CATCH(unchecked_push_back, T, void, priv_unchecked_push_back)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -2976,10 +2998,20 @@ private:
|
||||
this->emplace_back(::boost::forward<U>(u));
|
||||
}
|
||||
|
||||
template <class U>
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_unchecked_push_back(BOOST_FWD_REF(U) u)
|
||||
{
|
||||
this->unchecked_emplace_back(::boost::forward<U>(u));
|
||||
}
|
||||
|
||||
//Overload to support compiler errors that instantiate too much
|
||||
inline void priv_push_back(::boost::move_detail::nat)
|
||||
{}
|
||||
|
||||
//Overload to support compiler errors that instantiate too much
|
||||
inline void priv_unchecked_push_back(::boost::move_detail::nat)
|
||||
{}
|
||||
|
||||
inline iterator priv_insert(const_iterator, ::boost::move_detail::nat)
|
||||
{ return iterator(); }
|
||||
|
||||
|
||||
+75
-17
@@ -42,17 +42,71 @@ namespace boost{
|
||||
namespace container {
|
||||
namespace test{
|
||||
|
||||
template<class Vector>
|
||||
struct vector_has_function_capacity
|
||||
{
|
||||
typedef typename Vector::size_type size_type;
|
||||
template <typename U, size_type (U::*)() const> struct Check;
|
||||
template <typename U> static char func(Check<U, &U::capacity> *);
|
||||
template <typename U> static int func(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(func<Vector>(0)) == sizeof(char);
|
||||
};
|
||||
#define BOOST_VECTOR_TEST_HAS_MEMBER_FUNC(FUNC) \
|
||||
\
|
||||
template<class T> \
|
||||
struct vector_has_function_##FUNC \
|
||||
{ \
|
||||
typedef char yes[1]; \
|
||||
typedef char no[2]; \
|
||||
\
|
||||
struct fallback { int FUNC; }; \
|
||||
struct derived : T, fallback {}; \
|
||||
\
|
||||
template <typename U, U> \
|
||||
struct check; \
|
||||
\
|
||||
template <typename U> \
|
||||
static no& test(check<int fallback::*, &U::FUNC>*); \
|
||||
\
|
||||
template <typename U> \
|
||||
static yes& test(...); \
|
||||
\
|
||||
static const bool value = sizeof(test<derived>(0)) == sizeof(yes); \
|
||||
}; \
|
||||
//
|
||||
|
||||
BOOST_VECTOR_TEST_HAS_MEMBER_FUNC(capacity)
|
||||
BOOST_VECTOR_TEST_HAS_MEMBER_FUNC(unchecked_push_back)
|
||||
|
||||
template<class V1, class V2>
|
||||
bool vector_unchecked_push_back_test(V1&, V2&, boost::container::dtl::false_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class MyBoostVector, class MyStdVector>
|
||||
bool vector_unchecked_push_back_test(MyBoostVector& , MyStdVector& , boost::container::dtl::true_type)
|
||||
{
|
||||
typedef typename MyBoostVector::value_type IntType;
|
||||
|
||||
MyBoostVector bv;
|
||||
MyStdVector sv;
|
||||
|
||||
bv.reserve(10);
|
||||
sv.reserve(10);
|
||||
|
||||
for (std::size_t i = 0, max = bv.capacity(); i < max; ++i) {
|
||||
bv.unchecked_push_back(IntType((int)i));
|
||||
sv.push_back((int)i);
|
||||
}
|
||||
|
||||
if(!test::CheckEqualContainers(bv, sv)) return false;
|
||||
|
||||
bv.clear();
|
||||
sv.clear();
|
||||
|
||||
for (std::size_t i = 0, max = bv.capacity(); i < max; ++i) {
|
||||
IntType move_me((int)i);
|
||||
bv.unchecked_push_back(boost::move(move_me));
|
||||
sv.push_back((int)i);
|
||||
}
|
||||
|
||||
if(!test::CheckEqualContainers(bv, sv)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class V1, class V2>
|
||||
bool vector_capacity_test(V1&, V2&, boost::container::dtl::false_type)
|
||||
@@ -94,19 +148,20 @@ bool vector_capacity_test(MyBoostVector&boostvector, MyStdVector&stdvector, boos
|
||||
const std::size_t sz = a.size();
|
||||
const std::size_t cap = a.capacity();
|
||||
|
||||
a.resize(1000);
|
||||
a.resize(sz);
|
||||
b.resize(sz/10);
|
||||
a.swap(b);
|
||||
if( !(b.capacity() == cap) ) return false;
|
||||
if( !(b.capacity() >= cap) ) return false;
|
||||
if( !(b.size() == sz) ) return false;
|
||||
if( !(a.capacity() != cap) ) return false;
|
||||
if( !(a.empty()) ) return false;
|
||||
if( !(a.capacity() >= cap/10) ) return false;
|
||||
if( !(a.size() == sz/10) ) return false;
|
||||
|
||||
a.swap(b);
|
||||
|
||||
if( !(a.capacity() == cap) ) return false;
|
||||
if( !(a.capacity() >= cap) ) return false;
|
||||
if( !(a.size() == sz) ) return false;
|
||||
if( !(b.capacity() != cap) ) return false;
|
||||
if( !(b.empty()) ) return false;
|
||||
if( !(b.capacity() >= cap/10) ) return false;
|
||||
if( !(b.size() == sz/10) ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -287,6 +342,9 @@ bool vector_copyable_only(MyBoostVector &boostvector, MyStdVector &stdvector, bo
|
||||
bcopy2 = boostvector;
|
||||
scopy2 = stdvector;
|
||||
if(!test::CheckEqualContainers(bcopy2, scopy2)) return false;
|
||||
|
||||
if(!vector_unchecked_push_back_test(boostvector, stdvector, dtl::bool_<vector_has_function_unchecked_push_back<MyBoostVector>::value>()))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user