Last active
April 5, 2018 17:02
-
-
Save elbeno/4ba204a9e93923fc426907c2d36cb53b to your computer and use it in GitHub Desktop.
Setting required fields & optional fields in a type safe way
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <vector> | |
template <uint32_t N> | |
struct request; | |
template <> | |
struct request<0> | |
{ | |
constexpr static uint32_t OPT_FIELDS = 1 << 0; | |
constexpr static uint32_t REQ_FIELD1 = 1 << 1; | |
constexpr static uint32_t REQ_FIELD2 = 1 << 2; | |
constexpr static uint32_t ALL_FIELDS = OPT_FIELDS | REQ_FIELD1 | REQ_FIELD2; | |
std::string required1; | |
std::string required2; | |
std::vector<std::string> optionals; | |
}; | |
template <uint32_t N> | |
struct request : request<N-1> | |
{ | |
using request<0>::REQ_FIELD1; | |
using request<0>::REQ_FIELD2; | |
request<N & ~REQ_FIELD1>& set_required_field1(const std::string& s) | |
{ | |
this->required1 = s; | |
return *this; | |
} | |
request<N & ~REQ_FIELD2>& set_required_field2(const std::string& s) | |
{ | |
this->required2 = s; | |
return *this; | |
} | |
request& set_optional_field(const std::string& s) | |
{ | |
this->optionals.push_back(s); | |
return *this; | |
} | |
}; | |
auto make_request() | |
{ | |
return request<request<0>::ALL_FIELDS>{}; | |
} | |
template <uint32_t N> | |
auto send_request(const request<N>& req) = delete; | |
auto send_request(const request<request<0>::OPT_FIELDS>& req) | |
{ | |
std::cout << "Send request: " | |
<< "req1 = " << req.required1 | |
<< ", req2 = " << req.required2 | |
<< ", opts = ["; | |
for (const auto& o : req.optionals) | |
std::cout << o << ','; | |
std::cout << "]\n"; | |
} | |
int main() | |
{ | |
auto req = make_request() | |
.set_required_field1("foo") | |
.set_required_field2("bar") | |
.set_optional_field("baz") | |
.set_optional_field("quux") | |
.set_optional_field("wibble") | |
; | |
send_request(req); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment