1 /* 2 * Portions of this file are copyright Rebirth contributors and licensed as 3 * described in COPYING.txt. 4 * Portions of this file are copyright Parallax Software and licensed 5 * according to the Parallax license below. 6 * See COPYING.txt for license details. 7 */ 8 9 #pragma once 10 11 #ifdef __cplusplus 12 #include <algorithm> 13 #include <cctype> 14 #include <cstddef> 15 #include "dxxsconf.h" 16 #include <array> 17 18 #define CALLSIGN_LEN 8 // so can use as filename (was: 12) 19 20 struct callsign_t 21 { 22 static const std::size_t array_length = CALLSIGN_LEN + 1; 23 operator const void *() const = delete; 24 using array_t = std::array<char, array_length>; 25 typedef char elements_t[array_length]; 26 array_t a; lower_predicatecallsign_t27 static char lower_predicate(char c) 28 { 29 return std::tolower(static_cast<unsigned>(c)); 30 } zero_terminatecallsign_t31 callsign_t &zero_terminate(array_t::iterator i) 32 { 33 std::fill(i, end(a), 0); 34 return *this; 35 } copycallsign_t36 callsign_t ©(const char *s, std::size_t N) 37 { 38 return zero_terminate(std::copy_n(s, std::min(a.size() - 1, N), begin(a))); 39 } copy_lowercallsign_t40 callsign_t ©_lower(const char *s, std::size_t N) 41 { 42 return zero_terminate(std::transform(s, std::next(s, std::min(a.size() - 1, N)), begin(a), lower_predicate)); 43 } lowercallsign_t44 void lower() 45 { 46 auto ba = begin(a); 47 std::transform(ba, std::prev(end(a)), ba, lower_predicate); 48 a.back() = 0; 49 } 50 [[nodiscard]] buffercallsign_t51 elements_t &buffer() 52 { 53 return *reinterpret_cast<elements_t *>(a.data()); 54 } 55 template <std::size_t N> 56 callsign_t &operator=(const char (&s)[N]) 57 { 58 static_assert(N <= array_length, "string too long"); 59 return copy(s, N); 60 } 61 template <std::size_t N> copy_lowercallsign_t62 void copy_lower(const char (&s)[N]) 63 { 64 static_assert(N <= array_length, "string too long"); 65 return copy_lower(s, N); 66 } fillcallsign_t67 void fill(char c) { a.fill(c); } 68 const char &operator[](std::size_t i) const 69 { 70 return a[i]; 71 } 72 operator const char *() const 73 { 74 return &a[0]; 75 }; 76 bool operator==(const callsign_t &r) const 77 { 78 return a == r.a; 79 } 80 bool operator!=(const callsign_t &r) const 81 { 82 return !(*this == r); 83 } 84 }; 85 static_assert(sizeof(callsign_t) == CALLSIGN_LEN + 1, "callsign_t too big"); 86 87 #endif 88