Page MenuHomePhorge

atom.hpp
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

atom.hpp

/***************************************************************************//**
*
* \file rosa/support/atom.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Facility for `atom`s, short strings statically encoded as integers.
*
* \note This implementation is based on the `atom` implementation of CAF.
* \todo Check license.
*
* `Atom`s can be used to turn short string literals into statically generated
* types. The literals may consist of at most `10` non-special characters, legal
* characters are `_0-9A-Za-z` and the whitespace character. Special characters
* are turned into whitespace, which may result in different string literals
* being encoded into the same integer value, if any of those contain at least
* one special character.
*
* \note The usage of special characters in the string literals used to create
* `atoms` cannot be checked by the compiler.
*
* Example:
*
* \code
* constexpr AtomValue NameValue = atom("name");
* using NameAtom = AtomConstant<NameValue>;
*
* [](NameAtom){ std::cout << "Argument of type NameAtom"; }(NameAtom::Value)
* \endcode
*
******************************************************************************/
#ifndef ROSA_SUPPORT_ATOM_HPP
#define ROSA_SUPPORT_ATOM_HPP
#include "rosa/support/debug.hpp"
namespace rosa {
/// Maximal length of valid atom strings.
constexpr size_t MaxAtomLength = 10;
/// Underlying integer type of atom values.
using atom_t = uint64_t;
/// Turn `rosa::atom_t` into a strongly typed enumeration.
///
/// Values of `rosa::atom_t` casted to `rosa::AtomValue` may be used in a
/// type-safe way.
enum class AtomValue : atom_t {};
/// Anonymous namespace with implementational details, consider it private.
namespace {
/// Encodes ASCII characters to 6-bit encoding.
constexpr unsigned char AtomEncodingTable[] = {
/* ..0 ..1 ..2 ..3 ..4 ..5 ..6 ..7 ..8 ..9 ..A ..B ..C ..D ..E ..F */
/* 0.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 1.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 2.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 3.. */ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0,
/* 4.. */ 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
/* 5.. */ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 0, 0, 37,
/* 6.. */ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
/* 7.. */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0};
/// Decodes 6-bit characters to ASCII
constexpr char AtomDecodingTable[] = " 0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ_"
"abcdefghijklmnopqrstuvwxyz";
/// Encodes one character and updates the integer representation.
///
/// \param Current an encoded value
/// \param CharCode a character to add to `Current`
///
/// \return `Current` updated with `CharCode`
constexpr atom_t nextInterim(atom_t Current, size_t CharCode) {
return (Current << 6) | AtomEncodingTable[(CharCode <= 0x7F) ? CharCode : 0];
}
/// Encodes a C-string into an integer value to be used as `rosa::AtomValue`.
///
/// \param CStr a string to encode
/// \param Interim encoded value to add `CStr` to it
///
/// \return `Interim` updated with `CStr`
constexpr atom_t atomValue(const char *CStr, atom_t Interim = 0xF) {
return (*CStr == '\0')
? Interim
: atomValue(CStr + 1,
nextInterim(Interim, static_cast<size_t>(*CStr)));
}
} // End namespace
/// Converts a `rosa::AtomValue` into `std::string`.
///
/// \param What value to convert
///
/// \return the `string` encoded in `What`
std::string to_string(const AtomValue &What);
/// Converts a `std::string` into a `rosa::AtomValue`.
///
/// \param S the `string` to convert
///
/// \return `AtomValue` representation of `S`
AtomValue atom_from_string(const std::string &S);
/// Converts a string-literal into a `rosa::AtomValue`.
///
/// \tparam Size the length of `Str`
///
/// \param Str the string-literal to convert
///
/// \return `AtomValue` representation of `Str`
///
/// \pre `Str` is not too long:\code
/// Size <= MaxAtomLength + 1
/// \endcode
template <size_t Size>
constexpr AtomValue atom(char const (&Str)[Size]) {
// Last character is the NULL terminator.
STATIC_ASSERT(Size <= MaxAtomLength + 1,
"Too many characters in atom definition");
return static_cast<AtomValue>(atomValue(Str));
}
/// Lifts a `rosa::AtomValue` to a compile-time constant.
///
/// \tparam V the `AtomValue` to lift
template <AtomValue V>
struct AtomConstant {
/// Ctor, has to do nothing.
constexpr AtomConstant(void) {}
/// Returns the wrapped value.
///
/// \return `V`
constexpr operator AtomValue(void) const { return V; }
/// Returns the wrapped value as of type `rosa::atom_t`.
///
/// \return `atom_t` value from `V`
static constexpr atom_t value() { return static_cast<atom_t>(V); }
/// An instance *of this constant* (*not* an `rosa::AtomValue`).
static const AtomConstant Value;
};
// Implementation of the static member field `Value` of `rosa::AtomConstant`.
template <AtomValue V>
const AtomConstant<V> AtomConstant<V>::Value = AtomConstant<V>{};
/// Converts a `rosa::AtomConstant` into `std::string`.
///
/// \tparam V `AtomValue` to convert
///
/// \note The actual argument of type `const AtomConstant<V>` is ignored
/// because the `AtomValue` to convert is encoded in the type itself.
///
/// \return the original string encoded in `V`
template <AtomValue V>
std::string to_string(const AtomConstant<V> &) {
return to_string(V);
}
} // End namespace rosa
#endif // ROSA_SUPPORT_ATOM_HPP

File Metadata

Mime Type
text/x-c++
Expires
Fri, Jul 4, 8:36 AM (1 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157563
Default Alt Text
atom.hpp (5 KB)

Event Timeline