]> code.bitgloo.com Git - clyne/constexpr-to-string.git/commitdiff
Merge branch 'master' into patch-1-negative-minimum-value
authorclyne <clyne@bitgloo.com>
Sat, 27 Jun 2020 23:02:24 +0000 (19:02 -0400)
committerGitHub <noreply@github.com>
Sat, 27 Jun 2020 23:02:24 +0000 (19:02 -0400)
1  2 
to_string.hpp

diff --cc to_string.hpp
index 611725855732c39b6a3bdc6ba304bbb23a4b09b7,3f04272b67a6941138057f47d4447a031f4886e4..bf724cd4ca94cb5bffb861fe70a10fb17e2e4597
   * @tparam N Number to convert
   * @tparam base Desired base, can be from 2 to 36
   */
- template<auto N, unsigned int base,
+ template<auto N, unsigned int base, typename char_type,
      std::enable_if_t<std::is_integral_v<decltype(N)>, int> = 0,
      std::enable_if_t<(base > 1 && base < 37), int> = 0>
struct to_string_t {
class to_string_t {
      // The lambda calculates what the string length of N will be, so that `buf`
      // fits to the number perfectly.
-     char buf[([] {
-                   unsigned int len = N >= 0 ? 1 : 2;
-                   for (auto n = N; n; len++, n /= base);
-                   return len;
-              }())];
+     char_type buf[([]() constexpr noexcept {
+                        unsigned int len = N > 0 ? 1 : 2;
 -                       for (auto n = N < 0 ? -N : N; n; len++, n /= base);
++                       for (auto n = N; n; len++, n /= base);
+                        return len;
+                    }())] = {};
  
+  public:
      /**
       * Constructs the object, filling `buf` with the string representation of N.
       */
-     constexpr to_string_t() {
-         auto ptr = buf + sizeof(buf) / sizeof(buf[0]);
+     constexpr to_string_t() noexcept {
+         auto ptr = end();
          *--ptr = '\0';
-         for (auto n = N; n; n /= base)
-             *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(N < 0 ? -1 : 1) * (n % base)];
-         if (N < 0)
-             *--ptr = '-';
+         if (N != 0) {
+             for (auto n = N < 0 ? -N : N; n; n /= base)
 -                *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n % base];
++                *--ptr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(N < 0 ? -1 : 1) * (n % base)];
+             if (N < 0)
+                 *--ptr = '-';
+         } else {
+             buf[0] = '0';
+         }
      }
  
-     /**
-      * Allows implicit conversion of this object to a `char *`.
-      */
-     constexpr operator char *() {
-         return buf;
-     }
-     
-     /**
-      * Allows implicit conversion of this object to a `const char *`.
-      */
-     constexpr operator const char *() const {
-         return buf;
-     }
+     // Support implicit casting to `char *` or `const char *`.
+     constexpr operator char_type *() noexcept { return buf; }
+     constexpr operator const char_type *() const noexcept { return buf; }
+     constexpr auto size() const noexcept { return sizeof(buf) / sizeof(buf[0]); }
+     // Element access
+     constexpr auto data() noexcept { return buf; }
+     constexpr const auto data() const noexcept { return buf; }
+     constexpr auto& operator[](unsigned int i) noexcept { return buf[i]; }
+     constexpr const auto& operator[](unsigned int i) const noexcept { return buf[i]; }
+     constexpr auto& front() noexcept { return buf[0]; }
+     constexpr const auto& front() const noexcept { return buf[0]; }
+     constexpr auto& back() noexcept { return buf[size() - 1]; }
+     constexpr const auto& back() const noexcept { return buf[size() - 1]; }
+     // Iterators
+     constexpr auto begin() noexcept { return buf; }
+     constexpr const auto begin() const noexcept { return buf; }
+     constexpr auto end() noexcept { return buf + size(); }
+     constexpr const auto end() const noexcept { return buf + size(); }
  };
  
  /**