Skip to content

Commit

Permalink
pre-v1.0-update2
Browse files Browse the repository at this point in the history
  • Loading branch information
dakka committed Mar 30, 2024
1 parent d559e85 commit 08e5eda
Show file tree
Hide file tree
Showing 4 changed files with 368 additions and 289 deletions.
42 changes: 18 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,39 +1,33 @@
# -----------------------------------------------------------------------------------------
# SPDX-License-Identifier: MIT
# conjure_enum (header only)
# Copyright (C) 2024 Fix8 Market Technologies Pty Ltd
# by David L. Dight
# see https://github.com/fix8mt/conjure_enum
#
# Lightweight header-only C++20 enum reflection
#
# Based on magic_enum <https://github.com/Neargye/magic_enum>
# Licensed under the MIT License <http://opensource.org/licenses/MIT>.
# SPDX-License-Identifier: MIT
# Copyright (c) 2019 - 2024 Daniil Goncharov <[email protected]>.
#
# Lightweight header-only C++20 enum reflection
#
# Distributed under the Boost Software License, Version 1.0 August 17th, 2003
# Licensed under the MIT License <http://opensource.org/licenses/MIT>.
#
# Permission is hereby granted, free of charge, to any person or organization
# obtaining a copy of the software and accompanying documentation covered by
# this license (the "Software") to use, reproduce, display, distribute,
# execute, and transmit the Software, and to prepare derivative works of the
# Software, and to permit third-parties to whom the Software is furnished to
# do so, all subject to the following:
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is furnished
# to do so, subject to the following conditions:
#
# The copyright notices in the Software and this entire statement, including
# the above license grant, this restriction and the following disclaimer,
# must be included in all copies of the Software, in whole or in part, and
# all derivative works of the Software, unless such copies or derivative
# works are solely in the form of machine-executable object code generated by
# a source language processor.
# The above copyright notice and this permission notice (including the next paragraph)
# shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
# SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
# FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# ----------------------------------------------------------------------------------------
cmake_minimum_required (VERSION 3.20)
project (conjure_enum
Expand Down
208 changes: 106 additions & 102 deletions examples/example.cpp
Original file line number Diff line number Diff line change
@@ -1,144 +1,93 @@
//-----------------------------------------------------------------------------------------
// SPDX-License-Identifier: MIT
// conjure_enum (header only)
// Copyright (C) 2024 Fix8 Market Technologies Pty Ltd
// by David L. Dight
// see https://github.com/fix8mt/conjure_enum
//
// Lightweight header-only C++20 enum reflection
//
// Based on magic_enum <https://github.com/Neargye/magic_enum>
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
// SPDX-License-Identifier: MIT
// Copyright (c) 2019 - 2024 Daniil Goncharov <[email protected]>.
//
// Lightweight header-only C++20 enum reflection
//
// Distributed under the Boost Software License, Version 1.0 August 17th, 2003
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is furnished
// to do so, subject to the following conditions:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// The above copyright notice and this permission notice (including the next paragraph)
// shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//----------------------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include <memory>
#include <format>
#if defined(__clang__) || defined(__GNUC__)
#include <cxxabi.h>
#endif

#include <fix8/conjure_enum.hpp>

//-----------------------------------------------------------------------------------------
using namespace std::literals::string_view_literals;
using namespace std::literals::string_literals;
//-----------------------------------------------------------------------------------------
using namespace FIX8;

//-----------------------------------------------------------------------------------------
enum class component : int { scheme, authority, userinfo, user, password, host, port, path=12, test=path, query, fragment };
enum component1 : int { scheme, authority, userinfo, user, password, host, port, path=12, query, fragment };
enum class numbers : int { zero, one, two, three, four, five, six, seven, eight, nine };
enum class numbers1 : int { zero=4, one=3, two=2, three, four, five, six, seven, eight, nine };

int main(int argc, char *argv[])
//-----------------------------------------------------------------------------------------
template<typename T>
const std::string demangle() noexcept
{
/*
std::cout << get_name(epeek<component, component::user>()) << '\n';
*/
if (conjure_enum<component>::is_valid<component::password>())
std::cout << "valid\n";
else
std::cout << "not valid\n";
if (conjure_enum<component>::is_valid<static_cast<component>(16)>())
std::cout << "valid\n";
else
std::cout << "not valid\n";

/*
for(const auto ev : conjure_enum::enum_values<component>)
std::cout << static_cast<int>(ev) << '\n';
for(const auto [a, b] : conjure_enum::enum_entries<component>)
std::cout << '*' << static_cast<int>(a) << ' ' << conjure_enum::remove_scope<component>(b) << '\n';
for(const auto ev : conjure_enum::enum_values<component1>)
std::cout << static_cast<int>(ev) << '\n';
for(const auto ev : conjure_enum::enum_names<component>)
std::cout << ev << '\n';
std::cout << conjure_enum::enum_names<component>[5] << '\n';
enum_bitset<numbers> n1(numbers::zero,numbers::one,numbers::three,numbers::seven,numbers::nine);
n1.for_each([](numbers val) noexcept
#if defined(__clang__) || defined(__GNUC__)
int status;
std::unique_ptr<char, decltype(&free)> eptr(abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status), &free);
switch (status)
{
std::cout << conjure_enum::enum_to_string<numbers>(val) << '(' << static_cast<int>(val) << ')' << '\n';
});
*/
/*
for (auto itr{conjure_enum::cbegin<component>()}; itr != conjure_enum::cend<component>(); ++itr)
{
const auto [a, b] {*itr};
std::cout << static_cast<int>(a) << ' ' << conjure_enum::remove_scope<component>(b) << '\n';
}*/

/*
std::cout << "1: " << std::string_view(conjure_enum::enum_name_v<component, component::fragment>) << '\n';
std::cout << "2: " << conjure_enum::enum_name<component, component::fragment>().get() << '\n';
std::cout << "3: " << conjure_enum::enum_to_string(component::path, true) << '\n';
std::cout << "4: " << conjure_enum::enum_to_string(component::test) << '\n';
std::cout << "16: " << '\"' << conjure_enum::enum_to_string(static_cast<component>(100)) << '\"' << '\n';
std::cout << "5: " << conjure_enum::enum_to_string(path) << '\n';
std::cout << "6: " << static_cast<int>(conjure_enum::string_to_enum<component>("component::path").value()) << '\n';
std::cout << "7: " << static_cast<int>(conjure_enum::string_to_enum<component1>("path").value()) << '\n';
std::cout << "8: " << static_cast<int>(conjure_enum::string_to_enum<component>("wrong").value_or(component(100))) << '\n';
std::cout << "9: " << conjure_enum::get_name<component1, scheme>() << '\n';
std::cout << "10: " << conjure_enum::get_name<component, component::scheme>() << '\n';
std::cout << "16: " << conjure_enum::get_type<component>() << '\n';
std::cout << "16: " << conjure_enum::get_type<component1>() << '\n';
*/

/*
//using enum component;
//std::cout << std::boolalpha << is_scoped<component, scheme>() << '\n';
std::cout << "11: " << std::boolalpha << conjure_enum::is_scoped<component>() << '\n';
std::cout << "12: " << std::boolalpha << conjure_enum::is_scoped<component1>() << '\n';
std::string_view res1 { conjure_enum::enum_name_v<component, component::userinfo> };
std::cout << "13: " << res1 << '\n';
std::cout << "14: " << conjure_enum::enum_name_v<component, component::userinfo> << '\n';
std::cout << "15: " << conjure_enum::count<component>() << '\n';
if (auto result {conjure_enum::int_to_enum<component>(100)}; result)
std::cout << static_cast<int>(*result) << '\n';
else
std::cout << "invalid int to enum\n";
if (auto result {conjure_enum::int_to_enum<component>(12)}; result)
std::cout << static_cast<int>(*result) << '\n';
else
std::cout << "invalid int to enum\n";
case 0: return eptr.get();
case -1: return "memory allocation failiure"s;
case -2: return "invalid mangled name"s;
default: break; // includes -3 invalid argument
}
return "invalid argument"s;
#endif
return typeid(T).name();
}

int main(int argc, char *argv[])
{
int total{};
auto myfunc { conjure_enum::for_each<component>([](component val, int other, int& tot)
auto myfunc { conjure_enum<component>::for_each([](component val, int other, int& tot)
{
std::cout << static_cast<int>(val) << ' ' << other << '\n';
tot += static_cast<int>(val);
}, 10, std::ref(total)) };
myfunc(component::fragment);
std::cout << total << '\n';

// enum_bitset
enum class numbers : int { zero, one, two, three, four, five, six, seven, eight, nine };
//enum_bitset<component> ec;
enum_bitset<numbers> eb;
eb.set_all<numbers::zero,numbers::two,numbers::five,numbers::nine>();
std::cout << eb << '\n';
std::cout << eb.test_all<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
eb.clear_all<numbers::five>();
std::cout << eb.test_all<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
std::cout << std::boolalpha << eb.test_all<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
eb.clear_all<numbers::five,numbers::two>();
std::cout << std::boolalpha << eb.test_all(0, 2, 5, 9) << '\n';
std::cout << std::boolalpha << eb.test_any(0, 2, 5, 9) << '\n';
std::cout << std::boolalpha << eb.test_all(numbers::zero,numbers::nine) << '\n';
std::cout << eb << '\n';
eb.clear(numbers::nine);
std::cout << eb << '\n';
Expand All @@ -155,16 +104,71 @@ int main(int argc, char *argv[])
ec.flip();
std::cout << ec << '\n';
std::cout << std::boolalpha << conjure_enum<component>::enum_contains("component::path"sv) << '\n';
std::cout << std::boolalpha << conjure_enum<component>::enum_contains(argv[1]) << '\n';
//std::cout << std::boolalpha << conjure_enum<component>::enum_contains(argv[1]) << '\n';
for(const auto [a, b] : conjure_enum<component>::enum_entries_sorted)
std::cout << conjure_enum<component>::remove_scope(b) << ' ' << static_cast<int>(a) << '\n';
for(const auto [a, b] : conjure_enum<numbers1>::enum_entries)
std::cout << b << ' ' << static_cast<int>(a) << '\n';
*/
std::cout << conjure_enum<component>::add_scope("path"sv) << '\n';
std::cout << conjure_enum<component>::add_scope("component::path"sv) << '\n';
std::cout << conjure_enum<component1>::add_scope("path"sv) << '\n';
std::cout << conjure_enum<component>::enum_to_string<component::scheme>() << '\n';
std::cout << conjure_enum<component1>::enum_to_string<scheme>() << '\n';
using cje = conjure_enum<component>;
std::cout << std::boolalpha << cje::has_scope("component::scheme") << '\n';
std::cout << std::boolalpha << cje::has_scope("scheme") << '\n';
std::cout << std::boolalpha << cje::has_scope("scheme") << '\n';
std::cout << conjure_enum<component>::epeek<component::path>() << '\n';
std::cout << conjure_enum<component>::tpeek() << '\n';
std::cout << demangle<decltype(conjure_enum<component>::enum_scoped_entries)>() << '\n';
for(const auto [a, b] : conjure_enum<component>::enum_scoped_entries)
std::cout << a << ' ' << b << '\n';
std::cout << std::format(R"("{}")", conjure_enum<component>::enum_to_string(static_cast<component>(100))) << '\n';
std::cout << std::format(R"("{}")", conjure_enum<component>::enum_to_string(static_cast<component>(100))) << '\n';
enum_bitset<numbers> a(0, 1, 2, 3);
std::cout << a << '\n';
enum_bitset<numbers> b(numbers::zero, numbers::one, numbers::two, numbers::three);
std::cout << b << '\n';
enum_bitset<numbers> c(15);
std::cout << c << '\n';
for(const auto [a, b] : conjure_enum<component>::enum_scoped_entries)
std::cout << std::format("{:9} {}\n", a, b);
for(const auto [value, str] : conjure_enum<component>::enum_entries) // scoped
std::cout << std::format("{:<2} {}\n", static_cast<int>(value), str);
std::cout << std::format("{}\n", conjure_enum<component>::enum_contains("component::path"sv));
std::cout << std::format("\"{}\"\n", conjure_enum<component>::enum_to_string<component::scheme>());
auto printer([](numbers val)
{
std::cout << conjure_enum<numbers>::enum_to_string(val) << '\n';
});
enum_bitset<numbers> ec1("numbers::zero |numbers::two |numbers::five| numbers::nine", false);
std::cout << ec1 << '\n';
ec1.for_each(printer);
enum_bitset<numbers> ed("zero|two|five|\tnine", true);
std::cout << ed << '\n';
ed.for_each(printer);
try
{
enum_bitset<numbers> ee("twenty,two,rubbish,nine", true, ',', false);
std::cout << ee << '\n';
ee.for_each(printer);
}
catch(const std::invalid_argument& e)
{
std::cerr << "exception: " << e.what() << '\n';
}
enum_bitset<numbers> ef("one|three|four|eight"sv, true);
std::cout << ef << '\n';
ef.for_each(printer);
int a1{1}, b1{2}, c1{3}, d1{};
enum_bitset<numbers> eg(d1, a1, b1, c1);
std::cout << eg << '\n';
enum_bitset<numbers> ek(0, 1, 2, 3);
std::cout << ek << '\n';
std::cout << (ek & 0b111) << '\n';
ek ^= numbers::two;
std::cout << ek << '\n';
enum_bitset<numbers> eh("one three four eight "sv, true, ' ');
std::cout << eh << '\n';
return 0;
}
Loading

0 comments on commit 08e5eda

Please sign in to comment.