Skip to content

File tagliteral.h

File List > code_source > templat > include > TempLat > util > rangeiteration > tagliteral.h

Go to the documentation of this file

#ifndef TEMPLAT_UTIL_RANGEITERATION_TAGLITERAL_H
#define TEMPLAT_UTIL_RANGEITERATION_TAGLITERAL_H

/* This file is part of TempLat, available at https://cosmolattice.github.io/templat .
   Copyright 2021-2026 The TempLat authors, see AUTHORS.md.
   Released under the MIT license, see LICENSE.md. */

// File info: Main contributor(s): Adrien Florio, Year: 2019

#include "TempLat/util/rangeiteration/tag.h"

namespace TempLat
{

  /*Disclaimer: The following two functions are taken as is from boost::hana from the integral_constants file, credit to
   * Louis Dionne. As such, they are released under the Boost License.
   * */

  constexpr int to_int(char c)
  {
    int result = 0;

    if (c >= 'A' && c <= 'F') {
      result = static_cast<int>(c) - static_cast<int>('A') + 10;
    } else if (c >= 'a' && c <= 'f') {
      result = static_cast<int>(c) - static_cast<int>('a') + 10;
    } else {
      result = static_cast<int>(c) - static_cast<int>('0');
    }

    return result;
  }

  template <std::size_t N> constexpr long long parse(const char (&arr)[N])
  {
    long long base = 10;
    std::size_t offset = 0;

    if (N > 2) {
      bool starts_with_zero = arr[0] == '0';
      bool is_hex = starts_with_zero && arr[1] == 'x';
      bool is_binary = starts_with_zero && arr[1] == 'b';

      if (is_hex) {
        // 0xDEADBEEF (hexadecimal)
        base = 16;
        offset = 2;
      } else if (is_binary) {
        // 0b101011101 (binary)
        base = 2;
        offset = 2;
      } else if (starts_with_zero) {
        // 012345 (octal)
        base = 8;
        offset = 1;
      }
    }

    long long number = 0;
    long long multiplier = 1;

    for (std::size_t i = 0; i < N - offset; ++i) {
      char c = arr[N - 1 - i];
      if (c != '\'') { // skip digit separators
        number += to_int(c) * multiplier;
        multiplier *= base;
      }
    }

    return number;
  }
  // END disclaimer.

  template <char... c> constexpr auto operator""_c()
  { // Adapted from boost::hana as well, but not as such.
    return Tag<parse<sizeof...(c)>({c...})>{};
  }

} // namespace TempLat

#endif