Skip to content

Yaraslaut/form

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

form

Collection of static reflection usage examples

Collection utilize existing c++26 reflection support from clang-p2996

To test it you can use provided Dockerfile to get compiler and build project

docker build . --progress=plain

Enum to string

Transform enum directly to std::string

enum class Color { red, green, blue };

void EnumToString() { 
  std::println("{}", form::enum_to_string(Color::red));  // red
}

Use lambda to format enum values following your pattern.

void EnumToString() { 
  auto transform = [](std::string data) {
    std::string out;
    out += std::tolower(data[0]);
    for (auto const c : data.substr(1, data.size())) {
      if (std::isupper(c))
        out += "-";
      out += std::tolower(c);
    }
    return out;
  };
  form::enum_to_string(Decorator::Underline, transform) //  underline
  form::enum_to_string(Decorator::DottedUnderline, transform) // dotted-underline
}

String to enum

Transform string directly to enum

enum class Color { red, green, blue };

void EnumToString() {
  auto color = form::string_to_enum<Color>("red").value();
}

Padding check at compile time

Calculate padding at compile time and enforce zero padding via concepts

struct struct_with_padding {
  char a;
  double c;
};

struct struct_no_padding {
  double c;
  char a;
};

template <form::no_padding T> void foo(T t) { 
  std::println("Without padding"); 
}

template <typename T> void foo(T t) {
  std::println("With padding: {}", form::get_padding<T>());
}


void PaddingCheck() {
  foo(struct_with_padding{}); // With padding: 7
  foo(struct_no_padding{});   // Without padding
  static_assert(form::no_padding<struct_no_padding>);
}

Create variant of all types inside the namespace

namespace list {
struct CancelSelection {};
struct ClearHistoryAndReset {};
} // namespace list
using list_variant = [:form::create_variant(^list):];

Variant type to string

void VariantToString() {
  list_variant v{list::CancelSelection{}};
  std::println("{}", form::variant_type_to_string(v)); // CancelSelection
}

Run all function from namespace in parallel

Example usage of similar technique for running tests

namespace for_tests {
bool test_true() { return true; }
bool test_false() { return false; }
void test_void() {};
} // namespace for_tests

void runTests() { form::util::detail::run_tests<^^for_tests>(); }

/*
 🔥 test_true
 💩 test_false
 🍀 test_void
*/

same_as concept for templates

concept form::same_as checks if type represent specific template

template <typename T> int foo(T) { return -1; }

template <typename T>
  requires form::same_as<T, ^std::complex>
int foo(T) {
  return 1;
}

foo(std::complex<float>{1.0f,1.0f}); //1

funny invoke

P3096

Invoke of the function with auto construction of the arguments

template<auto F>
auto invoke() {
    static constexpr auto params = std::define_static_array(parameters_of(F));
    typename [:return_type_of(F):] result;
    [&result]<size_t...I>(std::index_sequence<I...>) {
        result = [:F:](
            [] consteval {
                constexpr auto type_reflection = std::meta::remove_cvref(std::meta::type_of(params[I]));
                if constexpr (std::meta::is_convertible_type(type_reflection, ^^std::string_view))
                    return identifier_of(params[I]); 
                else
                    return typename [:type_reflection:]{};
            }()...
        );
    }(std::make_index_sequence<params.size()>{});
    return result;
}


std::string foo(std::string_view a, std::string_view b) {
    return std::format("{} {}", a, b);
}

int bar(int a, std::string_view b) {
    return a + b.size();
}

int main() {
    std::println("{}",invoke<^^foo>());
    std::println("{}",invoke<^^bar>());
}

Reflecting JSON

Post

About

Static reflection collection

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published