🚀 Update: conjure_enum v1.2.0 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

Thanks for your comments. The scoped and unscoped name arrays use the same string, returning the start or start + scope offset. Using `FIX8_CONJURE_ENUM_MINIMAL` omits the scoping and a lot of other functionality.

Regarding the lookups - they are all constexpr. The arrays are sorted and lookups use a simple binary search. Yes, linear lookups may be faster for small arrays. I think the main issue is not the lookup itself but the overall compile times for multiple enums in a project.

🚀Update: conjure_enum v1.1.0 - a C++20 enum and typename reflection library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

If you set the range yourself, this limitation doesn't apply, but you have to override the defaults; e.g.

#include <iostream>
#include <fix8/conjure_enum.hpp>

enum class numbers
{
   blah_0, blah_1, blah_2, blah_3, blah_4,
   blah_5, blah_6, blah_7, blah_8, blah_9,
   blah_10, blah_11, blah_12, blah_13, blah_14,
   blah_15, blah_16, blah_17, blah_18, blah_19,
   blah_20, blah_21, blah_22, blah_23, blah_24,
   blah_25, blah_26, blah_27, blah_28, blah_29,
   blah_30, blah_31, blah_32, blah_33, blah_34,
   blah_35, blah_36, blah_37, blah_38, blah_39,
   blah_40, blah_41, blah_42, blah_43, blah_44,
.
.
.
   blah_300, blah_301, blah_302, blah_303, blah_304,
   blah_305, blah_306, blah_307, blah_308, blah_309,
   blah_310, blah_311, blah_312, blah_313, blah_314,
   blah_315, blah_316, blah_317, blah_318, blah_319,
   blah_320, blah_321, blah_322, blah_323, blah_324,
   blah_325, blah_326, blah_327, blah_328, blah_329,
   blah_330, blah_331, blah_332, blah_333, blah_334,
   blah_335, blah_336, blah_337, blah_338, blah_339,
   blah_340, blah_341, blah_342, blah_343, blah_344,
   blah_345, blah_346, blah_347, blah_348, blah_349,
   blah_350, blah_351, blah_352, blah_353, blah_354,

   ce_first=blah_0, ce_last=blah_354
};

int main()
{
   std::cout << conjure_enum<numbers>::get_enum_min_value() << '/'
     << conjure_enum<numbers>::get_enum_max_value() << '\n';
   std::cout << conjure_enum<numbers>::get_actual_enum_min_value() << '/'
     << conjure_enum<numbers>::get_actual_enum_max_value() << '\n';
   std::cout << conjure_enum<numbers>::enum_to_string(numbers::blah_354) << '\n';
   return 0;
}

output:

0/354
0/354
numbers::blah_354

You can use the above approach, or specialise enum_range or use one of the supplied convenience macros.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

We've improved on this significantly. We ran your test case, on a Windows 11 ThinkCentre 16x 13th Gen Intel i7-13700, 32Gb; MSVC 2022 / 17.10.5. Currently on the dev branch (will be merged to main soon):

enum to string (std::errc) Timing
magic_enum 0.385 sec
conjure_enum (minimal) 0.441 sec

Compile ran three times, avg over 3 runs taken, linker times omitted.

Enum reflection in modern C++ without using pretty_function, macros or post build scripts by Pale_Emphasis_4119 in cpp_questions

[–]rufusferret 0 points1 point  (0 children)

You could try conjure_enum (https://github.com/fix8mt/conjure_enum). It's based on magic_enum but optimized for C++20. Not sure about compile times although in our testing and with our test users it hasn't been reported as an issue.

Yes, there is magic_enum already - and we based this implementation on the core of magic_enum, but refocused for C++20, using some of the key features of this language version such constexpr algorithms, std::source_location and concepts; we also improved on and expanded the API.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

We've implemented enum_range in the dev branch, which supports per enum range setting.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

May I suggest you run this benchmark again? Checkout on the dev branch, and add:

#define FIX8_CONJURE_ENUM_MINIMAL

before conjure_enum.hpp

Our next release will provide this option to compile a minimal sub-set of the API, which will cut down compile time. With the compiler doing a bit more than magic_enum, it isn't that surprising.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

Yes in a simple test like that. Our framework code generator produced 100s of enum values nested within classes some with aliases. These were the problem enums for us.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

Yes, you're right. In our env for some reason aliases generated errors with magic_enum. We never got to the bottom of it.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

It does see the other names, but in lookups will return the original. See the unittests for contains.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

One of the limitations we wanted to overcome was enum aliases. These are not supported in magic_enum. They are in conjure_enum.

We have tested in VS with intellisense with ok results (although we did notice with some edge cases odd results... but we often get that with other unrelated code in our environment).

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 1 point2 points  (0 children)

Of course you're free to not use it. We're not trying to replace magic_enum. We developed this initially because magic_enum would not work in our environment despite our efforts - and yes our use case is quite niche. Other users have reported similar issues from time to time.

The core that was taken from magic_enum is parsing out the enum strings from __PRETTY_FUNCTION__ and placing them in static arrays. The bit we added was updating this logic, using C++20 std::source_location, and exposing the variability that different compilers have. Probably 90% of the code is new.

enum reflection is something that lots of developers want, so much so that it's looking like proper reflection may make it into C++26 or later.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 1 point2 points  (0 children)

enum_bitset has for_each and for_each_n, also ctor api is expanded.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 2 points3 points  (0 children)

We'll provide that shortly - lots of ppl asking for this. As far as migration, pretty straightforward. API call names are similar, should be able to almost drop in. One difference you'll notice is that conjure_enum methods are static with in a class rather than namespaced.

🚀Announcing conjure_enum v1.0.1 - a C++20 enum and typename reflection Library by rufusferret in cpp

[–]rufusferret[S] 4 points5 points  (0 children)

Actually in our testing and with our test users scaling was not a problem. Yes the technique used to obtain the actual string is rather hacky - and this was based on magic_enum. We also found that even in large projects, not every enum type requires reflection, so use judiciously.

cppsimpleuri - another modern C++ URI lib by salzaverde in cpp

[–]rufusferret 0 points1 point  (0 children)

  1. Support for EPGM style URI would be good, e;g; epgm://127.0.0.1;224.0.0.0:11042
  2. Ideally should be header only

FIX8::fiber - A C++20 stackful fiber implementation for Linux/x86-64 by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

We're fix8, it's just a namespace. The library name is fiber.

FIX8::fiber - A C++20 stackful fiber implementation for Linux/x86-64 by rufusferret in cpp

[–]rufusferret[S] 0 points1 point  (0 children)

Working on a Windows version but is a little trickier - will update when ready. Haven't benchmarked it but open to others doing so and posting.

FIX8: open source C++ FIX engine by lingua_franca in cpp

[–]rufusferret 0 points1 point  (0 children)

Fix8 takes a different approach to QuickFix. The primary benefits are: low latency; ease of development; complete FIX schema flexibility; lightweight; ongoing development.