Pathfinder 1e – Can anyone explain what is meant by "5 levels below" with the limited buffer function of Kineticist Archetype Elemental Purist?

The advantages of the internal tampon evolve with your level of kineticist. It starts at 1 point maximum and goes to 2 at level 11 and 3 at level 16.

Limited buffer

treats his level of physiotherapist as 5 for the purposes of
aptitude.

line means that you subtract 5 from your physiotherapist level to determine the benefits you get from the internal buffering capacity. In particular, when you get it at level 11, your limit is always 1 point since your level is 11-5 = 6. You will get a second point at level 16 and the third point at level 21.

pathfinder 1e – Can anyone explain what is meant by "5 lower levels" with the limited buffer function of Kineticist Archetype Elemental Purist?

The advantages of the internal tampon evolve with your level of kineticist. It starts at 1 point maximum and goes to 2 at level 11 and 3 at level 16.

Limited buffer

treats his level of physiotherapist as 5 for the purposes of
aptitude.

line means that you subtract 5 from your physiotherapist level to determine the benefits you get from the internal buffering capacity. In particular, when you get it at level 11, your limit is always 1 point since your level is 11-5 = 6. You will get a second point at level 16 and the third point at level 21.

c – Buffer overflow with pwntools

I was studying the buffer overflow vulnerability and there was a small task ahead. I am very new to this kind of thing and I am unable to solve it beyond a certain point. The program has a character (120) but is limited by the read () command. Can someone explain me or help me a little with the problem? I've attached the binary as well as the complete C code.

Program C

Binary file

I have to exploit it only with the help of pwntools, so I would be grateful if you could explain something about it.

Thanking you in advance!

Does a Buffer Overflow Vulnerability Always Mean a Code Run-Time Vulnerability?

Since Buffer Overflows always lets a malicious hacker write out of the buffer and overwrite the return pointer to a shellcode that it can place, does that mean that successful operation of a stack overflow always causes the can you invoke a shell if this is done? The right way? At least in theory, if you assume that the DEP and the ASLR are not in place.

buffer overflow – How is malicious code executed on Android devices without the knowledge of its owners?

Battery Exchange Network

The Stack Exchange network includes 175 question-and-answer communities, including Stack Overflow, the largest and most reliable online community on which developers can learn, share knowledge and build their careers.

Visit Stack Exchange

buffer overflow – EIP control with ASCII values

I'm trying to replace the EIP to cause a buffer overflow. I can write values ​​in the EIP, but I can only write ASCII values ​​and I have to redirect the execution to a high stack address, for example. 0xbfff4a60

I can overwrite using AAAA which will convert to 0x41414141. I have sixteen bytes available to write. Is it possible to do this with ASCII, or unique assembly tips entered with ASCII?

Thank you

EDIT: Entering extended ASCII values ​​does not work, as

5th dnd – Can I recover some of my normal health points while I have a buffer of temporary health?

Temporary hit points do not prevent you from recovering regular hit points

The "Health Points" section under "Damages and Healing" indicates:

(…) The current hit points of a creature (usually just called life points) can be any number ranging from the creature's maximum health to 0. This number changes frequently. when a creature takes damage or receives healing (…)

And then, the section on "Temporary points of life" indicates:

Some spells and special abilities grant temporary health to a creature. Temporary hit points are not real hit points; they are a buffer against damage, a set of health points that protect you from injuries (…)

Nowhere in the section is it said that you can not be cured while having temporary health points. In fact, they are defined as a buffer against pityand all their effects and operation with respect to damage are defined. If they were meant to prevent you from being cured it would be declared. Also note that the health section never says that you can not receive care while you have temporary hit points.

Because nothing in the text and the rules indicates or even hints at temporary health points preventing you from receiving a normal healing, they do not prevent it.

How is it that the buffer overflow occurs in an application-like application, if a canary exists?

