
On Thu, Jun 12, 2025 at 10:24 AM Alexander Grund via Boost < boost@lists.boost.org> wrote:
Compares the 2 approaches and I very much like the enum approach which does not pollute the global scope with constants that should be scoped too but isn't possibly with the strong type. See:
auto configuration = kUseSimd | kUsePrefetching;
auto config = ConfigEnum::UseSimd | ConfigEnum::UsePrefetching;
As I said before you can limit the scope by introducting a namespace, i.e. namespace ConfigEnum { All this is stylistic obviously, but I do not like that you are creating enum combination that does not represent any value from enum set. Now we both know in C++ everything is allowed :) and then some more, so you can freely bitwise or enums... BTW Interesting proposal from 9 years ago: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0375r0.html I am mostly talking about conceptual meaning of enum: set<int> is not int. Again to be clear I am not arguing with you, just saying why I prefer one style. And to keep our toy example from exploding into a full prototype I will just briefly recap what would I prefer to see in "full" solution 1. difference between flag, and flag combination 2. wrap atomic operations so users can operate on ConfigFlag, and ConfigFlagCombination(or AtomicConfigFlagCombination if we feel using atomic for each use case is too slow), while underlying logic is as if they are operating on atomic<uint32_t> 1. is : struct ConfigFlag { uint32_t val; }; // combination of 0 or more ConfigFlag struct ConfigFlagCombination { uint32_t val; }; ConfigFlagSet operator | (ConfigFlag a, ConfigFlag b) { return {a.val|b.val}; } 2. is: TODO :) I believe this may be considered over engineering a simple problem, but in large codebase where this pattern is used a lot might be worth it.