Skip to content

Instantly share code, notes, and snippets.

@rhom6us
Created May 25, 2024 04:20
Show Gist options
  • Save rhom6us/48f78b42a4bf441fe7bc04903f8db4e0 to your computer and use it in GitHub Desktop.
Save rhom6us/48f78b42a4bf441fe7bc04903f8db4e0 to your computer and use it in GitHub Desktop.
c++ string template parameters
#include <iostream>
#include <utility>
using namespace std;
enum class request_type {
GET,
POST,
PUT,
DELETE,
OPTIONS,
};
template<class T, class U>
[[nodiscard]] constexpr auto&& forward_like(U&& x) noexcept {
constexpr bool is_adding_const = std::is_const_v<std::remove_reference_t<T>>;
if constexpr (std::is_lvalue_reference_v<T&&>) {
if constexpr (is_adding_const)
return std::as_const(x);
else
return static_cast<U&>(x);
} else { // is rvalue
if constexpr (is_adding_const)
return std::move(std::as_const(x));
else
return std::move(x);
}
}
template<class To, class From>
[[nodiscard]] auto&& unholy_cast(From&& from) {
return forward_like<From>(*reinterpret_cast<To*>(&from));
}
template<class T= struct DEFAULT>
struct Request {};
template<const char* path, request_type type, class Data>
struct Handler {
virtual void handle(Request<Data> d) = 0;
};
namespace paths {
constexpr const char home[] = "/home";
namespace users {
const char index[] = "/users";
const char get[] = "/users/{id}";
}
}
struct Huh: Handler<paths::home, request_type::GET, class GET_HOME_TAG>, Handler<paths::users::get, request_type::POST, class POST_USERS_TAG> {
void handle(Request<class GET_HOME_TAG> a) override {
cout << "a" << endl;
}
void handle(Request<class POST_USERS_TAG> b) override {
cout << "b" << endl;
}
};
template<const char* S>
struct foo {
const char* get() {
return S;
}
};
constexpr const char s1[] = "asdf";
int main() {
foo<s1> f;
foo<paths::home> fh;
Huh h;
Request r;
auto& rr = unholy_cast<Request<POST_USERS_TAG>>(r);
h.handle(rr);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment