Tarion
Tarion

Reputation: 17134

Is there a container with dynamic size but no allocation in c++?

I'm programming C++ for embedded constraint devices.

I often have some memory on the stack or heap and need a container like a vector to access parts of it. For example when parsing some message with 20 bytes I want a container to access byte 5 to 10.

The container would need a start pointer, end pointer and must not allocate nor free memory. Is there something in c++ that helps me here?

vector allocates memory, array needs a fixed size which I do not know before.

Upvotes: 3

Views: 906

Answers (3)

Caleth
Caleth

Reputation: 62719

You can create a simple view type that has the same members as std::array, but without owning the underlying array. All of the members have obvious implementations

template <typename T>
struct view {
    using value_type             = T;
    using size_type              = std::size_t;
    using difference_type        = std::ptrdiff_t;
    using reference              = value_type&;
    using const_reference        = const value_type&;
    using pointer                = value_type*;
    using const_pointer          = const value_type*;
    using iterator               = value_type*;
    using const_iterator         = const value_type*;
    using reverse_iterator       = std::reverse_iterator<value_type*>;
    using const_reverse_iterator = std::reverse_iterator<const value_type*>;

    view(pointer b = nullptr, pointer e = nullptr) : begin_(b), end_(e) {}
    template<size_type N>
    view(T (&arr)[N]) : begin_(arr), end_(arr + N) {}
    view(const view &) = default;
    view(view&&) = default;

    reference at(size_type i) { if (i < 0 || i > size()) throw std::out_of_range(); return *(begin_ + i); }
    const_reference at(size_type i) const { if (i < 0 || i > size()) throw std::out_of_range(); return *(begin_ + i); }

    reference operator[](size_type i) { return *(begin_ + i); }
    const_reference operator[](size_type i) const { return *(begin_ + i); }

    reference front() { return *begin_; }
    const_reference front() const { return *begin_; }

    reference back() { return *(end_ -1); }
    const_reference back() const { return *(end_ -1); }

    pointer data() { return begin_; }
    const_pointer data() const { return begin_; }

    iterator begin() { return begin_; }
    iterator end() { return end_; }

    const_iterator begin() const { return begin_; }
    const_iterator end() const { return end_; }

    const_iterator cbegin() const { return begin_; }
    const_iterator cend() const { return end_; }

    reverse_iterator rbegin() { return { begin_ }; }
    reverse_iterator rend() { return { end_ }; }

    const_reverse_iterator rbegin() const { return { begin_ }; }
    const_reverse_iterator rend() const { return { end_ }; }

    const_reverse_iterator crbegin() const { return { begin_ }; }
    const_reverse_iterator crend() const { return { end_ }; }

    bool empty() const { return begin_ == end_; }
    difference_type size() const { return end_ - begin_; }
    difference_type max_size() const { return std::numeric_limits<difference_type>::max() / sizeof(T); }

private:
    T * begin_, end_;
};

Upvotes: 4

ks1322
ks1322

Reputation: 35716

For example when parsing some message with 20 bytes I want a container to access byte 5 to 10.

I think you don't need any more containers for this. If the message is already stored in already allocated array all you need is a pair of iterators to memory range inside array. Now you can pass these iterators to some stl algorithm to perform the job you want or write your own.

Upvotes: 5

eerorika
eerorika

Reputation: 238351

Is there a container with dynamic size but no allocation in c++?

There is no such container in standard C++.

C99 does have variable length arrays and some C++ compilers provide that feature as a language extension.


I often have some memory ... and need a container like a vector to access parts of it.

You don't need a container like a vector to access parts of memory. You can access memory directly. Example:

char c;
char* = memory_address;
c = memory_address[0]; // read access
memory_address[0] = c; // write access

Upvotes: 1

Related Questions