Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  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;
  27.         static char lower_predicate(char c)
  28.         {
  29.                 return std::tolower(static_cast<unsigned>(c));
  30.         }
  31.         callsign_t &zero_terminate(array_t::iterator i)
  32.         {
  33.                 std::fill(i, end(a), 0);
  34.                 return *this;
  35.         }
  36.         callsign_t &copy(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.         }
  40.         callsign_t &copy_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.         }
  44.         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.         elements_t &buffer() __attribute_warn_unused_result
  51.         {
  52.                 return *reinterpret_cast<elements_t *>(a.data());
  53.         }
  54.         template <std::size_t N>
  55.                 callsign_t &operator=(const char (&s)[N])
  56.                 {
  57.                         static_assert(N <= array_length, "string too long");
  58.                         return copy(s, N);
  59.                 }
  60.         template <std::size_t N>
  61.                 void copy_lower(const char (&s)[N])
  62.                 {
  63.                         static_assert(N <= array_length, "string too long");
  64.                         return copy_lower(s, N);
  65.                 }
  66.         void fill(char c) { a.fill(c); }
  67.         const char &operator[](std::size_t i) const
  68.         {
  69.                 return a[i];
  70.         }
  71.         operator const char *() const
  72.         {
  73.                 return &a[0];
  74.         };
  75.         bool operator==(const callsign_t &r) const
  76.         {
  77.                 return a == r.a;
  78.         }
  79.         bool operator!=(const callsign_t &r) const
  80.         {
  81.                 return !(*this == r);
  82.         }
  83. };
  84. static_assert(sizeof(callsign_t) == CALLSIGN_LEN + 1, "callsign_t too big");
  85.  
  86. #endif
  87.