Direct-BT
2.3.1
Direct-BT - Direct Bluetooth Programming.
|
Go to the documentation of this file.
26 #ifndef JAU_COW_VECTOR_HPP_
27 #define JAU_COW_VECTOR_HPP_
36 #include <condition_variable>
105 template <
typename Value_type,
typename Alloc_type = std::allocator<Value_type>>
120 typedef std::vector<value_type, allocator_type>
storage_t;
138 static constexpr
size_type DIFF_MAX = std::numeric_limits<difference_type>::max();
142 mutable std::recursive_mutex mtx_write;
148 : store_ref( std::make_shared<
storage_t>() ), sync_atomic(false) {}
151 : store_ref( std::make_shared<storage_t>(a) ), sync_atomic(
false) { }
154 : store_ref( std::make_shared<
storage_t>(n, a) ), sync_atomic(false) { }
157 : store_ref( std::make_shared<
storage_t>(n, value, a) ), sync_atomic(false) { }
164 : sync_atomic(false) {
168 x_store_ref = x.store_ref;
170 store_ref = std::make_shared<storage_t>( *x_store_ref, x_store_ref->get_allocator() );
180 std::lock_guard<std::recursive_mutex> lock(mtx_write);
184 x_store_ref = x.store_ref;
186 storage_ref_t new_store_ref = std::make_shared<storage_t>( *x_store_ref, x_store_ref->get_allocator() );
189 store_ref = std::move(new_store_ref);
200 std::unique_lock<std::recursive_mutex> lock(x.mtx_write);
202 store_ref = std::move(x.store_ref);
207 x.store_ref =
nullptr;
223 std::unique_lock<std::recursive_mutex> lock1(x.mtx_write, std::defer_lock);
224 std::unique_lock<std::recursive_mutex> lock2( mtx_write, std::defer_lock);
225 std::lock(lock1, lock2);
229 store_ref = std::move(x.store_ref);
233 x.store_ref =
nullptr;
247 template<
class InputIt >
249 : store_ref(std::make_shared<
storage_t>(first, last, alloc)), sync_atomic(false)
259 : store_ref(std::make_shared<
storage_t>(initlist, alloc)), sync_atomic(false)
303 std::lock_guard<std::recursive_mutex> lock(mtx_write);
304 return std::make_shared<storage_t>( *store_ref, store_ref->get_allocator() );
336 std::lock_guard<std::recursive_mutex> lock(mtx_write);
338 store_ref = std::move( new_store_ref );
383 return store_ref->get_allocator();
389 return store_ref->capacity();
401 return store_ref->empty();
413 return store_ref->size();
419 std::lock_guard<std::recursive_mutex> lock(mtx_write);
421 if( new_capacity > old_store_ref->capacity() ) {
422 storage_ref_t new_store_ref = std::make_shared<storage_t>( *old_store_ref, old_store_ref->get_allocator() );
423 new_store_ref->reserve(new_capacity);
425 store_ref = std::move(new_store_ref);
437 std::lock_guard<std::recursive_mutex> lock(mtx_write);
441 store_ref = std::move(new_store_ref);
453 std::unique_lock<std::recursive_mutex> lock(mtx_write, std::defer_lock);
454 std::unique_lock<std::recursive_mutex> lock_x(x.mtx_write, std::defer_lock);
455 std::lock(lock, lock_x);
460 x.store_ref = store_ref;
461 store_ref = x_store_ref;
473 std::lock_guard<std::recursive_mutex> lock(mtx_write);
475 if( 0 < old_store_ref->size() ) {
476 storage_ref_t new_store_ref = std::make_shared<storage_t>( *old_store_ref, old_store_ref->get_allocator() );
477 new_store_ref->pop_back();
480 store_ref = std::move(new_store_ref);
494 std::lock_guard<std::recursive_mutex> lock(mtx_write);
495 storage_ref_t new_store_ref = std::make_shared<storage_t>( *store_ref, store_ref->get_allocator() );
496 new_store_ref->push_back(x);
499 store_ref = std::move(new_store_ref);
511 std::lock_guard<std::recursive_mutex> lock(mtx_write);
512 storage_ref_t new_store_ref = std::make_shared<storage_t>( *store_ref, store_ref->get_allocator() );
513 new_store_ref->push_back( std::move(x) );
516 store_ref = std::move(new_store_ref);
530 template<
typename... Args>
533 std::lock_guard<std::recursive_mutex> lock(mtx_write);
534 storage_ref_t new_store_ref = std::make_shared<storage_t>( *store_ref, store_ref->get_allocator() );
535 reference res = new_store_ref->emplace_back( std::forward<Args>(args)... );
538 store_ref = std::move(new_store_ref);
577 std::lock_guard<std::recursive_mutex> lock(mtx_write);
578 for(
auto it = store_ref->begin(); it != store_ref->end(); ) {
579 if( comparator( *it, x ) ) {
616 std::lock_guard<std::recursive_mutex> lock(mtx_write);
617 storage_ref_t new_store_ref = std::make_shared<storage_t>( *store_ref, store_ref->get_allocator() );
618 for(
auto it = new_store_ref->begin(); it != new_store_ref->end(); ) {
619 if( comparator( *it, x ) ) {
620 it = new_store_ref->erase(it);
622 if( !all_matching ) {
631 store_ref = std::move(new_store_ref);
640 if( 1 < ++i ) { res.append(
", "); }
651 template<
typename Value_type,
typename Alloc_type>
660 template<
typename Value_type,
typename Alloc_type>
666 rhs_cend += rhs.
size();
669 template<
typename Value_type,
typename Alloc_type>
674 template<
typename Value_type,
typename Alloc_type>
677 rhs_cend += rhs.
size();
679 lhs_cend += lhs.
size();
680 return std::lexicographical_compare(rhs.
cbegin(), rhs_cend, lhs.
begin(), lhs_cend);
683 template<
typename Value_type,
typename Alloc_type>
685 {
return lhs < rhs; }
687 template<
typename Value_type,
typename Alloc_type>
689 {
return !(lhs < rhs); }
691 template<
typename Value_type,
typename Alloc_type>
693 {
return !(rhs < lhs); }
695 template<
typename Value_type,
typename Alloc_type>
#define constexpr_cxx20
constexpr qualifier replacement for C++20 constexpr.
constexpr_atomic cow_vector(const cow_vector &x)
constexpr cow_vector(size_type n, const value_type &value, const allocator_type &a=allocator_type())
Implementation of a Copy-On-Write (CoW) read-onlu iterator over immutable value_type storage.
allocator_type get_allocator() const noexcept
constexpr cow_vector(const allocator_type &a) noexcept
bool(* equal_comparator)(const value_type &a, const value_type &b)
Generic value_type equal comparator to be user defined for e.g.
constexpr cow_vector() noexcept
std::ostream & operator<<(std::ostream &out, const cow_darray< Value_type, Alloc_type > &c)
#define constexpr_atomic
Used when designed to declare a function constexpr, but prohibited by its specific implementation.
const value_type * const_pointer
constexpr_atomic void pop_back() noexcept
Like std::vector::pop_back().
constexpr_atomic void set_store(storage_ref_t &&new_store_ref) noexcept
Special case facility allowing the user to replace the current store with the given value,...
constexpr_atomic int erase_matching(const value_type &x, const bool all_matching, equal_comparator comparator)
Erase either the first matching element or all matching elements.
constexpr_atomic bool empty() const noexcept
Like std::vector::empty().
constexpr cow_vector(std::initializer_list< value_type > initlist, const allocator_type &alloc=allocator_type())
Create a new instance from an initializer list.
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
constexpr cow_vector(InputIt first, InputIt last, const allocator_type &alloc=allocator_type())
Creates a new instance, copying all elements from the given template input-iterator value_type range ...
constexpr_cxx20 std::string toString() const noexcept
constexpr_atomic size_type capacity() const noexcept
cow_ro_iterator< storage_t, storage_ref_t, cow_container_t > const_iterator
constexpr_atomic cow_vector(cow_vector &&x) noexcept
constexpr_atomic storage_ref_t copy_store()
Returns a new shared_ptr copy of the underlying store, i.e.
constexpr_atomic reference emplace_back(Args &&... args)
Like std::vector::emplace_back(), construct a new element in place at the end().
constexpr cow_vector(size_type n, const allocator_type &a=allocator_type())
constexpr size_type max_size() const noexcept
Returns std::numeric_limits<difference_type>::max() as the maximum array size.
void swap(cow_darray< Value_type, Alloc_type > &rhs, cow_darray< Value_type, Alloc_type > &lhs) noexcept
std::make_signed< size_type >::type difference_type
This class provides a RAII-style Sequentially Consistent (SC) data race free (DRF) critical block.
constexpr_atomic void clear() noexcept
Like std::vector::clear(), but ending with zero capacity.
std::vector< value_type, allocator_type > storage_t
constexpr_atomic storage_ref_t snapshot() const noexcept
Returns the current snapshot of the underlying shared std::vector<T> reference.
std::shared_ptr< storage_t > storage_ref_t
constexpr_atomic void push_back(const value_type &x)
Like std::vector::push_back(), copy.
constexpr UnaryFunction for_each_const(T &data, UnaryFunction f, std::enable_if_t< is_cow_type< T >::value, bool >=true) noexcept
constexpr_atomic cow_vector & operator=(cow_vector &&x)
Like std::vector::operator=(&&), move.
constexpr_atomic void swap(cow_vector &x) noexcept
Like std::vector::swap().
bool operator<=(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
constexpr const_iterator cbegin() const noexcept
See description in jau::cow_darray::cbegin()
constexpr cow_vector(const storage_t &x)
constexpr_atomic bool push_back_unique(const value_type &x, equal_comparator comparator)
Like std::vector::push_back(), but only if the newly added element does not yet exist.
constexpr std::recursive_mutex & get_write_mutex() noexcept
Returns this instances' recursive write mutex, allowing user to implement more complex mutable write ...
const value_type & const_reference
bool operator>(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
cow_vector & operator=(const cow_vector &x)
Like std::vector::operator=(&), assignment.
void reserve(size_type new_capacity)
constexpr_atomic size_type size() const noexcept
Like std::vector::size().
Alloc_type allocator_type
cow_rw_iterator< storage_t, storage_ref_t, cow_container_t > iterator
cow_vector< value_type, allocator_type > cow_container_t
bool operator!=(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Implementation of a Copy-On-Write (CoW) read-write iterator over mutable value_type storage.
bool operator>=(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)
constexpr iterator begin()
See description in jau::cow_darray::begin()
Implementation of a Copy-On-Write (CoW) using std::vector as the underlying storage,...
constexpr_atomic void push_back(value_type &&x)
Like std::vector::push_back(), move.
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
bool operator<(const cow_darray< Value_type, Alloc_type > &rhs, const cow_darray< Value_type, Alloc_type > &lhs)