26 #include <type_traits> 28 #include <boost/iterator/iterator_adaptor.hpp> 56 template <
class T,
size_t NS,
class Enable =
void>
61 template <
class T,
size_t NS,
class Enable =
void>
63 template <
class T,
size_t NS>
67 typename
std::enable_if<(
68 std::is_trivial<T>::value && sizeof(T) <= NS &&
69 NS % alignof(T) == 0)>::type> {
74 template <
class T,
size_t NS>
78 static constexpr
size_t kNodeSize = NS;
79 static constexpr
size_t kElementCount = NS /
sizeof(
T);
80 static constexpr
size_t kPaddingBytes = NS %
sizeof(
T);
90 return memcmp(
data(), other.data(),
sizeof(
T) * kElementCount) == 0;
93 return !(*
this == other);
100 return (n + kElementCount - 1) / kElementCount;
108 return nodeCount(n) * NS;
120 (kElementCount - 1 - (n - 1) % kElementCount) *
sizeof(
T))
132 return paddedByteSize(n) - paddingBytes(n);
137 unsigned char bytes[NS];
144 template <
class T,
size_t NS>
147 template <
class T,
size_t NS>
150 template <
class T,
size_t NS>
154 template <
class Iter>
159 template <
typename Void,
typename Container,
typename...
Args>
161 static decltype(
auto) go(Container& container,
Args&&... args) {
162 using Value =
typename Container::value_type;
163 return container.push_back(
Value(std::forward<Args>(args)...));
167 template <
typename Container,
typename...
Args>
170 std::declval<Container&>().emplace_back(std::declval<Args>()...))>,
173 static decltype(
auto) go(Container& container,
Args&&... args) {
174 return container.emplace_back(std::forward<Args>(args)...);
178 template <
typename Container,
typename...
Args>
180 Container& container,
183 return impl::go(container, std::forward<Args>(args)...);
192 template <
class From,
class To,
class Enable =
void>
195 template <
class From,
class To>
199 typename std::enable_if<std::is_const<
200 typename std::remove_reference<From>::type>::value>
::type> {
201 typedef typename std::add_lvalue_reference<
205 template <
class From,
class To>
209 typename std::enable_if<!std::is_const<
210 typename std::remove_reference<From>::type>::value>
::type> {
216 template <
class Iter>
218 typedef boost::iterator_adaptor<
224 typename std::iterator_traits<Iter>::value_type::value_type,
229 typename std::iterator_traits<Iter>::reference,
230 typename std::iterator_traits<Iter>::value_type::value_type>
::type>
240 template <
class Iter>
245 typedef typename std::iterator_traits<Iter>::value_type
Node;
253 return *this->base_reference();
261 return (*this->base_reference()).data()[pos_];
266 this->base_reference() == other.base_reference() && pos_ == other.
pos_);
269 void advance(
typename Super::difference_type n) {
270 constexpr ssize_t elementCount = Node::kElementCount;
271 ssize_t newPos = pos_ + n;
272 if (newPos >= 0 && newPos < elementCount) {
276 ssize_t nblocks = newPos / elementCount;
277 newPos %= elementCount;
280 newPos += elementCount;
282 this->base_reference() += nblocks;
287 if (++pos_ == Node::kElementCount) {
288 ++this->base_reference();
295 --this->base_reference();
296 pos_ = Node::kElementCount - 1;
301 constexpr ssize_t elementCount = Node::kElementCount;
303 std::distance(this->base_reference(), other.base_reference());
304 return nblocks * elementCount + (other.
pos_ - pos_);
307 friend class boost::iterator_core_access;
318 template <
class Container>
323 template <
class Container>
328 template <
class Container>
333 template <
class Container>
338 template <
class Container>
343 template <
class Container>
371 template <
class Container>
374 typedef typename Container::value_type
Node;
383 static constexpr
size_t kElementsPerNode = Node::kElementCount;
385 Adaptor() : lastCount_(Node::kElementCount) {}
386 explicit Adaptor(Container
c,
size_t lastCount = Node::kElementCount)
387 :
c_(
std::
move(c)), lastCount_(lastCount) {}
389 :
c_(Node::nodeCount(n), fullNode(
value)) {
390 const auto count = n % Node::kElementCount;
391 lastCount_ =
count != 0 ?
count : Node::kElementCount;
397 :
c_(
std::
move(other.
c_)), lastCount_(other.lastCount_) {
398 other.lastCount_ = Node::kElementCount;
401 if (
this != &other) {
403 lastCount_ = other.lastCount_;
404 other.lastCount_ = Node::kElementCount;
411 return const_iterator(
c_.begin());
414 auto it = const_iterator(
c_.end());
415 if (lastCount_ != Node::kElementCount) {
416 it -= (Node::kElementCount - lastCount_);
423 const_iterator
end()
const {
427 return iterator(
c_.begin());
430 auto it = iterator(
c_.end());
431 if (lastCount_ != Node::kElementCount) {
432 it -= difference_type(Node::kElementCount - lastCount_);
446 c_.empty() ? 0 : (
c_.size() - 1) * Node::kElementCount + lastCount_);
452 ?
c_.max_size() * Node::kElementCount
458 return c_.front().data()[0];
462 return c_.front().data()[0];
465 const value_type&
back()
const {
467 return c_.back().data()[lastCount_ - 1];
471 return c_.back().data()[lastCount_ - 1];
474 template <
typename...
Args>
476 new (allocate_back()) value_type(std::forward<Args>(args)...);
485 if (--lastCount_ == 0) {
487 lastCount_ = Node::kElementCount;
493 lastCount_ = Node::kElementCount;
498 c_.reserve(Node::nodeCount(n));
502 return c_.capacity() * Node::kElementCount;
506 return c_[idx / Node::kElementCount].data()[idx % Node::kElementCount];
509 return c_[idx / Node::kElementCount].data()[idx % Node::kElementCount];
517 std::pair<Container, size_t>
move() {
518 std::pair<Container, size_t> p(
std::move(
c_), lastCount_);
519 lastCount_ = Node::kElementCount;
527 std::pair<const Container&, size_t>
peek()
const {
528 return std::make_pair(std::cref(
c_), lastCount_);
533 if (lastCount_ != Node::kElementCount) {
534 auto last =
c_.back().data();
535 std::fill(last + lastCount_, last + Node::kElementCount, padValue);
536 lastCount_ = Node::kElementCount;
542 if (lastCount_ == Node::kElementCount) {
546 return &
c_.back().data()[lastCount_++];
551 std::fill(n.data(), n.data() + kElementsPerNode,
value);
std::pair< Container, size_t > move()
void emplace_back(Args &&...args)
Iterator< typename Container::iterator > iterator
bool equal(const Iterator &other) const
value_type * allocate_back()
Node::value_type value_type
const_iterator cend() const
Iterator< typename Container::const_iterator > begin(const Container &c)
const value_type & const_reference
const value_type & operator[](size_type idx) const
bool operator!=(const Node &other) const
Container::value_type Node
constexpr detail::Map< Move > move
value_type & operator[](size_type idx)
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
void advance(typename Super::difference_type n)
requires E e noexcept(noexcept(s.error(std::move(e))))
Iterator< typename Container::const_iterator > const_iterator
const_iterator begin() const
std::iterator_traits< Iter >::value_type Node
static constexpr size_t paddedByteSize(size_t n)
size_type max_size() const
Adaptor(Container c, size_t lastCount=Node::kElementCount)
static constexpr size_t nodeCount(size_t n)
const value_type & front() const
static Node fullNode(const value_type &value)
void reserve(size_type n)
void swap(Adaptor &other)
void push_back(value_type x)
static constexpr size_t paddingBytes(size_t n)
constexpr auto empty(C const &c) -> decltype(c.empty())
def Iter(n, format, sep='')
Adaptor(Adaptor &&other) noexcept
boost::iterator_adaptor< Iterator< Iter >, Iter, typename std::iterator_traits< Iter >::value_type::value_type, boost::use_default, typename detail::TransferReferenceConstness< typename std::iterator_traits< Iter >::reference, typename std::iterator_traits< Iter >::value_type::value_type >::type > type
bool Value(const T &value, M matcher)
const_iterator cbegin() const
Super::reference dereference() const
constexpr auto data(C &c) -> decltype(c.data())
std::add_lvalue_reference< typename std::add_const< To >::type >::type type
const value_type & back() const
size_type capacity() const
void swap(exception_wrapper &a, exception_wrapper &b) noexcept
detail::IteratorBase< Iter >::type Super
void padToFullNode(const value_type &padValue)
std::pair< const Container &, size_t > peek() const
const Node & node() const
Super::difference_type distance_to(const Iterator &other) const
Iterator< typename Container::iterator > begin(Container &c)
Container::size_type size_type
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
const_iterator::difference_type difference_type
Adaptor(size_t n, const value_type &value=value_type())
const_iterator end() const
void swap(SwapTrackingAlloc< T > &, SwapTrackingAlloc< T > &)
static constexpr size_t unpaddedByteSize(size_t n)
Iterator< typename Container::const_iterator > end(const Container &c)
bool operator==(const Node &other) const
Adaptor & operator=(Adaptor &&other)
decltype(auto) padded_emplace_back_or_push_back(Container &container, Args &&...args)
Iterator< typename Container::iterator > end(Container &c)
Iterator< typename Container::const_iterator > cbegin(const Container &c)
std::add_lvalue_reference< To >::type type
Iterator< typename Container::const_iterator > cend(const Container &c)