I've read recently that WhatsApp has fallen again to buffer overflow attacks.
But I wonder why the protection against canaries is not used. I imagine that for some reason, Facebook and other code companies do not use it globally for some reason or protect some of the buffer overflow attacks, if so why or how ?

ripple – TfTypeError: expected property "0" of type Buffer, got Promise

the code is for a ripple address but I get this error (under the code)

const bip39 = require ("bip39");
const bip32 = require ("ripple-beep32");
const ripple = require (& # 39; ripple-keypairs & # 39;)

// var mnemonic = Shadow Join Tank prefers the surface around the tornado, the return of the enemy fish returns in parentheses & # 39;
// or generate:
mnemonic = bip39.generateMnemonic ()

console.log (& mnemonic: + mnemonic)
const seed = bip39.mnemonicToSeed (mnemonic) // add the second argument of the 25th encrypted word
console.log (& # 39; seed: & # 39; seed)
// const m = bip32.fromSeed (seed)
const m = bip32.fromSeedBuffer (seed)
console.log ("m:", m)
const keyPair = m.derivePath ("m / 44" / 144 "/ 0" / 0/0 "). keyPair.getKeyPairs ()
address const = ripple.deriveAddress (keyPair.publicKey)

console.log (& # 39; privateKey: & # 39; + keyPair.privateKey)
console.log (& # 39; publicKey: + keyPair.publicKey)
console.log (& # 39; address: + address)

This is the output when running the script.js node

C: JFF> node ps3.js –abort-on-uncaught-exception
mnemonic: ritual slam explain appearance man tail register future pink run drill insect
seed: promise {}

C: JFF node_modules typeforce index.js: 190
throws tfSubError (e, i)
^
TfTypeError: property "0" expected of type Buffer, got Promise
at captureStackTrace (C: JFF node_modules typeforce errors.js: 20:11)
at tfSubError (C: JFF node_modules typeforce errors.js: 99: 3)
at C: JFF node_modules typeforce index.js: 190: 17
at Array.every ()
to _tuple (C: JFF node_modules typeforce index.js: 186: 20)
at typeforce (C: JFF node_modules typeforce index.js: 233: 9)
on Function.HDNode.fromSeedBuffer (C: JFF node_modules ripple-beep32 lib hdnode.js: 32: 3)
to the object. (C: JFF ps3.js: 14: 17)
in Module._compile (internal / modules / cjs / loader.js: 956: 30)
on Object.Module._extensions..js (internal / modules / cjs / loader.js: 973: 10) {
message: expected property "0" of type Buffer, got Promise ",
__label: not defined,
__property: 0,
__type: (Function: _Buffer) {toJSON: (Function: linked)},
__value: Promise {},
__valueTypeName: Promise & # 39;
}

collections – a c ++ ringtone buffer using c ++ 17 and c ++ 20 std :: span coming soon

when i heard about linux's new interface io_uring then new io_uring i looked about the ring buffer

I then thought that I could replace my c ++ 11 std :: queue-based secure queue with a ring buffer to avoid repeated memory allocation during production and execution. the consumption of the packets between the threads.

so I wanted to implement it as an exercise and I started looking for implementations of c ++ and found the boost boost buffer

I did not look much at its source code, I looked at the features it provides and tried to implement most, but I still miss some

so here's what I came up with:

#pragma once
#include 
#include 
#include "span.h"
#include 

#define PROVIDE_CONTAINER_TYPES(T) 
    using value_type = T;
    using pointer = T * ;
    using const_pointer = const T *;
    using reference = T & ;
    using const_reference = const T &; 
    using size_type = std::size_t; 
    using difference_type = std::ptrdiff_t

struct no_init_t {};
constexpr no_init_t no_init;

class ring_buffer_index
    {
        size_t index;

    public:

        ring_buffer_index() : index{0} {}

        ring_buffer_index(size_t pos) : index{pos} {}

        ring_buffer_index& operator++()
        {
            ++index;
            return *this;
        }

        ring_buffer_index& operator--()
        {
            --index;
            return *this;
        }

        ring_buffer_index operator+(size_t pos) const { return ring_buffer_index{index + pos}; }

        size_t operator-(ring_buffer_index other) const { return index - other.index; }

        bool operator==(ring_buffer_index other) const { return index == other.index; }

        bool operator!=(ring_buffer_index other) const { return index != other.index; }

        void operator+=(size_t times) { index += times; }

        void operator-=(size_t times) { index -= times; }

        void reset() { index = 0; }

        size_t as_index(size_t N) const
        {
            size_t pos = index;
            pos %= N;
            return pos;
        }

    };

    template 
    class uninitialized_array
    {
        std::unique_ptr raw_buffer;

    public:

        uninitialized_array() noexcept = default;

        uninitialized_array(size_t N) : raw_buffer{ new unsigned char(sizeof(T) * N) } {}

        uninitialized_array(uninitialized_array&& other) noexcept = default;

        uninitialized_array& operator=(uninitialized_array&& other) noexcept = default;

        void copy(const uninitialized_array& other, size_t N)
        {
            raw_buffer.reset();
            if (other.raw_buffer && N)
            {
                raw_buffer.reset(new unsigned char(sizeof(T) * N));
                std::uninitialized_copy(other.ptr(), other.ptr() + N, ptr());
            }
        }

        void resize(size_t N)
        {
            raw_buffer.reset( new unsigned char(sizeof(T) * N) );
        }

        T * ptr() noexcept { return reinterpret_cast(raw_buffer.get()); }

        const T * ptr() const noexcept { return reinterpret_cast(raw_buffer.get()); }

        T& operator()(size_t pos) noexcept
        {
            return ptr()(pos);
        }

    };

    template 
    class ring_buffer_iterator
    {
        T *ptr;
        ring_buffer_index index;
        size_t N;

    public:

        PROVIDE_CONTAINER_TYPES(T);

        using iterator_category = std::random_access_iterator_tag;

        ring_buffer_iterator(T *ptr, ring_buffer_index index, size_t N) : ptr{ ptr }, index{ index }, N{ N } {}

        ring_buffer_iterator& operator++()
        {
            if constexpr (!reverse)
                ++index;
            else
                --index;
            return *this;
        }

        ring_buffer_iterator& operator+=(size_t n) { index += n; return *this; }

        ring_buffer_iterator& operator-=(size_t n) { return operator+=(-n); }

        template  = true> 
        reference operator*() const
        {
            return ptr(index.as_index(N));
        }

        template  = true>
        const_reference operator*() const
        {
            return ptr(index.as_index(N));
        }

        template  = true>
        reference operator()(difference_type n) { return *(*this + n); }

        const_reference operator()(difference_type n) const { return *(*this + n); }

        bool operator!=(ring_buffer_iterator other) const { return index != other.index; }

        bool operator==(ring_buffer_iterator other) const { return index == other.index; }

        friend ring_buffer_iterator operator+(const ring_buffer_iterator& iter, size_t times) { return ring_buffer_iterator{iter.ptr, iter.index + times, iter.N}; }

        friend ring_buffer_iterator operator+(size_t times, const ring_buffer_iterator& iter) { return ring_buffer_iterator{ iter.ptr, iter.index + times, iter.N }; }

        friend ring_buffer_iterator operator-(const ring_buffer_iterator& lhs, size_t times) { return ring_buffer_iterator{lhs.ptr, lhs.index - times, lhs.N}; }

        friend difference_type operator-(const ring_buffer_iterator& lhs, const ring_buffer_iterator& rhs) { return static_cast(lhs.index - rhs.index); }

    };

    template 
    class ring_buffer
    {
        size_t N;
        mutable uninitialized_array raw_buffer;
        ring_buffer_index read_pos, write_pos;

        T& read_ptr() const
        {
            return raw_buffer(read_pos.as_index(N));
        }

        T& write_ptr() const
        {
            return raw_buffer(write_pos.as_index(N));
        }

        bool will_remain_linearized(size_t num)
        {
            ring_buffer_index last_elem = write_pos + num - 1;
            return last_elem.as_index(N) >= read_pos.as_index(N);
        }

    public:

        PROVIDE_CONTAINER_TYPES(T);

        using iterator = ring_buffer_iterator;
        using const_iterator = ring_buffer_iterator;
        using reverse_iterator = ring_buffer_iterator;
        using const_reverse_iterator = const ring_buffer_iterator;

        /*
        contrtuctors and assignment operators
        */

        ring_buffer() : N{0} {}

        ring_buffer(size_t size) : N{ size }, raw_buffer { size } {}

        ring_buffer(ring_buffer&&) noexcept = default;

        ring_buffer(const ring_buffer& other)
        {
            clear();
            N = other.N;
            read_pos = other.read_pos;
            write_pos = other.write_pos;
            raw_buffer.copy(other.raw_buffer, N);
        }

        ring_buffer(std::initializer_list init) : ring_buffer(init.size())
        {
            std::uninitialized_copy(init.begin(), init.end(), raw_buffer.ptr());
        }

        template 
        ring_buffer(InputIterator first, InputIterator last) : ring_buffer(static_cast(std::distance(first, last)))
        {
            std::uninitialized_copy(first, last, raw_buffer.ptr());
            write_pos += capacity();
        }

        ring_buffer& operator=(ring_buffer&& other) noexcept
        {
            clear();
            N = other.N;
            read_pos = other.read_pos;
            write_pos = other.write_pos;
            raw_buffer = std::move(other.raw_buffer);
            return *this;

        }

        ring_buffer& operator=(const ring_buffer& other)
        {
            clear();
            N = other.N;
            read_pos = other.read_pos;
            write_pos = other.write_pos;
            raw_buffer.copy(other.raw_buffer, N);
            return *this;
        }

        ~ring_buffer() { clear(); }

        /*
        addition methods
        */

        /*
        add at the back of the buffer , this is usually used rather than add at the front
        */

        void push_back_without_checks(const value_type& value)
        {
            emplace_back_without_checks(value);
        }

        void push_back_without_checks(value_type&& value)
        {
            emplace_back_without_checks(std::move(value));
        }

        bool try_push_back(const value_type& value)
        {
            return try_emplace_back(value);
        }

        bool try_push_back(value_type&& value)
        {
            return try_emplace_back(std::move(value));
        }

        void push_back(const value_type& value)
        {
            emplace_back(value);
        }

        void push_back(value_type&& value)
        {
            emplace_back(std::move(value));
        }

        template 
        void emplace_back_without_checks(Args&& ... args)
        {
            new(&write_ptr()) T(std::forward(args)...);
            ++write_pos;
        }

        template 
        bool try_emplace_back(Args&& ... args)
        {
            if (full())
                return false;
            emplace_back_without_checks(std::forward(args)...);
            return true;
        }

        template 
        void emplace_back(Args&& ... args)
        {
            if (full())
                pop_front();
            emplace_back_without_checks(std::forward(args)...);
        }

        template 
        void insert_back(InputIterator first, InputIterator last)
        {
            size_t num = static_cast(std::distance(first, last));
            if (will_remain_linearized(num))
            {
                std::uninitialized_copy(first, last, &write_ptr());
                write_pos += num;
            }
            else
                std::copy(first, last, std::back_inserter(*this));
        }

        /*
        add at the front of the buffer
        */

        void push_front_without_checks(const value_type& value)
        {
            emplace_front_without_checks(value);
        }

        void push_front_without_checks(value_type&& value)
        {
            emplace_front_without_checks(value);
        }

        bool try_push_front(const value_type& value)
        {
            return try_emplace_front(value);
        }

        bool try_push_front(value_type&& value)
        {
            return try_emplace_front(value);
        }

        void push_front(const value_type& value)
        {
            emplace_front(value);
        }

        void push_front(value_type&& value)
        {
            emplace_front(value);
        }

        template 
        void emplace_front_without_checks(Args&& ... args)
        {
            --read_pos;
            new (&read_ptr()) T(std::forward(args)...);
        }

        template 
        bool try_emplace_front(Args&& ... args)
        {
            if (full())
                return false;
            emplace_front_without_checks(std::forward(args)...);
        }

        template 
        void emplace_front(Args&& ... args)
        {
            if (full())
                pop_back();
            emplace_front_without_checks(std::forward(args)...);
        }

        template 
        void insert_front(InputIterator first, InputIterator last)
        {
            std::copy(first, last, std::front_inserter(*this));
        }

        /*
        extraction methods
        */

        /*
        extract from the front of the buffer
        used with back insertion to make a FIFO queue
        */

        void pop_front(value_type& value)
        {
            auto& elem = read_ptr();
            value = std::move(elem);
            elem.~T();
            ++read_pos;
        }

        bool try_pop_front(value_type& value)
        {
            if (empty())
                return false;
            pop_front(value);
            return true;
        }

        void pop_front()
        {
            read_ptr().~T();
            ++read_pos;
        }

        bool try_pop_front()
        {
            if (empty())
                return false;
            pop_front();
            return true;
        }

        // dumps num of first elements into dest where dest points to initialized memory
        template 
        void pop_front(OutputIterator dest, size_t num)
        {
            move_from_front(dest, num);
            if constexpr (std::is_pod_v)
                read_pos += num;
            else
            {
                while (num--)
                    pop_front();
            }
        }

        // dumps num of first elements into dest where dest points to uninitialized memory
        template 
        void pop_front(OutputIterator dest, size_t num, no_init_t)
        {
            move_from_front(dest, num, no_init);
            if constexpr (std::is_pod_v)
                read_pos += num;
            else
            {
                while (num--)
                    pop_front();
            }
        }

        template 
        bool try_pop_front(OutputIterator dest, size_t num)
        {
            if (num > size())
                return false;
            pop_front(dest, num);
            return true;
        }

        template 
        bool try_pop_front(OutputIterator dest, size_t num, no_init_t)
        {
            if (num > size())
                return false;
            pop_front(dest, num, no_init);
            return true;
        }


        /*
        extract from the back of the buffer
        used with back insertion to make a LIFO queue
        */

        void pop_back(value_type& value)
        {
            --write_pos;
            auto& elem = write_ptr();
            value = std::move(elem);
            elem.~T();
        }

        bool try_pop_back(value_type& value)
        {
            if (empty())
                return false;
            pop_back(value);
            return true;
        }

        void pop_back()
        {
            --write_pos;
            write_ptr().~T();
        }

        bool try_pop_back()
        {
            if (empty())
                return false;
            pop_back();
            return true;
        }

        template 
        void pop_back(OutputIterator dest, size_t num)
        {
            move_from_back(dest, num);
            if constexpr (std::is_pod_v)
                write_pos -= num;
            else
            {
                while (num--)
                    pop_back();
            }
        }

        template 
        void pop_back(OutputIterator dest, size_t num, no_init_t)
        {
            move_from_back(dest, num, no_init);
            if constexpr (std::is_pod_v)
                write_pos -= num;
            else
            {
                while (num--)
                    pop_back();
            }
        }

        template 
        bool try_pop_back(OutputIterator dest, size_t num)
        {
            if (size() < num)
                return false;
            pop_back(dest, num);
            return true;
        }

        template 
        bool try_pop_back(OutputIterator dest, size_t num, no_init_t)
        {
            if (size() < num)
                return false;
            pop_back(dest, num, no_init);
            return true;
        }

        /*
        accesors
        */

        reference front() { return read_ptr(); }

        reference back()
        {
            auto pos = write_pos;
            --pos;
            return raw_buffer(pos.as_index(N));
        }

        const_reference front() const { return read_ptr(); }

        const_reference back() const
        {
            auto pos = write_pos;
            --pos;
            return raw_buffer(pos.as_index(N));
        }

        reference operator()(size_type pos) noexcept
        {
            auto index = read_pos + pos;
            return raw_buffer(index.as_index(N));
        }

        const_reference operator()(size_type pos) const noexcept
        {
            auto index = read_pos + pos;
            return raw_buffer(index.as_index(N));
        }

        /*
        ^ ==> read pointer
        > ==> write pointer
        data starts from read pointer to write pointer

        1 - linearized (from empty to full) : there is one array starting from read pointer to write pointer
        --------------------------------------------------------------------------
        | ^ | 1 | 2 | 3 | 4 | 5 | > |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
        --------------------------------------------------------------------------

        2 - not linearized :
        the first array is from read pointer until the end of the buffer (last index N-1)
        the second array is from the start of the buffer until the write pointer
        --------------------------------------------------------------------------------------
        | 6 | 7 | 8 | > |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | ^ | 1 | 2 | 3 | 4 | 5 |  
        --------------------------------------------------------------------------------------
        */

        std::span array_one() noexcept
        {
            pointer read_pointer = &read_ptr();
            if (is_linearized()) // or empty
                return std::span{read_pointer, read_pointer + size()};
            else
                return std::span{read_pointer, raw_buffer.ptr() - read_pointer + size()};
        }

        std::span array_one() const noexcept
        {
            pointer read_pointer = &read_ptr();
            if (is_linearized()) // or empty
                return std::span{read_pointer, read_pointer + size()};
            else
                return std::span{read_pointer, raw_buffer.ptr() - read_pointer + size()};
        }

        std::span array_two() noexcept
        {
            if (is_linearized())
                return {};
            else
            {
                return std::span{raw_buffer.ptr(), &write_ptr()};
            }
        }

        std::span array_two() const noexcept
        {
            if (is_linearized())
                return {};
            else
            {
                return std::span{raw_buffer.ptr(), &write_ptr()};
            }
        }

        void copy_from_front(value_type& value) const
        {
            value = front();
        }

        value_type copy_from_front() const
        {
            value_type value;
            copy_from_front(value);
            return value;
        }

        void move_from_front(value_type& value)
        {
            value = std::move(front());
        }

        value_type move_from_front()
        {
            value_type value;
            move_from_front(value);
            return value;
        }

        template 
        void copy_from_front(OutputIterator dest, size_t num) const
        {
            if (is_linearized())
            {
                pointer begin_iter = &read_ptr();
                pointer end_iter = begin_iter + num;
                std::copy(begin_iter, end_iter, dest);
            }
            else
            {
                auto begin_iter = begin();
                auto end_iter = begin_iter + num;
                std::copy(begin_iter, end_iter, dest);
            }
        }

        template 
        void copy_from_front(OutputIterator dest, size_t num, no_init_t) const
        {
            if (is_linearized())
            {
                pointer begin_iter = &read_ptr();
                pointer end_iter = begin_iter + num;
                std::uninitialized_copy(begin_iter, end_iter, dest);
            }
            else
            {
                auto begin_iter = begin();
                auto end_iter = begin_iter + num;
                std::uninitialized_copy(begin_iter, end_iter, dest);
            }
        }

        template 
        void move_from_front(OutputIterator dest, size_t num)
        {
            if (is_linearized())
            {
                pointer begin_iter = &read_ptr();
                pointer end_iter = begin_iter + num;
                std::copy(std::make_move_iterator(begin_iter), std::make_move_iterator(end_iter), dest);
            }
            else
            {
                auto begin_iter = begin();
                auto end_iter = begin_iter + num;
                std::copy(std::make_move_iterator(begin_iter), std::make_move_iterator(end_iter), dest);
            }
        }

        template 
        void move_from_front(OutputIterator dest, size_t num, no_init_t)
        {
            if (is_linearized())
            {
                pointer begin_iter = &read_ptr();
                pointer end_iter = begin_iter + num;
                std::uninitialized_move(begin_iter, end_iter, dest);
            }
            else
            {
                auto begin_iter = begin();
                auto end_iter = begin_iter + num;
                std::uninitialized_move(begin_iter, end_iter, dest);
            }
        }

        void copy_from_back(value_type& value) const
        {
            value = back();
        }

        value_type copy_from_back() const
        {
            value_type value;
            copy_from_back(value);
            return value;
        }

        void move_from_back(value_type& value)
        {
            value = std::move(back());
        }

        value_type move_from_back()
        {
            value_type value;
            move_from_back(value);
            return value;
        }

        template 
        void copy_from_back(OutputIterator dest, size_t num) const
        {
            if (is_linearized())
            {
                pointer end_iter = &write_ptr();
                pointer first = end_iter - num;
                std::copy(first, end_iter, dest);
            }
            else
            {
                auto end_iter = end();
                auto first = end_iter - num;
                std::copy(first, end_iter, dest);
            }
        }

        template 
        void copy_from_back(OutputIterator dest, size_t num, no_init_t) const
        {
            if (is_linearized())
            {
                pointer end_iter = &write_ptr();
                pointer first = end_iter - num;
                std::uninitialized_copy(first, end_iter, dest);
            }
            else
            {
                auto end_iter = end();
                auto first = end_iter - num;
                std::uninitialized_copy(first, end_iter, dest);
            }
        }

        template 
        void move_from_back(OutputIterator dest, size_t num)
        {
            if (is_linearized())
            {
                pointer end_iter = &write_ptr();
                pointer first = end_iter - num;
                std::copy(std::make_move_iterator(first), std::make_move_iterator(end_iter), dest);
            }
            else
            {
                auto end_iter = end();
                auto first = end_iter - num;
                std::copy(std::make_move_iterator(first), std::make_move_iterator(end_iter), dest);
            }
        }

        template 
        void move_from_back(OutputIterator dest, size_t num, no_init_t)
        {
            if (is_linearized())
            {
                pointer end_iter = &write_ptr();
                pointer first = end_iter - num;
                std::uninitialized_move(first, end_iter, dest);
            }
            else
            {
                auto end_iter = end();
                auto first = end_iter - num;
                std::uninitialized_move(first, end_iter, dest);
            }
        }

        /*
        range methods
        */

        iterator begin() noexcept { return iterator{raw_buffer.ptr(), read_pos, N}; }

        iterator end() noexcept { return iterator{raw_buffer.ptr(), write_pos, N}; }

        const_iterator begin() const noexcept { return const_iterator{raw_buffer.ptr(), read_pos, N}; }

        const_iterator end() const noexcept { return const_iterator{raw_buffer.ptr(), write_pos, N}; }

        const_iterator cbegin() const noexcept { return begin(); }

        const_iterator cend() const noexcept { return end(); }

        reverse_iterator rbegin() noexcept { return reverse_iterator{ raw_buffer.ptr(), write_pos - 1, N }; }

        reverse_iterator rend() noexcept { return reverse_iterator{ raw_buffer.ptr(), read_pos - 1, N }; }

        const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator{ raw_buffer.ptr(), write_pos - 1, N }; }

        const_reverse_iterator rend() const noexcept { return const_reverse_iterator{ raw_buffer.ptr(), read_pos - 1, N }; }

        const_reverse_iterator crbegin() const noexcept { return rbegin(); }

        const_reverse_iterator crend() const noexcept { return rend(); }


        /*
        eraser, linearization, resize and some info
        */

        void clear()
        {
            if constexpr (std::is_pod_v)
            {
                read_pos.reset();
                write_pos.reset();
            }
            else
            {
                while (!empty())
                    pop_front();
            }
        }

        pointer linearize()
        {
            ring_buffer rbf(N);
            auto first_array = array_one();
            rbf.insert_back(std::make_move_iterator(first_array.begin()), std::make_move_iterator(first_array.end()));
            auto second_array = array_two();
            rbf.insert_back(std::make_move_iterator(second_array.begin()), std::make_move_iterator(second_array.end()));
            this->operator=(std::move(rbf));
            return raw_buffer.ptr();
        }

        template 
        void linearize(OutputIterator dest) const
        {
            auto first_array = array_one();
            std::copy(first_array.begin(), first_array.end(), dest);
            auto second_array = array_two();
            std::copy(second_array.begin(), second_array.end(), dest + first_array.size());
        }

        void set_capacity(size_type Num)
        {
            clear();
            N = Num;
            raw_buffer.resize(Num);
        }

        size_t capacity() const noexcept { return N; }

        size_t size() const noexcept { return write_pos - read_pos; }

        size_t available_size() const noexcept { return capacity() - size(); }

        size_t reserve() const noexcept { return available_size(); }

        bool full() const noexcept { return size() == capacity(); }

        bool empty() const noexcept { return !size(); }

        bool is_linearized() const noexcept 
        {
            ring_buffer_index last_pos = write_pos - 1;
            return last_pos.as_index(N) >= read_pos.as_index(N);
        }

        /*
        aliases to use the ring buffer as FIFO
        */

        template 
        void emplace(Args&& ... args)
        {
            emplace_back(std::forward(args)...);
        }

        void push(const value_type& value)
        {
            push_back(value);
        }

        void push(value_type&& value)
        {
            push_back(std::move(value));
        }

        template 
        void insert(InputIterator first, InputIterator last)
        {
            insert_back(first, last);
        }

        void pop(value_type& value)
        {
            pop_front(value);
        }

        bool try_pop(value_type& value)
        {
            return try_pop_front(value);
        }

        void pop()
        {
            pop_front();
        }

        bool try_pop()
        {
            return try_pop_front();
        }

        template 
        void pop(OutputIt dest, size_t num)
        {
            pop_front(dest, num);
        }

        template 
        void pop(OutputIt dest, size_t num, no_init_t)
        {
            pop_front(dest, num, no_init);
        }

        template 
        bool try_pop(OutputIt dest, size_t num)
        {
            return try_pop_front(dest, num);
        }

        template 
        bool try_pop(OutputIt dest, size_t num, no_init_t)
        {
            return try_pop_front(dest, num, no_init);
        }

    };

The header span.h can be found here:
https://github.com/some-coder366/ring-buffer/blob/master/span.h

I've found it somewhere on the Internet for a few months, but I do not remember where I pulled it and, as the title says, it's about an implementation of the new span c ++ 20 which represents a view for a range of contiguous memories like string_view but it allows to access the values ​​if it is not const

I want to know :

  • Does the implementation misuse the concept of circular buffer?
  • do the iterators respond to the c ++ concept of iterators?
  • are there any disadvantages to using the indexes as counters and getting the real indexes with module, especially for larger values?
  • is it preferable that the "crush" operation be destroyed and built instead or as the boost does: reassign

I used the old approach because of some things:

First, the standard does not state that the moved object is no longer valid, but it is still usable and must be destroyed. However, for most types, a move operation is a destruction (as in the case of rust).

second, a reallocation usually involves the destruction and rebuilding of a new instance in place of the existing class, sometimes with more checks:

class SomeClass
{
public:

    SomeClass()
    {
       buffer = new char(100);
    }

    ~SomeClass()
    {
        clear();
    }

    SomeClass& operator=(const SomeClass& other)
    {
        if (std::addressof(other) != this) // ---> extra check
        {
            clear(); // ---> destructing
            // reassign == reconstruct
        }
        return *this;
    }

    void clear()
    {
       if (buffer) delete() buffer;
       buffer = nullptr;
    }

private:
    char *buffer;
};

there are also other checks in the circular buffer to determine if this location contains uninitialized memory or an initialized object to decide whether to build or assign