Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev to Main pre 1.0d release #6

Merged
merged 14 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# by David L. Dight
# see https://github.com/fix8mt/conjure_enum
#
# Lightweight header-only C++20 enum and type reflection
# Lightweight header-only C++20 enum and typename reflection
#
# Licensed under the MIT License <http://opensource.org/licenses/MIT>.
#
Expand All @@ -32,7 +32,7 @@ cmake_minimum_required (VERSION 3.20)
project (conjure_enum
LANGUAGES CXX
HOMEPAGE_URL https://github.com/fix8mt/conjure_enum
DESCRIPTION "Lightweight C++20 enum and type reflection"
DESCRIPTION "Lightweight C++20 enum and typename reflection"
VERSION 1.0.0)

# to disable strip:
Expand All @@ -52,7 +52,9 @@ message("-- Build unit tests: ${BUILD_UNITTESTS}")

function(build loc x)
add_executable(${x} ${loc}/${x}.cpp)
add_dependencies(${x} srcloctest) # srcloctest should be built even if errors with conjure_enum
if(NOT ${x} STREQUAL srcloctest)
add_dependencies(${x} srcloctest) # srcloctest should be built even if errors with conjure_enum
endif()
set_target_properties(${x} PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED true)
target_include_directories(${x} PRIVATE include)
if(BUILD_ALL_WARNINGS)
Expand Down
91 changes: 72 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// by David L. Dight
// see https://github.com/fix8mt/conjure_enum
//
// Lightweight header-only C++20 enum and type reflection
// Lightweight header-only C++20 enum and typename reflection
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
//
Expand All @@ -32,7 +32,7 @@
<a href="https://www.fix8mt.com"><img src="assets/conjure_enum_logo.png" width="200"></a>
</p>

<h3 align="center">Lightweight header-only C++20 enum and type reflection</h3>
<h3 align="center">Lightweight header-only C++20 enum and typename reflection</h3>

---

