Skip to content

TheMaverickProgrammer/varvec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Variable Vectors

Build Status Coverage Status

The idea behind this repository is to implement a set of "variable vector" types, built on top of std::variant machinery (although extensible to any type that implements the same API), allowing a user to store heterogenous types in a std::vector-like container, but while also maintaining a minimal memory footprint by contiguously packing data as tightly as possible.

For trivial types, the data is stored in a packed format that completely ignores alignment requirements (data is re-aligned on-demand during access), and for non-trivial user defined types, the data is stored on native alignment boundaries, but each entry only needs the storage required by the current type, not the common size of all types as would be the case with std::vector<std::variant<...>>.

Basic Usage

The library customizes into many different types, but at a high level there are only three types exported, a vector implementation, an iterator, and an overload helper for composing lambdas (still waiting on a standard option).

A motivating example akin to std::vector<std::variant<...>>:

#include <varvec.hpp>

int main() {
    // A complex vector type.
    using mixed_vector = varvec::static_vector<
        32,   // Total space to use for member storage
        5,    // Max members
        bool, // Types...
        int,
        float,
        double,
        std::unique_ptr<std::string>
    >;

    // Fill it with data of all types.
    mixed_vector vals;
    vals.push_back(true);
    vals.push_back(42);
    vals.push_back(0.5f);
    vals.push_back(3.14159);
    vals.push_back(std::make_unique<std::string>("hello world"));

    // Outputs:
    // Using visit_at syntax: 0.5
    // Using get_at syntax: hello world
    vals.visit_at(2, [] (auto& v) {
        std::cout << "Using visit_at syntax: " << v << std::endl;
    });
    std::cout
        << "Using get_at syntax: "
        << *vals.get_at<std::unique_ptr<std::string>>(4)
        << std::endl;

    // Outputs:
    // Range for: 1
    // Range for: 42
    // Range for: 0.5
    // Range for: 3.14159
    // Range for: hello world
    for (mixed_vector::value_type variant : vals) {
        std::visit(varvec::overload {
            [] <class T> (T* ptr) { std::cout << "Range for: " << **ptr << std::endl; },
            [] (auto& val) { std::cout << "Range for: " << val << std::endl; }
        }, variant);
    }

    // Outputs:
    // 39
    // std::vector<variant<...>> would require ~80 bytes.
    std::cout << vals.used_bytes() << std::endl;
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published