HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Digits.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_Digits.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #pragma once
12 
13 #include "UT_API.h"
14 //#include <UT/UT_StringHolder.h> // does not work due to recursive include of UT_Format
15 
16 #include <SYS/SYS_Types.h>
17 //#include <string>
18 #include <iosfwd>
19 
20 ///////////////////////////////////////////////////////////////////////////////
21 //! Converts a double or float or half to the shortest accurate decimal possible.
23 {
24 public:
25  enum Flags {
26  GENERAL = 0, //!< used FIXED or SCIENTIFIC depending on range, no trailing zeros
27  FIXED = 1, //!< fixed-point
28  SCIENTIFIC = 2, //!< exponential notation
29  BINARY = 4,
30  OCTAL = 8,
31  HEX = 12,
32  BASE = 12, //!< mask for BINARY, OCTAL, HEX
33  E_PLUS = 16, //!< put a + sign on exponent (like printf)
34  E_2 = 32 //!< use at least 2 digits for exponent (like printf)
35  };
36 
37  //! Initialize to empty string
38  UT_Digits(): mySize(0) { myBuffer[0] = 0; }
39  //! Change to a new 64-bit double
40  void reset(fpreal64, Flags flags=GENERAL, int precision = -1);
41  //! Change to a new 32-bit float
42  void reset(fpreal32, Flags flags=GENERAL, int precision = -1);
43  //! Change to a 16-bit IEEE "half"
44  void reset(fpreal16, Flags flags=GENERAL, int precision = -1);
45  //! Change to an integer
46  void reset(int64, Flags flags=GENERAL, int precision = -1);
47  //! Change to an integer
48  void reset(int32, Flags flags=GENERAL, int precision = -1);
49  //! Change to an unsigned
50  void reset(uint64, Flags flags=GENERAL, int precision = -1);
51  //! Change to an unsigned
52  void reset(uint32, Flags flags=GENERAL, int precision = -1);
53 
54  //! Constructors that do reset(i)
55  explicit UT_Digits(fpreal64 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
56  explicit UT_Digits(fpreal32 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
57  explicit UT_Digits(fpreal16 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
58  explicit UT_Digits(int64 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
59  explicit UT_Digits(int32 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
60  explicit UT_Digits(uint64 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
61  explicit UT_Digits(uint32 i, Flags flags=GENERAL, int precision = -1) { reset(i, flags, precision); }
62 
63  //! Constructors that take precision but no flags
64  UT_Digits(fpreal64 i, int precision) { reset(i, GENERAL, precision); }
65  UT_Digits(fpreal32 i, int precision) { reset(i, GENERAL, precision); }
66  UT_Digits(fpreal16 i, int precision) { reset(i, GENERAL, precision); }
67 
68  //! Return the formatted string, which is stored in an internal buffer
69  const char* c_str() const { return myBuffer; }
70  //! Return the formatted string, which is stored in an internal buffer
71  const char* data() const { return myBuffer; }
72  //! Length of the string
73  unsigned size() const { return mySize; }
74  //! get the bytes of the formatted text
75  char operator[](unsigned i) const { return myBuffer[i]; }
76 
77  //! Return the formatted string, which is stored in an internal buffer
78  operator const char*() const { return myBuffer; }
79 
80  // operator std::string() const { return std::string(myBuffer, mySize); }
81  // operator UT_StringRef() const { return UT_StringRef(myBuffer, mySize); }
82  // operator UT_StringHolder() const { return UT_StringHolder(myBuffer, mySize); }
83  // operator UT_StringView() const { return UT_StringView(myBuffer, mySize); }
84 
85  //! Cast to a double that will format to the same digits. This is useful to
86  //! convert a float or half to the "expected" double value.
87  explicit operator fpreal64() const;
88 
89  //! Returns true if reset to a non-zero value
90  explicit operator bool() const;
91 
92  //! String equality, useful for testing
93  bool operator!=(const char*) const;
94  bool operator==(const char* v) const { return !operator!=(v); }
95 
96  // Post-format modifications. You must call these in this order!
97  void insert(unsigned i, const char* c, unsigned len);
98  void insert(unsigned i, char c, unsigned len=1);
99  void pad0(Flags flags, int digits); //!< add leading zeros so there are n digits
100  void grouping(Flags flags); //!< insert commas every 3 leading digits (or _ every 4 for hex)
101  void prefix(Flags flags); //!< add C prefix such as "0x"
102  void plus(bool space=false); //!< add a '+' or ' ' to positive numbers
103  void uppercase();
104  void append(char c) { myBuffer[mySize++] = c; myBuffer[mySize] = 0; }
105 
106  // std::to_chars emulation
107 
108  char* write(char* start, char* end) const; // returns pointer after last char
109 
110  struct to_chars_result { // match syntax of std::to_chars where you do to_chars().ptr
111  char* ptr;
112  };
113 
114  static to_chars_result to_chars(char* start, char* end, fpreal64 v, Flags flags=GENERAL, int precision=-1)
115  { return {UT_Digits(v, flags, precision).write(start, end)}; }
116  static to_chars_result to_chars(char* start, char* end, fpreal32 v, Flags flags=GENERAL, int precision=-1)
117  { return {UT_Digits(v, flags, precision).write(start, end)}; }
118  static to_chars_result to_chars(char* start, char* end, fpreal16 v, Flags flags=GENERAL, int precision=-1)
119  { return {UT_Digits(v, flags, precision).write(start, end)}; }
120 
121  static to_chars_result to_chars(char* start, char* end, int64 v)
122  { return {UT_Digits(v).write(start, end)}; }
123  static to_chars_result to_chars(char* start, char* end, int32 v)
124  { return {UT_Digits(v).write(start, end)}; }
125  static to_chars_result to_chars(char* start, char* end, uint64 v)
126  { return {UT_Digits(v).write(start, end)}; }
127  static to_chars_result to_chars(char* start, char* end, uint32 v)
128  { return {UT_Digits(v).write(start, end)}; }
129 
130  static Flags toFlags(int base) { return base==16 ? HEX : base==8 ? OCTAL : base == 2 ? BINARY : GENERAL; }
131  static to_chars_result to_chars(char* start, char* end, int64 v, int base)
132  { return {UT_Digits(v, toFlags(base)).write(start, end)}; }
133  static to_chars_result to_chars(char* start, char* end, int32 v, int base)
134  { return {UT_Digits(v, toFlags(base)).write(start, end)}; }
135  static to_chars_result to_chars(char* start, char* end, uint64 v, int base)
136  { return {UT_Digits(v, toFlags(base)).write(start, end)}; }
137  static to_chars_result to_chars(char* start, char* end, uint32 v, int base)
138  { return {UT_Digits(v, toFlags(base)).write(start, end)}; }
139 
140 private:
141  unsigned mySize;
142  char myBuffer[500]; // this is big enough for largest number with precision=31
143 
144  void addSign(bool negative, Flags flags);
145  void addNan(bool infinity, Flags flags);
146  void addInt(int, Flags flags, int precision);
147  void addNumber(int e, uint64 f, Flags flags, int precision);
148  void addNumber(int e, uint64 f, int k, bool, Flags flags, int precision);
149  void addHex(int e, uint64 f, int k, bool, Flags flags, int precision);
150  unsigned addExp(unsigned, int e, Flags flags);
151 };
152 
153 UT_API std::ostream& operator<<(std::ostream& o, const UT_Digits& i);
154 
156 { return UT_Digits::Flags(int(a) | int(b)); }
157 
159 { return a = UT_Digits::Flags(int(a) | int(b)); }
160 
161 /// Replicate EXPRftoa() using UT_Digits, this avoids a temporary WorkBuffer.
162 /// Larger precision makes any value that fits in an int64 print without
163 /// an exponent. Also prints -0.0 as "0" for back-compatability
164 class UT_DigitsEXPR : public UT_Digits
165 {
166 public:
167  UT_DigitsEXPR(fpreal64 v) : UT_Digits(v==0.0 ? 0.0 : v, 19) {}
168  UT_DigitsEXPR(fpreal32 v) : UT_Digits(v==0.0f ? 0.0f : v, 19) {}
169 };
static to_chars_result to_chars(char *start, char *end, int64 v)
Definition: UT_Digits.h:121
static to_chars_result to_chars(char *start, char *end, fpreal16 v, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:118
GLbitfield flags
Definition: glcorearb.h:1596
int int32
Definition: SYS_Types.h:39
UT_Digits(int32 i, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:59
static to_chars_result to_chars(char *start, char *end, uint32 v, int base)
Definition: UT_Digits.h:137
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:128
const GLdouble * v
Definition: glcorearb.h:837
char * write(char *start, char *end) const
GLuint start
Definition: glcorearb.h:475
char operator[](unsigned i) const
get the bytes of the formatted text
Definition: UT_Digits.h:75
UT_Digits()
Initialize to empty string.
Definition: UT_Digits.h:38
bool operator==(const char *v) const
Definition: UT_Digits.h:94
static Flags toFlags(int base)
Definition: UT_Digits.h:130
static to_chars_result to_chars(char *start, char *end, int64 v, int base)
Definition: UT_Digits.h:131
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
UT_DigitsEXPR(fpreal32 v)
Definition: UT_Digits.h:168
void append(char c)
Definition: UT_Digits.h:104
#define UT_API
Definition: UT_API.h:14
UT_Digits(fpreal32 i, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:56
unsigned long long uint64
Definition: SYS_Types.h:117
OIIO_FORCEINLINE vbool4 insert(const vbool4 &a, bool val)
Helper: substitute val for a[i].
Definition: simd.h:3436
float fpreal32
Definition: SYS_Types.h:200
UT_DigitsEXPR(fpreal64 v)
Definition: UT_Digits.h:167
UT_Digits(fpreal64 i, int precision)
Constructors that take precision but no flags.
Definition: UT_Digits.h:64
UT_Digits(fpreal64 i, Flags flags=GENERAL, int precision=-1)
Constructors that do reset(i)
Definition: UT_Digits.h:55
static to_chars_result to_chars(char *start, char *end, uint32 v)
Definition: UT_Digits.h:127
double fpreal64
Definition: SYS_Types.h:201
static to_chars_result to_chars(char *start, char *end, uint64 v)
Definition: UT_Digits.h:125
GLfloat f
Definition: glcorearb.h:1926
GLboolean reset
Definition: glad.h:5138
static to_chars_result to_chars(char *start, char *end, fpreal32 v, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:116
static to_chars_result to_chars(char *start, char *end, uint64 v, int base)
Definition: UT_Digits.h:135
GLuint GLuint end
Definition: glcorearb.h:475
long long int64
Definition: SYS_Types.h:116
const TypeMask operator|(const TypeMask &m1, const TypeMask &m2)
Definition: GA_PrimCompat.h:79
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
const char * data() const
Return the formatted string, which is stored in an internal buffer.
Definition: UT_Digits.h:71
GLenum GLint GLint * precision
Definition: glcorearb.h:1925
UT_Digits(uint32 i, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:61
UT_Digits(fpreal16 i, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:57
static to_chars_result to_chars(char *start, char *end, fpreal64 v, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:114
UT_Digits(uint64 i, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:60
static to_chars_result to_chars(char *start, char *end, int32 v, int base)
Definition: UT_Digits.h:133
static to_chars_result to_chars(char *start, char *end, int32 v)
Definition: UT_Digits.h:123
UT_API std::ostream & operator<<(std::ostream &o, const UT_Digits &i)
unsigned int uint32
Definition: SYS_Types.h:40
UT_Digits(int64 i, Flags flags=GENERAL, int precision=-1)
Definition: UT_Digits.h:58
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
void write(T &out, bool v)
Definition: ImfXdr.h:287
UT_Digits(fpreal32 i, int precision)
Definition: UT_Digits.h:65
Converts a double or float or half to the shortest accurate decimal possible.
Definition: UT_Digits.h:22
const char * c_str() const
Return the formatted string, which is stored in an internal buffer.
Definition: UT_Digits.h:69
UT_Digits(fpreal16 i, int precision)
Definition: UT_Digits.h:66
unsigned size() const
Length of the string.
Definition: UT_Digits.h:73
std::enable_if< UT_EnableBitMask< T >::enable, T & >::type operator|=(T &lhs, T rhs)
Definition: UT_EnumHelper.h:37