Skip to content

Nested containers with different sizes  #111

@ivan-aksamentov

Description

@ivan-aksamentov

I would like nested containers to have different sizes (all known at compile time). Is this possible?

For example, consider this map of sets:

// This dimension is variable           V
using Set = frozen::set<frozen::string, 3>;

constexpr frozen::map<frozen::string, Set, 4> table = {
  {"one", {"A"}},
  {"two", {"B", "C"}},
  {"three", {"D", "E", "F"}},
  {"-", {}},
};

And it's usage:

const auto& two = table.find("two");
// two is {"B", "C"}

const auto& three = table.find("three");
// three is {"D", "E", "F"}

As you see, sets inside the map have different length.

This currently won't compile:

error: no matching constructor for initialization of 'const frozen::map<frozen::string, Set, 4>' (aka 'const map<basic_string<char>, set<basic_string<char>, 3>, 4>')
constexpr frozen::map<frozen::string, Set, 4> table = {
                                              ^       ~
note: candidate constructor not viable: requires 2 arguments, but 4 were provided
  constexpr map(container_type items, Compare const &compare)
            ^
note: candidate constructor not viable: requires 2 arguments, but 4 were provided
  constexpr map(std::initializer_list<value_type> items, Compare const &compare)
            ^
note: candidate constructor not viable: requires single argument 'items', but 4 arguments were provided
  explicit constexpr map(container_type items)
                     ^
note: candidate constructor not viable: requires single argument 'items', but 4 arguments were provided
  constexpr map(std::initializer_list<value_type> items)
            ^
note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 4 were provided
class map {
      ^
note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 4 were provided

I thought, if sets really need to be of the same size, then maybe we could fill them with some dummy values, for example "?":

constexpr frozen::map<frozen::string, Set, 4> table = {
  {"one", {"A", "?", "?"}},
  {"two", {"B", "C", "?"}},
  {"three", {"D", "E", "F"}},
  {"-", {"?", "?", "?"}},
};

I can handle these dummy values in userspace and make sure I never search for the "?" in these sets, but from inside the library it can probably be handled more efficiently?

Application: reverse translation in biology. I need a lookup table to find a set of possible triplets (value of the map) for a given aminoacid (key of the map). The sets are at most 6 elements. This table is fundamental to biology and never changes, so runtime initialization would be certainly wasteful.

Sets can also be arrays, I guess. They are very small anyway.

Any other ideas on how this can be implemented without runtime initialization and associated static initialization order fiasco etc.?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions