added \*frob

master
Avril 4 years ago
parent 40be7c9859
commit 4199c0b3de
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,27 +1,115 @@
#pragma once
#include <string>
#include <vector>
namespace frob
{
using u8 = unsigned char;
constexpr u8 rot13(u8 i)
constexpr static const u8 ROT13_CONSTANT =
#ifdef FROB_CONSTANT
(u8)(FROB_CONSTANT)
#else
(u8)42;
#endif
constexpr inline u8 rot13(u8 i)
{
return i ^ (u8)42;
return i ^ ROT13_CONSTANT;
}
template<std::size_t N>
template<std::size_t N, typename CHAR=char>
requires(N > 0)
struct cfrob
{
char out[N]{};
constexpr cfrob(const char (&sz)[N])
CHAR out[N]{};
inline constexpr operator const char*() const { return out; }
inline operator char*() { return out; }
constexpr cfrob(const CHAR (&sz)[N])
{
for(std::size_t i=0;i<N-1;i++)
out[i] = rot13((u8)sz[i]);
out[N-1] = 0;
}
};
// frobnicate functions
template<std::size_t N>
constexpr auto memfrob(const u8 (&sz)[N])
{
return cfrob(sz);
}
template<std::size_t N>
inline auto memfrob(u8 (&sz)[N])
{
for(std::size_t i=0;i<N;i++)
sz[i] = rot13(sz[i]);
return sz;
}
template<typename P = void>
inline P* memfrob(u8* ptr, std::size_t len)
{
for(auto i=0;i<len;i++)
ptr[i] = rot13(ptr[i]);
return (P*)ptr;
}
inline std::vector<u8> memfrob(const u8* ptr, std::size_t len)
{
std::vector<u8> out;
out.reserve(len);
for(std::size_t i=0;i<len;i++)
out.push_back(rot13(ptr[i]));
return out;
}
inline std::vector<u8>& memfrob(std::vector<u8>* _s)
{
std::vector<u8>& s = *_s;
for(auto& b : s) b = rot13(b);
return s;
}
inline std::vector<u8> memfrob(const std::vector<u8>& s)
{
std::vector<u8> out = s;
memfrob(out);
return out;
}
template<std::size_t N>
constexpr inline auto strfrob(const char (&sz)[N])
{
return cfrob(sz);
}
inline std::string strfrob(const std::string& s)
{
std::string out;
out.reserve(s.size());
for(const char& c : s)
out+= rot13((u8)c);
return out;
}
inline std::string& strfrob(std::string* sp)
{
std::string& s = *sp;
for(char& c : s)
c = rot13((u8)c);
return s;
}
inline std::string strfrob(const char* str)
{
return strfrob(std::string(str));
}
inline char* strfrob(char* str)
{
for(;*str;str++)
*str = rot13((u8)*str);
return str;
}
}
template<frob::cfrob C>
constexpr auto operator "" _frob()
{

@ -10,14 +10,37 @@ constexpr const char* str2 = "Hello world."_frob;
// Can also be stored as normal `const char*` string constant pointer.
const char* str3 = "Hello world."_frob;
void assert_streq(const char* str, const char* str2)
{
if (strcmp(str,str2)!=0)
{
std::cerr << "Mismatch: '" << str << "' is not eq to '" << str2 << "'" << std::endl;
std::terminate();
}
}
#define ASSERT_STREQ(ty, expr, get) do { ty _str = expr; assert_streq(_str get, str2); } while(0)
int main()
{
char* str2 = strdup(str);
memfrob(str2, strlen(str));
std::cout << str << std::endl;
std::cout << str2 << std::endl;
free(str2);
std::cout << str2 << std::endl;
// test of frob::*frob()
{
ASSERT_STREQ(const auto, frob::strfrob(str), .c_str());
std::string frobbed = frob::strfrob((const char*)str2);
constexpr const auto out = frob::strfrob<>("Hello world."); //for some reason it doesn't prefer the `constexpr` template overload, even in a constexpr context?
auto out2 = frob::strfrob(out);
std::cout << frobbed << std::endl;
std::cout << out << std::endl;
std::cout << out2 << std::endl;
}
free(str2);
return 0;
}

Loading…
Cancel
Save