OnixS C++ SGX Titan ITCH Market Data Handler  1.2.2
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 
31 #include "NamespaceHelper.h"
32 
33 ONIXS_HANDLER_NAMESPACE_BEGIN
34 
35 //
36 
37 template
38  <
39  typename Integer
40  >
41  inline
42  typename
43  boost::enable_if
44  <
45  boost::is_signed<Integer>,
46  bool
47  >::
48  type
50  Integer& integer)
51 {
52  return (0 > integer);
53 }
54 
55 template
56  <
57  typename Integer
58  >
59  inline
60  typename
61  boost::enable_if
62  <
63  boost::is_unsigned<Integer>,
64  bool
65  >::
66  type
68  Integer&)
69 {
70  return false;
71 }
72 
73 //
74 
75 inline
76  void
78  std::string& str)
79 {
80  const Char Minus = '-';
81 
82  str += Minus;
83 }
84 
85 template
86  <
87  typename Integer
88  >
89  inline
90  typename
91  boost::enable_if
92  <
93  boost::is_signed<Integer>
94  >::
95  type
97  std::string& str,
98  Integer integer)
99 {
100  if (0 > integer)
101  addNegativeSign(str);
102 }
103 
104 template
105  <
106  typename Integer
107  >
108  inline
109  typename
110  boost::enable_if
111  <
112  boost::is_unsigned<Integer>
113  >::
114  type
116  std::string&,
117  Integer)
118 {
119 }
120 
121 //
122 
123 
124 template
125  <
126  typename Integer
127  >
128  inline
129  typename
130  boost::enable_if
131  <
132  boost::is_integral<Integer>,
133  size_t
134  >::
135  type
137  Integer integer)
138 {
139  size_t qty = 0;
140 
141  do
142  {
143  ++qty;
144 
145  integer /= 10;
146  } while (integer);
147 
148  return qty;
149 }
150 
151 template
152  <
153  typename Integer
154  >
155  typename
156  boost::enable_if
157  <
158  boost::is_integral<Integer>,
159  size_t
160  >::
161  type
163  Char* str,
164  Integer integer)
165 {
166  const Char map[] =
167  "9876543210123456789";
168 
169  const Char* digits =
170  static_cast<const Char*>(map) +
171  9;
172 
173  Char* carriage = str;
174 
175  do
176  {
177  *carriage++ = *(
178  digits + (integer % 10));
179 
180  integer /= 10;
181  } while (integer);
182 
183  const
184  size_t
185  digitsQty = (
186  carriage - str);
187 
188  while (
189  str != carriage &&
190  str != --carriage)
191  {
192  const Char digit = *str;
193 
194  *str++ = *carriage;
195 
196  *carriage = digit;
197  }
198 
199  return digitsQty;
200 }
201 
202 //
203 
204 template
205  <
206  typename Integer
207  >
208  inline
209  typename
210  boost::enable_if
211  <
212  boost::is_integral<Integer>,
213  size_t
214  >::
215  type
217  Integer integer)
218 {
219  const
220  size_t
221  signLength =
222  isNegative(integer)
223  ? 1
224  : 0;
225 
226  return (
227  signLength +
228  countDigits(integer)
229  );
230 }
231 
232 //
233 
234 template
235  <
236  typename Integer
237  >
238  typename
239  boost::enable_if
240  <
241  boost::is_integral<Integer>
242  >::
243  type
245  std::string& str,
246  Integer integer)
247 {
249  str,
250  integer);
251 
252  Char digits
253  [
254  std::
255  numeric_limits<Integer>::
256  digits10 +
257  2
258  ];
259 
260  str.append
261  (
262  digits,
264  (
265  digits,
266  integer
267  )
268  );
269 }
270 
271 /// Functions below serialize integer and decimal
272 /// numbers in a "%<width>.<precision>" printf format.
273 /// Formatted value is never truncated if width is less
274 /// than a number of digits in a whole part of a number.
275 /// Value truncating is used as rounding strategy when
276 /// fractional part has grater precision than requested
277 /// one.
278 
280 {
281  size_t width_;
282  size_t precision_;
283  Char filler_;
284 
285 public:
287  : width_(0)
288  , precision_(0)
289  , filler_(' ')
290  {
291  }
292 
293  Char filler() const
294  {
295  return filler_;
296  }
297 
298  void filler(Char filler)
299  {
300  filler_ = filler;
301  }
302 
303  size_t width() const
304  {
305  return width_;
306  }
307 
308  void width(size_t width)
309  {
310  width_ = width;
311  }
312 
313  size_t precision() const
314  {
315  return precision_;
316  }
317 
318  void precision(size_t precision)
319  {
320  precision_ = precision;
321  }
322 };
323 
324 inline
325  void
327  std::string& str,
328  const FormatSpec& format,
329  size_t digitsQty)
330 {
331  using namespace std;
332  digitsQty =
333  max(
334  digitsQty,
335  format.precision());
336 
337  if (format.width() > digitsQty)
338  {
339  str.append(
340  format.width() - digitsQty,
341  format.filler());
342  }
343 }
344 
345 inline
346  void
348  std::string& str,
349  const FormatSpec& format,
350  size_t digitsQty)
351 {
352  if (format.precision() > digitsQty)
353  {
354  const Char Zero = '0';
355 
356  str.append(
357  format.precision() - digitsQty,
358  Zero);
359  }
360 }
361 
362 template
363  <
364  typename Integer
365  >
366  typename
367  boost::enable_if
368  <
369  boost::is_integral<Integer>
370  >::
371  type
373  std::string& str,
374  const FormatSpec& format,
375  Integer integer)
376 {
377  const
378  bool
379  negative =
380  isNegative(integer);
381 
382  Char digits
383  [
384  std::
385  numeric_limits<Integer>::
386  digits10 +
387  2
388  ];
389 
390  const
391  size_t
392  digitsQty =
393  digitsToStr(
394  digits, integer);
395 
397  (
398  str,
399  format,
400  digitsQty +
401  (negative ? 1 : 0)
402  );
403 
404  if (negative)
405  addNegativeSign(str);
406 
408  (
409  str,
410  format,
411  digitsQty
412  );
413 
414  str.append
415  (
416  digits,
417  digitsQty
418  );
419 }
420 
421 ONIXS_HANDLER_NAMESPACE_END
char Char
Character type alias.
Definition: String.h:37
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)
STL namespace.
void addIntegerAlignmentSpace(std::string &str, const FormatSpec &format, size_t digitsQty)
void addIntegerPrecisionZeros(std::string &str, const FormatSpec &format, size_t digitsQty)
boost::enable_if< boost::is_integral< Integer >, size_t >::type measureInteger(Integer integer)
boost::enable_if< boost::is_unsigned< Integer >, bool >::type isNegative(Integer &)
boost::enable_if< boost::is_integral< Integer >, size_t >::type countDigits(Integer integer)
boost::enable_if< boost::is_integral< Integer > >::type integerToStr(std::string &str, const FormatSpec &format, Integer integer)