Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

LOAD "LINUX",8,1 -- Topic on #LinuxGER


devel / comp.lang.c++ / How to make a function `constexpr` in a REASONABLE way

SubjectAuthor
o How to make a function `constexpr` in a REASONABLE wayAlf P. Steinbach

1
How to make a function `constexpr` in a REASONABLE way

<u6i6ml$sv7l$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=434&group=comp.lang.c%2B%2B#434

  copy link   Newsgroups: comp.lang.c++
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: alf.p.steinbach@gmail.com (Alf P. Steinbach)
Newsgroups: comp.lang.c++
Subject: How to make a function `constexpr` in a REASONABLE way
Date: Fri, 16 Jun 2023 19:38:27 +0200
Organization: A noiseless patient Spider
Lines: 173
Message-ID: <u6i6ml$sv7l$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Fri, 16 Jun 2023 17:38:29 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="41fde8fe75c13341b4da7e47a75482a0";
logging-data="949493"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+uR6gUbsiShLsX66L5lGLl"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.12.0
Cancel-Lock: sha1:4RDVKujNk8cgmMDHy8a1JdbJ0Ak=
Content-Language: en-US
 by: Alf P. Steinbach - Fri, 16 Jun 2023 17:38 UTC

This is some conceptually very simple code, namely a `constexpr`
constant `os` that provides an id number for the OS (windows, unix, ...,
I guess android will also make its way into the list),

a ditto `constexpr` function `name_of` that can convert such id to
string, and

a currently not `constexpr` function `os_is` that tells whether the `os`
is in a specified category, e.g. `os_is( Os_id::windows )` will be true
when the OS is either `win32` or `win64`.

I can see how I can manually check nearly every case and that way make
`os_is` a `constexpr` function.

But I'd like some general reasonable mechanism or code. Just because I'm
slightly annoyed that I didn't see such a way. But other eyes might?

using fsm::ref_, fsm::array_of_, // ref_<T> = T&
fsm::int_size_of;
using std::string_view;

#define FSMi_OS_ID_NAMES \
any, \
windows, win32, win64, unix, linux, mac_os, ios,
ios_in_simulator, ios_on_device, unknown

struct Os_id{ enum Enum: int { FSMi_OS_ID_NAMES, _ }; };
constexpr int n_os_ids = Os_id::_;

struct Os_names
{
static constexpr auto s = string_view( FSM_AS_STRING_LITERAL(
FSMi_OS_ID_NAMES ) "," );
array_of_<n_os_ids, string_view> m_strings;

constexpr Os_names()
{
bool in_space = true;
int id = 0;
const char* p_start = nullptr; // Must be
initialized in a `constexpr` function.

for( const char& ch: s ) {
if( ch == ',' or ch == ' ' or ch == '\n' ) {
in_space = true;
if( p_start ) {
const auto length = int( &ch - p_start );
m_strings[id] = string_view( p_start, length );
++id;
p_start = nullptr;
}
} else if( in_space ) {
p_start = &ch;
in_space = false;
}
}
}
};

inline constexpr Os_names os_names{};

constexpr auto name_of( const Os_id::Enum id )
-> string_view
{
// return "Zalo";
return (id < int_size_of( os_names.m_strings )
? os_names.m_strings[id]
: "<invalid os id value>"
);
}

template< Os_id::Enum an_id, class... Sub_types >
struct Os_{ static constexpr Os_id::Enum id = an_id; };

using Id = Os_id;
using Os_categories =
Os_< Id::any,
Os_< Id::windows,
Os_< Id::win32 >,
Os_< Id::win64 >
>,
Os_< Id::unix,
Os_< Id::linux >,
Os_< Id::mac_os >,
Os_< Id::ios,
Os_< Id::ios_in_simulator >,
Os_< Id::ios_on_device >
>
>,
Os_< Id::unknown >
>;

using Parent_id_array = array_of_<n_os_ids, Os_id::Enum>;

template< Os_id::Enum category, class... Sub_types >
inline void populate(
ref_<Parent_id_array> parent_id_array,
const Os_id::Enum parent_id,
Os_<category, Sub_types...> os
)
{
parent_id_array[os.id] = parent_id;
(populate( parent_id_array, os.id, Sub_types() ), ...);
}

inline auto parent_ids()
-> ref_<const array_of_<n_os_ids, Os_id::Enum>>
{
struct Parent_ids
{
Parent_id_array m_ids = {};
Parent_ids() { populate( m_ids, Os_id::any, Os_categories()
); }
};

static const Parent_ids the_parent_ids = {};
return the_parent_ids.m_ids;
};

// constexpr Os_id::Enum os = DETECTED_OS_ID;
#ifndef FSMi_TEST_OS_ID
constexpr
#endif
Os_id::Enum os = Os_id::
#if defined( FSM_OS_IS_WINDOWS )
#if defined( FSM_OS_IS_WIN32 ) // Note: is not defined for
64-bit Windows (unlike `_WIN32`).
win32
#elif defined( FSM_OS_IS_WIN64 )
win64
#else
windows
#endif
#elif defined( FSM_OS_IS_UNIX )
#if defined( FSM_OS_IS_LINUX )
linux
#elif defined( FSM_OS_IS_IOS )
#if defined( FSM_OS_IS_IOS_IN_SIMULATOR )
ios_in_simulator
#elif defined( FSM_OS_IS_IOS_ON_DEVICE )
ios_on_device
#else
ios
#endif
#elif defined( FSM_OS_IS_MAC_OS )
mac_os
#else
unix
#endif
#else
unknown
#endif
;

inline auto os_is( const Os_id::Enum a_category )
-> bool
{
Os_id::Enum category = os;
for( ;; ) {
if( a_category == category ) {
return true;
}
if( category == Os_id::any ) {
return false;
}
category = parent_ids()[category];
}
for( ;; ) {} // Should never get here.
}

- Alf

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor