repr
0.1
Reconstructable string representations and more
Toggle main menu visibility
Main Page
Installation
Usage
Customization
Extending
FAQ
CI Results
Test
Benchmark
API Documentation
Namespace List
Namespace List
Namespace Members
All
_
a
c
d
e
f
g
i
l
m
n
o
p
r
s
t
u
v
w
Functions
_
a
c
d
e
f
g
i
l
m
n
o
r
s
t
u
v
w
Variables
Typedefs
Enumerations
Concept List
Class List
Class List
Class Index
Class Hierarchy
Class Members
All
_
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
~
Functions
_
a
c
e
f
g
i
l
m
n
o
p
r
s
t
v
w
~
Variables
a
b
c
d
e
f
g
i
k
l
m
n
o
p
q
r
s
t
u
v
Typedefs
a
c
d
e
f
g
h
l
m
p
r
s
t
u
v
w
Enumerations
Enumerator
Related Symbols
File List
File List
File Members
All
_
l
n
o
r
u
Variables
Macros
_
l
o
r
u
Examples
Source Code
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
Concepts
Loading...
Searching...
No Matches
accessor.h
Go to the documentation of this file.
#pragma once
#include <
array
>
#include <
bit
>
#include <
cstddef
>
#include <
iterator
>
#include <
string_view
>
#include <
type_traits
>
#include <
librepr/util/collections/list.h
>
#include "
util.h
"
namespace
librepr::ctei
{
template
<
typename
T, EnumKind Kind,
typename
Structure = TypeList<>>
requires
std::is_enum_v<T>
struct
Accessor
{
using
structure
=
Structure
;
using
underlying
=
std::underlying_type_t<T>
;
constexpr
static
auto
kind
=
Kind
;
private
:
static
constexpr
auto
get_enum_names() {
if
constexpr
(structure::size == 0) {
return
std::array<std::string_view, 0>
{};
}
else
{
auto
constexpr
full_size = structure::invoke([]<
typename
...
Range
>() {
return
((
Range::size
) + ...); });
auto
buffer =
std::array<std::string_view, full_size>
{};
structure::for_each(
[
offset
= 0
U
]<
typename
Range
>(
auto
& output)
mutable
{
constexpr
auto
range_names
= Range::template
enum_names<T, Kind>
;
// populate array in reverse
offset
+=
Range::size
;
std::copy
(
std::begin
(
range_names
),
std::end
(
range_names
),
std::next
(
std::begin
(output), full_size -
offset
));
},
buffer);
return
buffer;
}
}
public
:
constexpr
static
auto
names
= get_enum_names();
//TODO enum_values?
template
<std::
size_t
Idx = 0>
constexpr
static
std::string_view
search_name
(
underlying
value)
requires
(
Kind
==
EnumKind::Linear
)
{
using
range
=
typename
structure::template
get<Idx>
;
if
(range::contains(value)) {
auto
offset
= value - range::min;
// TODO assert offset is >= 0
return
range::template
enum_names<T, Kind>
[
std::size_t
(
offset
)];
}
if
constexpr
(
Idx
+ 1 < structure::size) {
// we haven't yet found, advance to next range
// TODO could do binary search instead
return
search_name<Idx + 1>
(value);
}
else
{
return
{};
}
}
constexpr
static
std::string_view
search_name
(
underlying
value) {
…
}
static
std::string_view
search_name
(
underlying
value)
requires
(
Kind
==
EnumKind::Flags
)
{
static_assert
(structure::size == 1,
"Flag-like enum structure should only consist of one contiguous subrange"
);
using
range
=
typename
structure::template
get<0>
;
if
(value == 0) {
// special case 0
return
names
[0];
}
if
(!
std::has_single_bit
(value)) {
// more than one flag
return
{};
}
auto
width =
std::bit_width
(value);
if
(width > range::max) {
// value too large
return
{};
}
auto
offset
=
std::countr_zero
(value) + 1;
// TODO assert offset is >= 0
return
names
[
std::size_t
(
offset
)];
}
static
std::string_view
search_name
(
underlying
value) {
…
}
static
std::string_view
search_name
(
underlying
/*value*/
)
requires
(
Kind
==
EnumKind::Empty
)
{
return
{};
}
static
std::string_view
search_name
(
underlying
/*value*/
) {
…
}
constexpr
static
std::string_view
get_name
(T value) {
auto
underlying
=
static_cast<
std::underlying_type_t<T>
>
(value);
return
search_name
(
underlying
);
}
constexpr
static
std::string_view
get_name
(T value) {
…
}
constexpr
static
auto
get_names
() {
return
names
; }
constexpr
static
auto
get_names
()
requires
(
Kind
==
EnumKind::Flags
)
{
constexpr
auto
valid_count
=
std::count_if
(
std::begin
(
names
),
std::end
(
names
), [](
std::string_view
element
) {
return
!
element
.empty(); });
auto
buffer =
std::array<std::string_view, valid_count>
{};
auto
idx
= 0
U
;
for
(
auto
&&
element
:
names
) {
if
(
element
.empty()) {
continue
;
}
buffer[
idx
++] =
element
;
}
return
buffer;
}
constexpr
static
auto
get_names
() {
…
}
};
struct
Accessor
{
…
};
}
// namespace librepr::ctei
namespace
librepr::ctei
{
…
}
include
librepr
enum
accessor.h
Generated by
1.9.8, using the excellent
Doxygen Awesome
Theme