From 4199c0b3dee58a21093da870f84ba261108f7eb2 Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 3 Dec 2020 19:26:55 +0000 Subject: [PATCH] added \*frob --- cfrob.hpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++--- test/test.cpp | 27 ++++++++++++-- 2 files changed, 118 insertions(+), 7 deletions(-) diff --git a/cfrob.hpp b/cfrob.hpp index 2ef6c18..021db32 100644 --- a/cfrob.hpp +++ b/cfrob.hpp @@ -1,27 +1,115 @@ #pragma once + +#include +#include + 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 + template 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 + constexpr auto memfrob(const u8 (&sz)[N]) + { + return cfrob(sz); + } + template + inline auto memfrob(u8 (&sz)[N]) + { + for(std::size_t i=0;i + inline P* memfrob(u8* ptr, std::size_t len) + { + for(auto i=0;i memfrob(const u8* ptr, std::size_t len) + { + std::vector out; + out.reserve(len); + + for(std::size_t i=0;i& memfrob(std::vector* _s) + { + std::vector& s = *_s; + for(auto& b : s) b = rot13(b); + return s; + } + inline std::vector memfrob(const std::vector& s) + { + std::vector out = s; + memfrob(out); + return out; + } + + template + 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 constexpr auto operator "" _frob() { diff --git a/test/test.cpp b/test/test.cpp index 51cb945..5ad8454 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -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; }