Skip to content

Instantly share code, notes, and snippets.

@hasselmm
Created April 25, 2022 13:30
Show Gist options
  • Save hasselmm/15af40abcec65f01b0899fd7eea3827d to your computer and use it in GitHub Desktop.
Save hasselmm/15af40abcec65f01b0899fd7eea3827d to your computer and use it in GitHub Desktop.
User defined literal for IPv4 addresses
#include <stdint.h>
namespace detail {
constexpr uint8_t parse_octet(const char *str, const char *end, const char **out = nullptr)
{
uint8_t octet = 0;
if (str < end) {
if (*str >= '3' && *str <= '9') { // 3-9 | 30-99
octet = static_cast<uint8_t>(*str++ - '0');
if (str < end && *str >= '0' && *str <= '9') { // --- | 30-99
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
}
} else if (*str == '2') { // 2 | 20-29 | 200-255
octet = static_cast<uint8_t>(*str++ - '0');
if (str < end) {
if (*str >= '0' && *str <= '4') { // --- | 20-24 | 200-249
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
if (str < end && *str >= '0' && *str <= '9') { // --- | ----- | 200-249
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
}
} else if (*str == '5') { // --- | 25 | 250-255
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
if (str < end && *str >= '0' && *str <= '5') { // --- | ----- | 250-255
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
}
} else if (*str >= '6' && *str <= '9') { // --- | 26-29 | -------
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
}
}
} else if (*str == '1') { // 1 | 10-19 | 100-199
octet = static_cast<uint8_t>(*str++ - '0');
if (str < end && *str >= '0' && *str <= '9') { // --- | 10-19 | 100-199
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
if (str < end && *str >= '0' && *str <= '9') { // --- | ----- | 100-199
octet *= 10;
octet += static_cast<uint8_t>(*str++ - '0');
}
}
} else if (*str == '0') { // 0 | ----- | -------
octet = static_cast<uint8_t>(*str++ - '0');
}
}
if (out)
*out = str;
return octet;
}
template<size_t N>
constexpr uint8_t parse_octet(const char (& str)[N])
{
return parse_octet(str, str + N - 1);
}
static_assert(parse_octet("0") == 0); static_assert(parse_octet("1") == 1); static_assert(parse_octet("2") == 2);
static_assert(parse_octet("3") == 3); static_assert(parse_octet("4") == 4); static_assert(parse_octet("5") == 5);
static_assert(parse_octet("6") == 6); static_assert(parse_octet("7") == 7); static_assert(parse_octet("8") == 8);
static_assert(parse_octet("9") == 9); static_assert(parse_octet("10") == 10); static_assert(parse_octet("11") == 11);
static_assert(parse_octet("12") == 12); static_assert(parse_octet("13") == 13); static_assert(parse_octet("14") == 14);
static_assert(parse_octet("15") == 15); static_assert(parse_octet("16") == 16); static_assert(parse_octet("17") == 17);
static_assert(parse_octet("18") == 18); static_assert(parse_octet("19") == 19); static_assert(parse_octet("20") == 20);
static_assert(parse_octet("21") == 21); static_assert(parse_octet("22") == 22); static_assert(parse_octet("23") == 23);
static_assert(parse_octet("24") == 24); static_assert(parse_octet("25") == 25); static_assert(parse_octet("26") == 26);
static_assert(parse_octet("27") == 27); static_assert(parse_octet("28") == 28); static_assert(parse_octet("29") == 29);
static_assert(parse_octet("30") == 30); static_assert(parse_octet("31") == 31); static_assert(parse_octet("32") == 32);
static_assert(parse_octet("33") == 33); static_assert(parse_octet("34") == 34); static_assert(parse_octet("35") == 35);
static_assert(parse_octet("36") == 36); static_assert(parse_octet("37") == 37); static_assert(parse_octet("38") == 38);
static_assert(parse_octet("39") == 39); static_assert(parse_octet("40") == 40); static_assert(parse_octet("41") == 41);
static_assert(parse_octet("42") == 42); static_assert(parse_octet("43") == 43); static_assert(parse_octet("44") == 44);
static_assert(parse_octet("45") == 45); static_assert(parse_octet("46") == 46); static_assert(parse_octet("47") == 47);
static_assert(parse_octet("48") == 48); static_assert(parse_octet("49") == 49); static_assert(parse_octet("50") == 50);
static_assert(parse_octet("51") == 51); static_assert(parse_octet("52") == 52); static_assert(parse_octet("53") == 53);
static_assert(parse_octet("54") == 54); static_assert(parse_octet("55") == 55); static_assert(parse_octet("56") == 56);
static_assert(parse_octet("57") == 57); static_assert(parse_octet("58") == 58); static_assert(parse_octet("59") == 59);
static_assert(parse_octet("60") == 60); static_assert(parse_octet("61") == 61); static_assert(parse_octet("62") == 62);
static_assert(parse_octet("63") == 63); static_assert(parse_octet("64") == 64); static_assert(parse_octet("65") == 65);
static_assert(parse_octet("66") == 66); static_assert(parse_octet("67") == 67); static_assert(parse_octet("68") == 68);
static_assert(parse_octet("69") == 69); static_assert(parse_octet("70") == 70); static_assert(parse_octet("71") == 71);
static_assert(parse_octet("72") == 72); static_assert(parse_octet("73") == 73); static_assert(parse_octet("74") == 74);
static_assert(parse_octet("75") == 75); static_assert(parse_octet("76") == 76); static_assert(parse_octet("77") == 77);
static_assert(parse_octet("78") == 78); static_assert(parse_octet("79") == 79); static_assert(parse_octet("80") == 80);
static_assert(parse_octet("81") == 81); static_assert(parse_octet("82") == 82); static_assert(parse_octet("83") == 83);
static_assert(parse_octet("84") == 84); static_assert(parse_octet("85") == 85); static_assert(parse_octet("86") == 86);
static_assert(parse_octet("87") == 87); static_assert(parse_octet("88") == 88); static_assert(parse_octet("89") == 89);
static_assert(parse_octet("90") == 90); static_assert(parse_octet("91") == 91); static_assert(parse_octet("92") == 92);
static_assert(parse_octet("93") == 93); static_assert(parse_octet("94") == 94); static_assert(parse_octet("95") == 95);
static_assert(parse_octet("96") == 96); static_assert(parse_octet("97") == 97); static_assert(parse_octet("98") == 98);
static_assert(parse_octet("99") == 99); static_assert(parse_octet("100") == 100); static_assert(parse_octet("101") == 101);
static_assert(parse_octet("102") == 102); static_assert(parse_octet("103") == 103); static_assert(parse_octet("104") == 104);
static_assert(parse_octet("105") == 105); static_assert(parse_octet("106") == 106); static_assert(parse_octet("107") == 107);
static_assert(parse_octet("108") == 108); static_assert(parse_octet("109") == 109); static_assert(parse_octet("110") == 110);
static_assert(parse_octet("111") == 111); static_assert(parse_octet("112") == 112); static_assert(parse_octet("113") == 113);
static_assert(parse_octet("114") == 114); static_assert(parse_octet("115") == 115); static_assert(parse_octet("116") == 116);
static_assert(parse_octet("117") == 117); static_assert(parse_octet("118") == 118); static_assert(parse_octet("119") == 119);
static_assert(parse_octet("120") == 120); static_assert(parse_octet("121") == 121); static_assert(parse_octet("122") == 122);
static_assert(parse_octet("123") == 123); static_assert(parse_octet("124") == 124); static_assert(parse_octet("125") == 125);
static_assert(parse_octet("126") == 126); static_assert(parse_octet("127") == 127); static_assert(parse_octet("128") == 128);
static_assert(parse_octet("129") == 129); static_assert(parse_octet("130") == 130); static_assert(parse_octet("131") == 131);
static_assert(parse_octet("132") == 132); static_assert(parse_octet("133") == 133); static_assert(parse_octet("134") == 134);
static_assert(parse_octet("135") == 135); static_assert(parse_octet("136") == 136); static_assert(parse_octet("137") == 137);
static_assert(parse_octet("138") == 138); static_assert(parse_octet("139") == 139); static_assert(parse_octet("140") == 140);
static_assert(parse_octet("141") == 141); static_assert(parse_octet("142") == 142); static_assert(parse_octet("143") == 143);
static_assert(parse_octet("144") == 144); static_assert(parse_octet("145") == 145); static_assert(parse_octet("146") == 146);
static_assert(parse_octet("147") == 147); static_assert(parse_octet("148") == 148); static_assert(parse_octet("149") == 149);
static_assert(parse_octet("150") == 150); static_assert(parse_octet("151") == 151); static_assert(parse_octet("152") == 152);
static_assert(parse_octet("153") == 153); static_assert(parse_octet("154") == 154); static_assert(parse_octet("155") == 155);
static_assert(parse_octet("156") == 156); static_assert(parse_octet("157") == 157); static_assert(parse_octet("158") == 158);
static_assert(parse_octet("159") == 159); static_assert(parse_octet("160") == 160); static_assert(parse_octet("161") == 161);
static_assert(parse_octet("162") == 162); static_assert(parse_octet("163") == 163); static_assert(parse_octet("164") == 164);
static_assert(parse_octet("165") == 165); static_assert(parse_octet("166") == 166); static_assert(parse_octet("167") == 167);
static_assert(parse_octet("168") == 168); static_assert(parse_octet("169") == 169); static_assert(parse_octet("170") == 170);
static_assert(parse_octet("171") == 171); static_assert(parse_octet("172") == 172); static_assert(parse_octet("173") == 173);
static_assert(parse_octet("174") == 174); static_assert(parse_octet("175") == 175); static_assert(parse_octet("176") == 176);
static_assert(parse_octet("177") == 177); static_assert(parse_octet("178") == 178); static_assert(parse_octet("179") == 179);
static_assert(parse_octet("180") == 180); static_assert(parse_octet("181") == 181); static_assert(parse_octet("182") == 182);
static_assert(parse_octet("183") == 183); static_assert(parse_octet("184") == 184); static_assert(parse_octet("185") == 185);
static_assert(parse_octet("186") == 186); static_assert(parse_octet("187") == 187); static_assert(parse_octet("188") == 188);
static_assert(parse_octet("189") == 189); static_assert(parse_octet("190") == 190); static_assert(parse_octet("191") == 191);
static_assert(parse_octet("192") == 192); static_assert(parse_octet("193") == 193); static_assert(parse_octet("194") == 194);
static_assert(parse_octet("195") == 195); static_assert(parse_octet("196") == 196); static_assert(parse_octet("197") == 197);
static_assert(parse_octet("198") == 198); static_assert(parse_octet("199") == 199); static_assert(parse_octet("200") == 200);
static_assert(parse_octet("201") == 201); static_assert(parse_octet("202") == 202); static_assert(parse_octet("203") == 203);
static_assert(parse_octet("204") == 204); static_assert(parse_octet("205") == 205); static_assert(parse_octet("206") == 206);
static_assert(parse_octet("207") == 207); static_assert(parse_octet("208") == 208); static_assert(parse_octet("209") == 209);
static_assert(parse_octet("210") == 210); static_assert(parse_octet("211") == 211); static_assert(parse_octet("212") == 212);
static_assert(parse_octet("213") == 213); static_assert(parse_octet("214") == 214); static_assert(parse_octet("215") == 215);
static_assert(parse_octet("216") == 216); static_assert(parse_octet("217") == 217); static_assert(parse_octet("218") == 218);
static_assert(parse_octet("219") == 219); static_assert(parse_octet("220") == 220); static_assert(parse_octet("221") == 221);
static_assert(parse_octet("222") == 222); static_assert(parse_octet("223") == 223); static_assert(parse_octet("224") == 224);
static_assert(parse_octet("225") == 225); static_assert(parse_octet("226") == 226); static_assert(parse_octet("227") == 227);
static_assert(parse_octet("228") == 228); static_assert(parse_octet("229") == 229); static_assert(parse_octet("230") == 230);
static_assert(parse_octet("231") == 231); static_assert(parse_octet("232") == 232); static_assert(parse_octet("233") == 233);
static_assert(parse_octet("234") == 234); static_assert(parse_octet("235") == 235); static_assert(parse_octet("236") == 236);
static_assert(parse_octet("237") == 237); static_assert(parse_octet("238") == 238); static_assert(parse_octet("239") == 239);
static_assert(parse_octet("240") == 240); static_assert(parse_octet("241") == 241); static_assert(parse_octet("242") == 242);
static_assert(parse_octet("243") == 243); static_assert(parse_octet("244") == 244); static_assert(parse_octet("245") == 245);
static_assert(parse_octet("246") == 246); static_assert(parse_octet("247") == 247); static_assert(parse_octet("248") == 248);
static_assert(parse_octet("249") == 249); static_assert(parse_octet("250") == 250); static_assert(parse_octet("251") == 251);
static_assert(parse_octet("252") == 252); static_assert(parse_octet("253") == 253); static_assert(parse_octet("254") == 254);
static_assert(parse_octet("255") == 255);
} // namespace detail
constexpr uint32_t operator""_ipv4(const char *str, size_t len)
{
const auto end = str + len;
auto ipv4 = uint32_t{};
for (int i = 0; i < 3; ++i) {
ipv4 |= detail::parse_octet(str, end, &str);
ipv4 <<= 8;
if (str >= end || *str++ != '.')
return 0;
}
ipv4 |= detail::parse_octet(str, end, &str);
if (str != end)
return 0;
return ipv4;
}
static_assert("127.0.0.1"_ipv4 == 0x7f'00'00'01);
static_assert("192.168.0.15"_ipv4 == 0xC0'A8'00'0f);
static_assert("192.168.0.20"_ipv4 == 0xC0'A8'00'14);
static_assert("192.168.0.31"_ipv4 == 0xC0'A8'00'1f);
static_assert("192.168.0.255"_ipv4 == 0xC0'A8'00'ff);
static_assert("192.168.0.111"_ipv4 == 0xC0'A8'00'6f);
static_assert("192_168_0_111"_ipv4 == 0);
static_assert("192.168.0.111.1"_ipv4 == 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment