Boost logo

Boost :

From: Richard Hodges (hodges.r_at_[hidden])
Date: 2022-06-24 04:31:21


On Fri, 24 Jun 2022 at 02:01, Hadriel Kaplan <hadrielk_at_[hidden]> wrote:

> On Thursday, June 23, 2022, 05:20:01 PM EDT, Richard Hodges via Boost <
> boost_at_[hidden]> wrote:
>
> > Yes, I'm looking for a real-world use case. The trivial hypothetical
> cases
> > offered are building a static association between an enum value and some
> > other value.
> > This can be done with switch/case (for example), in about the same amount
> > of typing, at compile time, in a function.
>
> <snipped example switch-case code>
>
> OK, now show me how to iterate over it. And how to get a view or slice of
> it (i.e., std::span or range). And how to get the number of elements. :)
>

I understand that presenting the type with the look and feel of a container
is somehow pleasing. The ability might be an interesting academic goal.

I am more interested in what real-world use-cases this solves.

boost.describe, wise_enum etc solve the case where (for example) I wish to
serialise and deserialise my enum value as text. This is useful in the real
world as, for example, it allows me to easily and reliably implement a JSON
communications protocol that contains my enum.

Indexed array still has the maintenance burden of having to maintain both
the enum and the associative "array" separately.

>
> I mean ultimately, it's a container. It's not _only_ useful for key'ed
> lookup retrieval.
>
> You can change the value of whatever the container holds too, for example.
> Or maybe I'm misunderstanding your point? (could easily be the case)
>

> Anyway, the main use-case or value of it, in my mind anyway, is actually
> the one when using Boost.Describe. Because when you're using Describe for
> an enum, you only need to do this for indexed_array:
>
> indexed_array<string, MyEnum> data;
>
> That's powerful, because you do not need to repeat any code, do not need
> to repeat any sizing/number of enums, etc. If you add new enumerators to
> your enum, you don't need to change this instantiation of indexed_array.
> It's all automatic, and you can't screw up.
>
> The arbitrary intervals and non-contiguous use-cases I'm less convinced
> by. It's too easy to mess up.
>
> And arguably it's not really a "indexed_array" at that point anyway - the
> underlying container might happen to be a std::array, but that's an
> implementation detail. From the user's perspective it's more like a
> "static_map" or some such. Except... it's not actually necessarily sorted,
> is it? All the examples show them sorted, but I'm not sure it really is if
> the user doesn't define it that way? (I'm trying _not_ to read the code -
> only the docs)
>

Perhaps there is a case when seeking to parse a number of flags that are
presented as text and each flag may not appear more than once?

enum class NerfEnum : char {
  wounded = 'W',
  buffed = 'B';
  burning = 'N';
};
BOOST_DESCRIBE_ENUM(NerfEnum, (wounded, buffed, burning));

JSON input:
{
...
   "nerfs": [wounded, buffed, burning]
...
}

indexed_array might then be used to efficiently store the set of flags
associated with this unfortunate character.
But in this case, am I not better off with an unsigned int, where each flag
is represented by a bit?

The "natural code" might be:

unsigned flags = 0;
for(auto&& value : nerfsjson.as_array())
  flags |= to_bit(*deserialise<NerfEnum>(value.as_string());

I could imagine that being able to express this bitset with a
container-like interface might make my code more intuitive, but I don't
think that indexed_array addresses this case.
(I appreciate that such a container would have some of the same criticisms
of vector<bool>)

> -hadriel
>
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk