OnixS C++ SGX Titan OUCH Trading Handler  1.2.0
API documentation
NumberFormatting.h
Go to the documentation of this file.
1 // Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2 //
3 // This software owned by Onix Solutions Limited [OnixS] and is
4 // protected by copyright law and international copyright treaties.
5 //
6 // Access to and use of the software is governed by the terms of the applicable
7 // OnixS Software Services Agreement (the Agreement) and Customer end user license
8 // agreements granting a non-assignable, non-transferable and non-exclusive license
9 // to use the software for it's own data processing purposes under the terms defined
10 // in the Agreement.
11 //
12 // Except as otherwise granted within the terms of the Agreement, copying or
13 // reproduction of any part of this source code or associated reference material
14 // to any other location for further reproduction or redistribution, and any
15 // amendments to this copyright notice, are expressly prohibited.
16 //
17 // Any reproduction or redistribution for sale or hiring of the Software not in
18 // accordance with the terms of the Agreement is a violation of copyright law.
19 //
20 
21 #pragma once
22 
23 #include <limits>
24 
25 #include <boost/type_traits.hpp>
26 
29 
30 
32  //
33 
34  template
35  <
36  typename Integer
37  >
38  inline
39  typename
40  boost::enable_if
41  <
42  boost::is_signed<Integer>,
43  bool
44  >::
45  type
47  Integer& integer)
48  {
49  return (0 > integer);
50  }
51 
52  template
53  <
54  typename Integer
55  >
56  inline
57  typename
58  boost::enable_if
59  <
60  boost::is_unsigned<Integer>,
61  bool
62  >::
63  type
65  Integer&)
66  {
67  return false;
68  }
69 
70  //
71 
72  inline
73  void
75  std::string& str)
76  {
77  const Char Minus = '-';
78 
79  str += Minus;
80  }
81 
82  template
83  <
84  typename Integer
85  >
86  inline
87  typename
88  boost::enable_if
89  <
90  boost::is_signed<Integer>
91  >::
92  type
94  std::string& str,
95  Integer integer)
96  {
97  if (0 > integer)
98  addNegativeSign(str);
99  }
100 
101  template
102  <
103  typename Integer
104  >
105  inline
106  typename
107  boost::enable_if
108  <
109  boost::is_unsigned<Integer>
110  >::
111  type
113  std::string&,
114  Integer)
115  {
116  }
117 
118  //
119 
120 
121  template
122  <
123  typename Integer
124  >
125  inline
126  typename
127  boost::enable_if
128  <
129  boost::is_integral<Integer>,
130  size_t
131  >::
132  type
134  Integer integer)
135  {
136  size_t qty = 0;
137 
138  do
139  {
140  ++qty;
141 
142  integer /= 10;
143  } while (integer);
144 
145  return qty;
146  }
147 
148  template
149  <
150  typename Integer
151  >
152  typename
153  boost::enable_if
154  <
155  boost::is_integral<Integer>,
156  size_t
157  >::
158  type
160  Char* str,
161  Integer integer)
162  {
163  const Char map[] =
164  "9876543210123456789";
165 
166  const Char* digits =
167  static_cast<const Char*>(map) +
168  9;
169 
170  Char* carriage = str;
171 
172  do
173  {
174  *carriage++ = *(
175  digits + (integer % 10));
176 
177  integer /= 10;
178  } while (integer);
179 
180  const
181  size_t
182  digitsQty = (
183  carriage - str);
184 
185  while (
186  str != carriage &&
187  str != --carriage)
188  {
189  const Char digit = *str;
190 
191  *str++ = *carriage;
192 
193  *carriage = digit;
194  }
195 
196  return digitsQty;
197  }
198 
199  //
200 
201  template
202  <
203  typename Integer
204  >
205  inline
206  typename
207  boost::enable_if
208  <
209  boost::is_integral<Integer>,
210  size_t
211  >::
212  type
214  Integer integer)
215  {
216  const
217  size_t
218  signLength =
219  isNegative(integer)
220  ? 1
221  : 0;
222 
223  return (
224  signLength +
225  countDigits(integer)
226  );
227  }
228 
229  //
230 
231  template
232  <
233  typename Integer
234  >
235  typename
236  boost::enable_if
237  <
238  boost::is_integral<Integer>
239  >::
240  type
242  std::string& str,
243  Integer integer)
244  {
246  str,
247  integer);
248 
249  Char digits
250  [
251  std::
252  numeric_limits<Integer>::
253  digits10 +
254  2
255  ];
256 
257  str.append
258  (
259  digits,
261  (
262  digits,
263  integer
264  )
265  );
266  }
267 
268  /// Functions below serialize integer and decimal
269  /// numbers in a "%<width>.<precision>" printf format.
270  /// Formatted value is never truncated if width is less
271  /// than a number of digits in a whole part of a number.
272  /// Value truncating is used as rounding strategy when
273  /// fractional part has grater precision than requested
274  /// one.
275 
277  {
278  size_t width_;
279  size_t precision_;
280  Char filler_;
281 
282  public:
284  : width_(0)
285  , precision_(0)
286  , filler_(' ')
287  {
288  }
289 
290  Char filler() const
291  {
292  return filler_;
293  }
294 
295  void filler(Char filler)
296  {
297  filler_ = filler;
298  }
299 
300  size_t width() const
301  {
302  return width_;
303  }
304 
305  void width(size_t width)
306  {
307  width_ = width;
308  }
309 
310  size_t precision() const
311  {
312  return precision_;
313  }
314 
315  void precision(size_t precision)
316  {
317  precision_ = precision;
318  }
319  };
320 
321  inline
322  void
324  std::string& str,
325  const FormatSpec& format,
326  size_t digitsQty)
327  {
328  digitsQty =
329  std::max(
330  digitsQty,
331  format.precision());
332 
333  if (format.width() > digitsQty)
334  {
335  str.append(
336  format.width() - digitsQty,
337  format.filler());
338  }
339  }
340 
341  inline
342  void
344  std::string& str,
345  const FormatSpec& format,
346  size_t digitsQty)
347  {
348  if (format.precision() > digitsQty)
349  {
350  const Char Zero = '0';
351 
352  str.append(
353  format.precision() - digitsQty,
354  Zero);
355  }
356  }
357 
358  template
359  <
360  typename Integer
361  >
362  typename
363  boost::enable_if
364  <
365  boost::is_integral<Integer>
366  >::
367  type
369  std::string& str,
370  const FormatSpec& format,
371  Integer integer)
372  {
373  const
374  bool
375  negative =
376  isNegative(integer);
377 
378  Char digits
379  [
380  std::
381  numeric_limits<Integer>::
382  digits10 +
383  2
384  ];
385 
386  const
387  size_t
388  digitsQty =
389  digitsToStr(
390  digits, integer);
391 
393  (
394  str,
395  format,
396  digitsQty +
397  (negative ? 1 : 0)
398  );
399 
400  if (negative)
401  addNegativeSign(str);
402 
404  (
405  str,
406  format,
407  digitsQty
408  );
409 
410  str.append
411  (
412  digits,
413  digitsQty
414  );
416 }
char Char
Character type alias.
Definition: String.h:38
void addIntegerPrecisionZeros(std::string &str, const FormatSpec &format, size_t digitsQty)
boost::enable_if< boost::is_unsigned< Integer >, bool >::type isNegative(Integer &)
boost::enable_if< boost::is_unsigned< Integer > >::type addNegativeSign(std::string &, Integer)
boost::enable_if< boost::is_integral< Integer >, size_t >::type digitsToStr(Char *str, Integer integer)
boost::enable_if< boost::is_integral< Integer > >::type integerToStr(std::string &str, const FormatSpec &format, Integer integer)
void addIntegerAlignmentSpace(std::string &str, const FormatSpec &format, size_t digitsQty)
#define ONIXS_SGXTITAN_OUCH_NAMESPACE_END
Definition: Bootstrap.h:31
#define ONIXS_SGXTITAN_OUCH_NAMESPACE_BEGIN
Definition: Bootstrap.h:27
boost::enable_if< boost::is_integral< Integer >, size_t >::type measureInteger(Integer integer)
boost::enable_if< boost::is_integral< Integer >, size_t >::type countDigits(Integer integer)