Expand Down Expand Up @@ -64,7 +64,7 @@
Based on the awesome work in [`magic_enum`](https://github.com/Neargye/magic_enum)[^2] and [`boost::describe`](https://github.com/boostorg/describe),
this library offers a streamlined and powerful way to add reflection capabilities to your C++ enums and other types. We've optimized the core functionality,
focusing on the main features developers usually want while enhancing and expanding them for a more efficient and expressive experience. We've also
added general purpose type reflection for any type.
added general purpose typename reflection for any type.

## b) Embrace the Future with C++20

Expand Down Expand Up @@ -97,6 +97,7 @@ unlocked the potential of `constexpr` algorithms and concepts. This translates t
- `add_scope`
- `remove_scope`
- `unscoped_string_to_enum`
- `for_each_n`
- iterators and more!
- ***Transparency***: Compiler implementation variability fully documented, verifiable and reportable (see 9 above)

Expand Down Expand Up @@ -414,7 +415,7 @@ _output_
true
false
```
## n) `for_each`
## n) `for_each`, `for_each_n`
```c++
template<typename Fn, typename... Args>
requires std::invocable<Fn&&, T, Args...>
Expand All @@ -423,9 +424,18 @@ requires std::invocable<Fn&&, T, Args...>
template<typename Fn, typename C, typename... Args> // specialisation for member function with object
requires std::invocable<Fn&&, C, T, Args...>
[[maybe_unused]] static constexpr auto for_each(Fn&& func, C *obj, Args&&... args);

template<typename Fn, typename... Args>
requires std::invocable<Fn&&, T, Args...>
[[maybe_unused]] static constexpr auto for_each_n(int n, Fn&& func, Args&&... args);

template<typename Fn, typename C, typename... Args> // specialisation for member function with object
requires std::invocable<Fn&&, C, T, Args...>
[[maybe_unused]] static constexpr auto for_each_n(int n, Fn&& func, C *obj, Args&&... args);
```
Call supplied invocable for _each_ enum value. Similar to `std::for_each` except the first parameter of your invocable must accept an enum value (passed by `for_each`).
Optionally provide any additional parameters. Works with lambdas, member functions, functions etc. The second version is intended to be used
Optionally provide any additional parameters. Works with lambdas, member functions, functions etc. You can limit the number of calls to your
invokable by using the `for_each_n` version with the first parameter being the maximum number to call. The second version of `for_each` and `for_each_n` is intended to be used
when using a member function - the _second_ parameter passed by your call must be the `this` pointer of the object.
If you wish to pass a `reference` parameter, you must wrap it in `std::ref`.

Expand All @@ -452,6 +462,19 @@ _output_
13 10
14 10
```
Above example using `for_each_n`, limiting to 3:
```c++
conjure_enum<component>::for_each_n(3, [](component val, int other)
{
std::cout << static_cast<int>(val) << ' ' << other << '\n';
}, 10);
```
_output_
```CSV
0 10
1 10
2 10
```
Example using returned object and additional reference parameter:
```c++
int total{};
Expand Down Expand Up @@ -708,7 +731,7 @@ constexpr enum_bitset(U bits);
constexpr enum_bitset(std::string_view from, bool anyscope=false,
char sep='|', bool ignore_errors=true);

template<valid_enum... E>
template<valid_bitset_enum... E>
constexpr enum_bitset(E... comp);

template<std::integral... I>
Expand Down Expand Up @@ -811,34 +834,41 @@ All of the standard accessors and mutators are supported.
| Method | Description |
| :--- | :--- |
| `test` | test for bit(s)|
| `set` | set bit(s)|
| `set` | set all or 1 bit, optionally set to off|
| `reset` | reset bits(s)|
| `flip` | flip bits(s)|
| `to_ulong` | convert to `unsigned long` |
| `to_ullong` | convert to `unsigned long long` |
| `count` | count of bits on |
| `size` | number of bits in bitset |
| `operator[]` | test bit at position |
| `any` | return true if any bit is on |
| `all` | return true if all bits are on |
| `none` | return true if no bits are on |

Additional methods
| Method | Description |
| :--- | :--- |
| `set_all` | set all specified bits |
| `reset_all` | reset all specified bits |
| `test_any` | test for one or more bits |
| `test_all` | test for all specified bits |
| `set` | set all specified bits, templated |
| `reset` | reset all specified bits, templated |
| `any_of` | test for one or more bits, templated, function, types and underlyings |
| `all_of` | test for all specified bits, templated, function, types and underlyings |
| `none_of` | test for all specified bits set to off, templated, function, types and underlyings |
| `not_count` | complement of count, count of off bits |

Take a look at the [implementation](include/fix8/conjure_enum.hpp) for more detail on the various API functions available.

All accessors and mutators work with enum values or integers as with operators. They also work with multiple values, either as template parameters or
as variadic arguments:
```c++
enum_bitset<numbers> eb;
eb.set_all<numbers::zero,numbers::two,numbers::five,numbers::nine>();
eb.set<numbers::zero,numbers::two,numbers::five,numbers::nine>();
std::cout << eb << '\n';
std::cout << std::boolalpha << eb.test_all<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
std::cout << std::boolalpha << eb.all_of<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
eb.reset<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 << std::boolalpha << eb.all_of(0, 2, 5, 9) << '\n';
std::cout << std::boolalpha << eb.any_of(0, 2, 5, 9) << '\n';
std::cout << std::boolalpha << eb.all_of(numbers::zero,numbers::nine) << '\n';
std::cout << eb << '\n';
eb.reset(numbers::nine)
std::cout << ec << '\n';
Expand Down Expand Up @@ -887,7 +917,7 @@ _output_
0001001010
---+--+-+-
```
### iii. `for_each`
### iii. `for_each`, `for_each_n`
```c++
template<typename Fn, typename... Args>
requires std::invocable<Fn&&, T, Args...>
Expand All @@ -896,9 +926,18 @@ requires std::invocable<Fn&&, T, Args...>
template<typename C, typename Fn, typename... Args> // specialisation for member function with object
requires std::invocable<Fn&&, C, T, Args...>
[[maybe_unused]] constexpr auto for_each(Fn&& func, C *obj, Args&&... args);

template<typename Fn, typename... Args>
requires std::invocable<Fn&&, T, Args...>
[[maybe_unused]] constexpr auto for_each_n(int n, Fn&& func, Args&&... args);

template<typename C, typename Fn, typename... Args> // specialisation for member function with object
requires std::invocable<Fn&&, C, T, Args...>
[[maybe_unused]] constexpr auto for_each_n(int n, Fn&& func, C *obj, Args&&... args);
```
Call supplied invocable for _each bit that is on_. Similar to `std::for_each` except first parameter of your invocable must accept an enum value (passed by `for_each`).
Optionally provide any additional parameters. Works with lambdas, member functions, functions etc. The second version is intended to be used
Optionally provide any additional parameters. Works with lambdas, member functions, functions etc. You can limit the number of calls to your
invokable by using the `for_each_n` version with the first parameter being the maximum number to call. The second version of `for_each` and `for_each_n` is intended to be used
when using a member function - the _second_ parameter passed by your call must be the `this` pointer of the object.
If you wish to pass a `reference` parameter, you must wrap it in `std::ref`.

Expand Down Expand Up @@ -927,10 +966,20 @@ numbers::two
numbers::five
numbers::nine
```
Above example using `for_each_n`, limiting to 3:
```c++
ec.for_each_n(3, &foo::printer, &bar, std::ref(std::cout));
```
_output_
```CSV
numbers::zero
numbers::two
numbers::five
```

---
# 5. API and Examples using `conjure_type`
`conjure_type` is a general purpose class allowing you to extract a string representation of any type.
`conjure_type` is a general purpose class allowing you to extract a string representation of any typename.
The string will be stored statically by the compiler, so you can use the statically generated value `name` to obtain your type.
```c++
template<typename T>
Expand Down Expand Up @@ -1119,6 +1168,10 @@ static const char *conjure_type<TEST::TEST1::NineEnums1>::tpeek() [T = TEST::TES
$
```

## e) Contributing
Contributions are welcome. Make your changes in [your fork on the dev branch](https://github.com/fix8mt/conjure_enum/tree/dev) and open a pull request from there. PRs to
master will not be considered.

---
# 7. Notes
## a) enum limits
Expand Down
8 changes: 4 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// by David L. Dight
// see https://github.com/fix8mt/conjure_enum
//
// Lightweight header-only C++20 enum and type reflection
// Lightweight header-only C++20 enum and typename reflection
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
//
Expand All @@ -30,18 +30,18 @@
//---------------------------------------------------------------------------------------->
# Security Policy
Security Policy
This document outlines the security policy for the conjure_enum project. Here, we detail how to report vulnerabilities and how we handle them.
This document outlines the security policy for the `conjure_enum` project. Here, we detail how to report vulnerabilities and how we handle them.

## Reporting a Vulnerability

If you discover a potential security vulnerability in conjure_enum, we encourage you to report it responsibly. Here's how:
If you discover a potential security vulnerability in `conjure_enum`, we encourage you to report it responsibly. Here's how:

- **Privately Contact Us:** Please file a [detailed report](https://github.com/fix8mt/conjure_enum/security/advisories/new).
- **Include Details:** In your email, please provide the following information (if applicable):
- A clear description of the vulnerability.
- Steps to reproduce the vulnerability (if possible).
- The potential impact of the vulnerability.
We appreciate your cooperation in keeping conjure_enum secure. We will work with you confidentially to address the vulnerability as quickly as possible.
We appreciate your cooperation in keeping `conjure_enum` secure. We will work with you confidentially to address the vulnerability as quickly as possible.

## Disclosure Process

Expand Down
16 changes: 9 additions & 7 deletions examples/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// by David L. Dight
// see https://github.com/fix8mt/conjure_enum
//
// Lightweight header-only C++20 enum and type reflection
// Lightweight header-only C++20 enum and typename reflection
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
//
Expand Down Expand Up @@ -73,6 +73,7 @@ const std::string demangle() noexcept

int main(void)
{
conjure_enum<component>::for_each_n(3, [](component val, int other) { std::cout << static_cast<int>(val) << ' ' << other << '\n'; }, 200);
int total{};
auto myfunc { conjure_enum<component>::for_each([](component val, int other, int& tot)
{
Expand All @@ -83,13 +84,13 @@ int main(void)
std::cout << total << '\n';

enum_bitset<numbers> eb;
eb.set_all<numbers::zero,numbers::two,numbers::five,numbers::nine>();
eb.set<numbers::zero,numbers::two,numbers::five,numbers::nine>();
std::cout << eb << '\n';
std::cout << std::boolalpha << eb.test_all<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
eb.reset_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 << std::boolalpha << eb.all_of<numbers::zero,numbers::two,numbers::five,numbers::nine>() << '\n';
eb.reset<numbers::five,numbers::two>();
std::cout << std::boolalpha << eb.all_of(0, 2, 5, 9) << '\n';
std::cout << std::boolalpha << eb.any_of(0, 2, 5, 9) << '\n';
std::cout << std::boolalpha << eb.all_of(numbers::zero,numbers::nine) << '\n';
std::cout << eb << '\n';
eb.reset(numbers::nine);
std::cout << eb << '\n';
Expand Down Expand Up @@ -195,6 +196,7 @@ int main(void)
}
};
const foo bar;
conjure_enum<numbers>::for_each_n(3, &foo::printer, &bar, 1000);
ek.for_each(std::bind(&foo::printer, &bar, std::placeholders::_1, 10));
ek.for_each(&foo::printer, &bar, 10);
[[maybe_unused]] enum_bitset<numbers> er("one|three|four|eight"sv, true);
Expand Down
2 changes: 1 addition & 1 deletion examples/srcloctest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// by David L. Dight
// see https://github.com/fix8mt/conjure_enum
//
// Lightweight header-only C++20 enum and type reflection
// Lightweight header-only C++20 enum and typename reflection
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
//
Expand Down
2 changes: 1 addition & 1 deletion examples/statictest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// by David L. Dight
// see https://github.com/fix8mt/conjure_enum
//
// Lightweight header-only C++20 enum and type reflection
// Lightweight header-only C++20 enum and typename reflection
//
// Licensed under the MIT License <http://opensource.org/licenses/MIT>.
//
Expand Down
Loading