aboutsummaryrefslogtreecommitdiff
path: root/include/cru/common/StringToNumberConverter.h
blob: b5118de65866cdc497047a11021191a0bd352484 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#pragma once
#include "Base.h"

#include <ostream>

namespace cru {
struct StringToNumberFlags {
  constexpr static unsigned kNoFlags = 0;
  constexpr static unsigned kAllowLeadingSpaces = 1 << 0;
  constexpr static unsigned kAllowTrailingSpaces = 1 << 1;
  constexpr static unsigned kAllowTrailingJunk = 1 << 2;
  constexpr static unsigned kAllowLeadingZeroForInteger = 1 << 2;
  constexpr static unsigned kThrowOnError = 1 << 3;
};

struct StringToIntegerConverterImplResult {
  StringToIntegerConverterImplResult() = default;
  StringToIntegerConverterImplResult(bool negate, unsigned long long value)
      : negate(negate), value(value) {}

  bool negate;
  unsigned long long value;
};

inline bool operator==(const StringToIntegerConverterImplResult& left,
                       const StringToIntegerConverterImplResult& right) {
  return left.negate == right.negate && left.value == right.value;
}

inline bool operator!=(const StringToIntegerConverterImplResult& left,
                       const StringToIntegerConverterImplResult& right) {
  return !(left == right);
}

inline std::ostream& operator<<(
    std::ostream& stream, const StringToIntegerConverterImplResult& result) {
  return stream << "StringToIntegerConverterImplResult("
                << (result.negate ? "-" : "") << result.value << ")";
}

/**
 * \brief A converter that convert number into long long.
 */
struct StringToIntegerConverterImpl {
 public:
  explicit StringToIntegerConverterImpl(unsigned flags, int base = 0)
      : flags(flags), base(base) {}

  bool CheckParams() const;

  /**
   * \brief Convert string to long long.
   * \param str The string to convert.
   * \param size The size of the string.
   * \param processed_characters_count The number of characters that were
   * processed. Or nullptr to not retrieve.
   */
  StringToIntegerConverterImplResult Parse(
      const char* str, Index size, Index* processed_characters_count) const;

  template <std::size_t Size>
  StringToIntegerConverterImplResult Parse(
      const char (&str)[Size], Index* processed_characters_count) const {
    return Parse(str, Size - 1, processed_characters_count);
  }

  unsigned flags;
  /**
   * \brief The base of the number used for parse or 0 for auto detect.
   * \remarks Base can only be of range [2, 36] or 0. If base is 0, decimal is
   * assumed by default ,or if str is started with "0x" or "0X" hexadecimal is
   * assumed, or if str is started with a single "0" octoral is assumed, or if
   * str is started with "0b" or "0B" binary is assumed. Otherwise it is an
   * error.
   */
  int base;
};
}  // namespace cru