Info
-
Did you know about compiler predefined macros assosicated with the compilation date/time?
Example
static_assert(std::string_view{"07:36::22"} == std::string_view{__TIME__}); // will only pass at certin time
static_assert(std::string_view{"Sep 19 2021"} == std::string_view{__DATE__}); // will only pass at certin date
Puzzle
- Can you implement consteval function
year
which will use DATE macro to return current year as integer?
[[nodiscard]] consteval auto year() -> int; // TODO
static_assert(2021 == year());
Solutions
constexpr auto from_chars(const char* first, const char* last, int& value) {
value = 0;
while (first != last) {
value *= 10;
value += *first++ - '0';
}
}
[[nodiscard]] consteval auto year() -> int {
constexpr auto today = __DATE__;
int year{};
from_chars(&today[7], &today[11], year);
return year;
}
template<auto N>
[[nodiscard]] consteval auto stoi(std::string_view str) {
return [&str]<auto... Ns>(std::index_sequence<Ns...>) {
return (((str[Ns] - '0') * std::pow(10, N - Ns - 1)) + ...);
}(std::make_index_sequence<N>{});
}
[[nodiscard]] consteval auto year() -> int {
return stoi<4>(std::string_view{__DATE__}.substr(7));
}
struct integer
{
static constexpr auto rule = lexy::dsl::integer<int>(lexy::dsl::digits<>);
static constexpr auto value = lexy::forward<int>;
};
[[nodiscard]] consteval auto year() -> int {
constexpr auto date = std::string_view{__DATE__};
constexpr auto input = lexy::string_input(date.substr(7));
constexpr auto result = lexy::parse<integer>(input, lexy::noop);
static_assert(result);
return result.value();
}
constexpr int char_to_digit(char x){
return x-'0';
};
consteval auto year_string() {
const auto date = std::string_view{__DATE__};
return date.substr(date.size() - 4);
};
constexpr int stringview_to_int(auto str, int index, int accum){
return index == 4
? accum
: stringview_to_int(str, index+1, accum*10 + char_to_digit(str[index]));
}
consteval auto year() {
return stringview_to_int(year_string(), 0, 0 );
};
constexpr int
ipow10(int b){ return b ? (10*ipow10(b-1)) : 1; }
constexpr int char_to_digit(char x){ return x-'0'; };
consteval auto year_string() {
const auto date = std::string_view{__DATE__};
return date.substr(date.size() - 4);
};
template<auto ... indices>
constexpr int
stringview_to_int(std::index_sequence< indices ...>, auto str){
return ((char_to_digit(str[indices])*ipow10(3-indices)) + ...);
}
consteval auto year() {
return stringview_to_int(std::make_index_sequence<4>(), year_string());
};
[[nodiscard]] consteval auto year() -> int {
int yr = 0;
for(int i=7; i<11; i++)
yr = 10*yr + __DATE__[i] - '0';
return yr;
}
[[nodiscard]] consteval auto year() -> int
{
auto dateStr = std::string_view{__DATE__};
int y = 0;
for ( int i = dateStr.size() - 1, j = 1; j <= 1000 ; i--, j*=10)
y += int(dateStr[i] - '0') * j ;
return y;
}
template<class T>
consteval auto strparse( T arg) -> int
{
return (arg[0]- '0') *1000 + (arg[1] - '0') * 100 + (arg[2] - '0') * 10 + (arg[3] - '0');
}
[[nodiscard]] consteval auto year() -> int
{
constexpr auto date = std::string_view(__DATE__);
constexpr auto year = std::string_view(date.data() + 7);
return strparse(year);
}
[[nodiscard]] consteval auto year() -> int {
return [] (auto acc, auto size, auto... is) {
return (..., (acc *= 10, acc += __DATE__[size - is] - '0'));
}(0, sizeof __DATE__, 5, 4, 3, 2);
}