#include <iostream>
#include <optional>
#include <string>
#include <sstream>
template <typename T>
std::string format_range(const std::optional<T>& start,
const std::optional<T>& end)
{
std::stringstream ss;
if (start) {
if (end) {
ss << "from " << *start << " to " << *end;
} else {
ss << "since " << *start;
}
} else if (end) {
ss << "until " << *end;
}
return ss.str();
}
template <typename T>
void invoke_format_range(const T& start, const T& end)
{
using namespace std;
optional<T> NONE;
cout << format_range<T>(NONE, NONE) << endl;
cout << format_range<T>(start, NONE) << endl;
cout << format_range<T>(NONE, end) << endl;
cout << format_range<T>(start, end) << endl;
}
int main()
{
invoke_format_range(std::string("START"), std::string("END"));
invoke_format_range(1, 12);
return 0;
}