fix8  version 1.4.0
Open Source C++ FIX Framework
traits.hpp
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------------------
2 /*
3 
4 Fix8 is released under the GNU LESSER GENERAL PUBLIC LICENSE Version 3.
5 
6 Fix8 Open Source FIX Engine.
7 Copyright (C) 2010-16 David L. Dight <fix@fix8.org>
8 
9 Fix8 is free software: you can redistribute it and / or modify it under the terms of the
10 GNU Lesser General Public License as published by the Free Software Foundation, either
11 version 3 of the License, or (at your option) any later version.
12 
13 Fix8 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 
16 You should have received a copy of the GNU Lesser General Public License along with Fix8.
17 If not, see <http://www.gnu.org/licenses/>.
18 
19 BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO
20 THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
21 COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
22 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
24 THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
25 YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
26 
27 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
28 HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
29 ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
30 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
31 NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
32 THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
33 HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 
35 */
36 //-------------------------------------------------------------------------------------------------
37 #ifndef FIX8_TRAITS_HPP_
38 #define FIX8_TRAITS_HPP_
39 
40 #include <set>
41 
42 //-------------------------------------------------------------------------------------------------
43 namespace FIX8 {
44 
45 //-------------------------------------------------------------------------------------------------
47 #if defined FIX8_HAVE_EXTENDED_METADATA
48 struct TraitHelper
49 {
50  const struct FieldTrait *_traits;
51  const unsigned _fieldcnt;
52 };
53 #endif
54 
55 //-------------------------------------------------------------------------------------------------
57 struct FieldTrait
58 {
59  enum FieldType
60  {
75  };
76 
79 
83  static bool is_int(FieldType ftype) { return ft_int <= ftype && ftype <= ft_end_int; }
84 
88  static bool is_char(FieldType ftype) { return ft_char <= ftype && ftype <= ft_end_char; }
89 
93  static bool is_float(FieldType ftype) { return ft_float <= ftype && ftype <= ft_end_float; }
94 
98  static bool is_string(FieldType ftype) { return ft_string <= ftype && ftype <= ft_end_string; }
99 
104  {
105  return is_int(ftype) ? ft_int : is_char(ftype) ? ft_char : is_float(ftype) ? ft_float : is_string(ftype) ? ft_string : ft_untyped;
106  }
107 
109  FieldTrait() = default;
110 
112  FieldTrait(const FieldTrait& from) : _fnum(from._fnum), _ftype(from._ftype), _pos(from._pos),
114 
123  FieldTrait(unsigned short fnum, unsigned ftype, unsigned short pos, unsigned short compon, unsigned short field_traits
124 #if defined FIX8_HAVE_EXTENDED_METADATA
125  , const FieldTrait *group=nullptr, unsigned fieldcnt=0
126 #endif
127  )
128  : _fnum(fnum), _ftype(FieldType(ftype)), _pos(pos), _component(compon), _field_traits(field_traits)
129 #if defined FIX8_HAVE_EXTENDED_METADATA
130  , _group(TraitHelper{group, fieldcnt})
131 #endif
132  {}
133 
136  FieldTrait(const unsigned short field) : _fnum(field) {}
137 
146  FieldTrait(const unsigned short field, const FieldType ftype, const unsigned short pos=0,
147  bool ismandatory=false, bool isgroup=false, const unsigned compon=0, bool ispresent=false) :
148  _fnum(field), _ftype(ftype), _pos(pos), _component(compon),
149  _field_traits((ismandatory ? 1 : 0) | (ispresent ? 1 : 0) << present
150  | (pos ? 1 : 0) << position | (isgroup ? 1 : 0) << group | (compon ? 1 : 0) << component) {}
151 
152  unsigned short _fnum;
154  mutable unsigned short _pos, _component;
156 #if defined FIX8_HAVE_EXTENDED_METADATA
157  const TraitHelper _group = TraitHelper{ nullptr, 0 };
158 #endif
159 
161  struct Compare
162  {
167  bool operator()(const FieldTrait& p1, const FieldTrait& p2) const { return p1._fnum < p2._fnum; }
168  };
169 
171  struct PosCompare
172  {
177  bool operator()(const FieldTrait* p1, const FieldTrait* p2) const
178  { return p1->_pos < p2->_pos; }
179  };
180 
185  static F8API std::string& get_type_string(FieldType ftype, std::string& to);
186 
191  friend F8API std::ostream& operator<<(std::ostream& os, const FieldTrait& what);
192 };
193 
194 F8API std::ostream& operator<<(std::ostream& os, const FieldTrait& what);
195 
196 //-------------------------------------------------------------------------------------------------
199 {
200  const unsigned _els, _sz;
201  unsigned short *_arr;
202 
203  FieldTrait_Hash_Array(const FieldTrait *from, const size_t els)
204  : _els(static_cast<unsigned>(els)), _sz((from + _els - 1)->_fnum + 1), _arr(new unsigned short [_sz])
205  {
206  std::fill(_arr, _arr + _sz, 0);
207  for (unsigned offset(0); offset < _els; ++offset)
208  *(_arr + (from + offset)->_fnum) = offset;
209  }
210 
211  ~FieldTrait_Hash_Array() { delete[] _arr; }
212 };
213 
214 //-------------------------------------------------------------------------------------------------
217 template<>
218 class presorted_set<unsigned short, FieldTrait, FieldTrait::Compare>
219 {
220 public:
222  using const_iterator = const FieldTrait*;
223  using result = std::pair<iterator, bool>;
224 
229  static size_t calc_reserve(size_t sz, size_t res)
230  {
231  if (!sz) // special case - reserve means number to reserve, not %
232  return res;
233  const size_t val(sz * res / 100);
234  return val ? val : 1;
235  }
236 
237 private:
238  size_t _reserve;
239  size_t _sz, _rsz;
242 
243  using internal_result = std::pair<iterator, iterator>;
244  using const_internal_result = std::pair<const_iterator, const_iterator>;
245 
246 public:
251  presorted_set(const_iterator arr_start, const size_t sz, const FieldTrait_Hash_Array *ftha)
252  : _reserve(), _sz(sz), _arr(new FieldTrait[_sz]), _ftha(ftha)
253  { memcpy(_arr, arr_start, _sz * sizeof(FieldTrait)); }
254 
259  presorted_set(const_iterator arr_start, const size_t sz, const size_t reserve=FIX8_RESERVE_PERCENT) : _reserve(reserve),
260  _sz(sz), _rsz(_sz + calc_reserve(_sz, _reserve)), _arr(new FieldTrait[_rsz]), _ftha()
261  { memcpy(_arr, arr_start, _sz * sizeof(FieldTrait)); }
262 
265  presorted_set(const presorted_set& from) : _reserve(from._reserve),
266  _sz(from._sz), _rsz(from._rsz), _arr(new FieldTrait[_rsz]), _ftha(from._ftha)
267  { memcpy(_arr, from._arr, _sz * sizeof(FieldTrait)); }
268 
272  explicit presorted_set(const size_t sz=0, const size_t reserve=FIX8_RESERVE_PERCENT) : _reserve(reserve),
273  _sz(sz), _rsz(_sz + calc_reserve(_sz, _reserve)), _arr(), _ftha() {}
274 
276  ~presorted_set() { delete[] _arr; }
277 
282  iterator find(const FieldTrait what, bool& answer)
283  {
284  if (_ftha)
285  return (answer = what._fnum < _ftha->_sz && (_arr + _ftha->_arr[what._fnum])->_fnum == what._fnum) ? _arr + _ftha->_arr[what._fnum] : 0;
286  const internal_result res(std::equal_range (_arr, _arr + _sz, what, FieldTrait::Compare()));
287  answer = res.first != res.second;
288  return res.first;
289  }
290 
295  iterator find(const unsigned short key, bool& answer) { return find(FieldTrait(key), answer); }
296 
300  const_iterator find(const unsigned short key) const
301  {
302  if (_ftha)
303  return key < _ftha->_sz && (_arr + _ftha->_arr[key])->_fnum == key ? _arr + _ftha->_arr[key] : end();
304  const FieldTrait what(key);
305  const const_internal_result res(std::equal_range (_arr, _arr + _sz, what, FieldTrait::Compare()));
306  return res.first != res.second ? res.first : end();
307  }
308 
312  const_iterator find(const FieldTrait what) const
313  {
314  if (_ftha)
315  return what._fnum < _ftha->_sz && (_arr + _ftha->_arr[what._fnum])->_fnum == what._fnum ? _arr + _ftha->_arr[what._fnum] : end();
316  const const_internal_result res(std::equal_range (_arr, _arr + _sz, what, FieldTrait::Compare()));
317  return res.first != res.second ? res.first : end();
318  }
319 
323  iterator find(const unsigned short key)
324  {
325  if (_ftha)
326  return key < _ftha->_sz && (_arr + _ftha->_arr[key])->_fnum == key ? _arr + _ftha->_arr[key] : end();
327  const FieldTrait what(key);
328  internal_result res(std::equal_range (_arr, _arr + _sz, what, FieldTrait::Compare()));
329  return res.first != res.second ? res.first : end();
330  }
331 
336  {
337  internal_result res(std::equal_range (_arr, _arr + _sz, what, FieldTrait::Compare()));
338  return res.first != res.second ? res.first : end();
339  }
340 
344  const_iterator at(const size_t idx) const { return idx < _sz ? _arr + idx : end(); }
345 
350  {
351  if (!_sz)
352  {
353  _arr = new FieldTrait[_rsz];
354  memcpy(_arr, what, sizeof(FieldTrait));
355  ++_sz;
356  return std::make_pair(_arr, true);
357  }
358 
359  bool answer;
360  iterator where(find(*what, answer));
361  if (answer) // sorry already here
362  return std::make_pair(end(), false);
363 
364  if (_sz < _rsz) // we have space
365  {
366  memmove(where + 1, where, (end() - where) * sizeof(FieldTrait));
367  memcpy(where, what, sizeof(FieldTrait));
368  }
369  else // we have to make space
370  {
371  iterator new_arr(new FieldTrait[_rsz = _sz + calc_reserve(_sz, _reserve)]);
372  const size_t wptr(where - _arr);
373  if (wptr > 0)
374  memcpy(new_arr, _arr, sizeof(FieldTrait) * wptr);
375  memcpy(new_arr + wptr, what, sizeof(FieldTrait));
376  memcpy(new_arr + wptr + 1, where, (end() - where) * sizeof(FieldTrait));
377  delete[] _arr;
378  _arr = new_arr;
379  }
380  ++_sz;
381  return std::make_pair(where, true);
382  }
383 
388  static size_t distance(const_iterator what_begin, const_iterator what_end)
389  { return what_end - what_begin; }
390 
394  void insert(const_iterator what_begin, const_iterator what_end)
395  {
396  for (const_iterator ptr(what_begin); ptr < what_end; ++ptr)
397  if (!insert(ptr).second)
398  break;
399  }
400 
402  void clear() { _sz = 0; }
403 
406  size_t size() const { return _sz; }
407 
410  bool empty() const { return _sz == 0; }
411 
414  size_t rsize() const { return _rsz; }
415 
418  iterator begin() { return _arr; }
419 
422  iterator end() { return _arr + _sz; }
423 
426  const_iterator begin() const { return _arr; }
427 
430  const_iterator end() const { return _arr + _sz; }
431 };
432 
433 //-------------------------------------------------------------------------------------------------
435 
438 {
440 
441 public:
447  template<typename InputIterator>
448  FieldTraits(const InputIterator begin, const size_t cnt,
449  const FieldTrait_Hash_Array *ftha) : _presence(begin, cnt, ftha) {}
452 
457  bool has(const unsigned short field, Presence::const_iterator& itr) const
458  {
459  if (itr == _presence.end())
460  itr = _presence.find(field);
461  return itr != _presence.end();
462  }
463 
467  bool has(const unsigned short field) const
468  {
469  Presence::const_iterator itr(_presence.find(field));
470  return itr != _presence.end();
471  }
472 
476  unsigned getval(const unsigned short field)
477  {
478  Presence::const_iterator itr(_presence.find(field));
479  return itr != _presence.end() ? itr->_field_traits.get() : 0;
480  }
481 
484  size_t size() const { return _presence.size(); }
485 
490  bool get(const unsigned short field, FieldTrait::TraitTypes type=FieldTrait::present) const
491  {
492  Presence::const_iterator itr(_presence.find(field));
493  return itr != _presence.end() ? itr->_field_traits.has(type) : false;
494  }
495 
501  bool get(const unsigned short field, Presence::const_iterator& itr, FieldTrait::TraitTypes type) const
502  {
503  if (itr != _presence.end())
504  return itr->_field_traits.has(type);
505  itr = _presence.find(field);
506  return itr != _presence.end() ? itr->_field_traits.has(type) : false;
507  }
508 
513  {
514  for (Presence::const_iterator itr(_presence.begin()); itr != _presence.end(); ++itr)
515  if ((itr->_field_traits & type) && (itr->_field_traits & FieldTrait::present) == 0)
516  return itr->_fnum;
517  return 0;
518  }
519 
524  void set(const unsigned short field, Presence::const_iterator& itr, FieldTrait::TraitTypes type)
525  {
526  if (itr == _presence.end())
527  {
528  itr = _presence.find(field);
529  if (itr != _presence.end())
530  itr->_field_traits.set(type);
531  }
532  else
533  itr->_field_traits.set(type);
534  }
535 
539  void set(const unsigned short field, FieldTrait::TraitTypes type=FieldTrait::present)
540  {
541  Presence::iterator itr(_presence.find(field));
542  if (itr != _presence.end())
543  itr->_field_traits.set(type);
544  }
545 
550  void clear(const unsigned short field, Presence::const_iterator& itr, FieldTrait::TraitTypes type=FieldTrait::present)
551  {
552  if (itr == _presence.end())
553  {
554  itr = _presence.find(field);
555  if (itr != _presence.end())
556  itr->_field_traits.clear(type);
557  }
558  else
559  itr->_field_traits.clear(type);
560  }
561 
565  void clear(const unsigned short field, FieldTrait::TraitTypes type=FieldTrait::present)
566  {
567  Presence::iterator itr(_presence.find(field));
568  if (itr != _presence.end())
569  itr->_field_traits.clear(type);
570  }
571 
575  bool add(const FieldTrait& what) { return _presence.insert(&what).second; }
576 
580  template<typename InputIterator>
581  void add(const InputIterator begin, const size_t cnt) { _presence.insert(begin, begin + cnt); }
582 
586  { for (Presence::const_iterator itr(_presence.begin()); itr != _presence.end(); itr++->_field_traits.clear(type)); }
587 
591  bool is_present(const unsigned short field) const { return get(field, FieldTrait::present); }
592 
596  bool is_mandatory(const unsigned short field) const { return get(field, FieldTrait::mandatory); }
597 
602  bool is_group(const unsigned short field, Presence::const_iterator& itr) const { return get(field, itr, FieldTrait::group); }
603 
607  bool is_group(const unsigned short field) const { return get(field, FieldTrait::group); }
608 
612  bool is_component(const unsigned short field) const { return get(field, FieldTrait::component); }
613 
618  unsigned short getComp(const unsigned short field, Presence::const_iterator& itr) const
619  {
620  if (itr != _presence.end())
621  return itr->_component;
622  itr = _presence.find(field);
623  return itr != _presence.end() ? itr->_component : 0;
624  }
625 
629  unsigned short getComp(const unsigned short field) const
630  {
631  Presence::const_iterator itr(_presence.find(field));
632  return itr != _presence.end() ? itr->_component : 0;
633  }
634 
639  unsigned short getPos(const unsigned short field, Presence::const_iterator& itr) const
640  {
641  if (itr != _presence.end())
642  return itr->_field_traits.has(FieldTrait::position) ? itr->_pos : 0;
643  itr = _presence.find(field);
644  return itr != _presence.end() && itr->_field_traits.has(FieldTrait::position) ? itr->_pos : 0;
645  }
646 
650  unsigned short getPos(const unsigned short field) const
651  {
652  Presence::const_iterator itr(_presence.find(field));
653  return itr != _presence.end() && itr->_field_traits.has(FieldTrait::position) ? itr->_pos : 0;
654  }
655 
658  const Presence& get_presence() const { return _presence; }
659 
664  friend F8API std::ostream& operator<<(std::ostream& os, const FieldTraits& what);
665 };
666 
667 F8API std::ostream& operator<<(std::ostream& os, const FieldTraits& what);
668 
669 } // FIX8
670 
671 #endif // FIX8_TRAITS_HPP_
FieldTrait(const unsigned short field, const FieldType ftype, const unsigned short pos=0, bool ismandatory=false, bool isgroup=false, const unsigned compon=0, bool ispresent=false)
Definition: traits.hpp:146
integral_type get() const
Definition: f8utils.hpp:924
static F8API std::string & get_type_string(FieldType ftype, std::string &to)
Definition: traits.cpp:69
void clear(const unsigned short field, Presence::const_iterator &itr, FieldTrait::TraitTypes type=FieldTrait::present)
Definition: traits.hpp:550
static FieldType underlying_type(FieldType ftype)
Definition: traits.hpp:103
Binary comparitor functor.
Definition: traits.hpp:161
unsigned short find_missing(FieldTrait::TraitTypes type=FieldTrait::mandatory) const
Definition: traits.hpp:512
FieldTraits(const InputIterator begin, const size_t cnt, const FieldTrait_Hash_Array *ftha)
Definition: traits.hpp:448
void insert(const_iterator what_begin, const_iterator what_end)
Definition: traits.hpp:394
static size_t calc_reserve(size_t sz, size_t res)
Definition: f8types.hpp:205
presorted_set(const size_t sz=0, const size_t reserve=FIX8_RESERVE_PERCENT)
Definition: traits.hpp:272
static bool is_char(FieldType ftype)
Definition: traits.hpp:88
unsigned short getPos(const unsigned short field, Presence::const_iterator &itr) const
Definition: traits.hpp:639
presorted_set(const_iterator arr_start, const size_t sz, const size_t reserve=FIX8_RESERVE_PERCENT)
Definition: traits.hpp:259
void clear(const T sbit)
Definition: f8utils.hpp:913
bool has(const unsigned short field, Presence::const_iterator &itr) const
Definition: traits.hpp:457
FieldTraits()
Ctor.
Definition: traits.hpp:451
bool is_mandatory(const unsigned short field) const
Definition: traits.hpp:596
const_iterator find(const FieldTrait what) const
Definition: traits.hpp:312
const Presence & get_presence() const
Definition: traits.hpp:658
FieldTrait(unsigned short fnum, unsigned ftype, unsigned short pos, unsigned short compon, unsigned short field_traits)
Definition: traits.hpp:123
std::ostream & operator<<(std::ostream &os, const GroupBase &what)
Definition: message.hpp:1373
bool is_component(const unsigned short field) const
Definition: traits.hpp:612
FieldTrait_Hash_Array(const FieldTrait *from, const size_t els)
Definition: traits.hpp:203
unsigned short * _arr
Definition: traits.hpp:201
FieldTrait(const unsigned short field)
Definition: traits.hpp:136
void add(const InputIterator begin, const size_t cnt)
Definition: traits.hpp:581
TraitTypes
Trait bits.
Definition: traits.hpp:78
result insert(const_iterator what)
Definition: f8types.hpp:290
Used for static trait interrogation.
Definition: traits.hpp:57
static bool is_float(FieldType ftype)
Definition: traits.hpp:93
iterator find(const unsigned short key, bool &answer)
Definition: traits.hpp:295
#define F8API
Definition: f8dll.h:60
void clear_flag(FieldTrait::TraitTypes type=FieldTrait::present)
Definition: traits.hpp:585
unsigned short _component
Definition: traits.hpp:154
const_iterator find(const unsigned short key) const
Definition: traits.hpp:300
void set(const unsigned short field, FieldTrait::TraitTypes type=FieldTrait::present)
Definition: traits.hpp:539
#define FIX8_RESERVE_PERCENT
Definition: f8config.h:676
Binary position comparitor functor.
Definition: traits.hpp:171
unsigned short _fnum
Definition: traits.hpp:152
ebitset< TraitTypes, unsigned short > _field_traits
Definition: traits.hpp:155
void clear(const unsigned short field, FieldTrait::TraitTypes type=FieldTrait::present)
Definition: traits.hpp:565
static size_t distance(const_iterator what_begin, const_iterator what_end)
Definition: traits.hpp:388
bool is_group(const unsigned short field, Presence::const_iterator &itr) const
Definition: traits.hpp:602
bool has(const unsigned short field) const
Definition: traits.hpp:467
friend F8API std::ostream & operator<<(std::ostream &os, const FieldTrait &what)
size_t size() const
Definition: traits.hpp:484
bool operator()(const FieldTrait &p1, const FieldTrait &p2) const
Definition: traits.hpp:167
unsigned short _pos
Definition: traits.hpp:154
static bool is_int(FieldType ftype)
Definition: traits.hpp:83
iterator find(const T what, bool &answer)
Definition: f8types.hpp:241
static bool is_string(FieldType ftype)
Definition: traits.hpp:98
Presence _presence
Definition: traits.hpp:439
bool add(const FieldTrait &what)
Definition: traits.hpp:575
integral_type has(const T sbit) const
Definition: f8utils.hpp:876
A collection of FieldTraits for a message. Which fields are required, which are present.
Definition: traits.hpp:437
FieldTrait(const FieldTrait &from)
Copy Ctor.
Definition: traits.hpp:112
unsigned short getPos(const unsigned short field) const
Definition: traits.hpp:650
unsigned short getComp(const unsigned short field) const
Definition: traits.hpp:629
presorted_set(const_iterator arr_start, const size_t sz, const FieldTrait_Hash_Array *ftha)
Definition: traits.hpp:251
friend F8API std::ostream & operator<<(std::ostream &os, const FieldTraits &what)
bool operator()(const FieldTrait *p1, const FieldTrait *p2) const
Definition: traits.hpp:177
FieldTrait()=default
Ctor.
iterator find(const FieldTrait what, bool &answer)
Definition: traits.hpp:282
void set(const T sbit, bool on=true)
Definition: f8utils.hpp:886
unsigned short getComp(const unsigned short field, Presence::const_iterator &itr) const
Definition: traits.hpp:618
iterator end()
Definition: f8types.hpp:363
bool is_group(const unsigned short field) const
Definition: traits.hpp:607
std::pair< const_iterator, const_iterator > const_internal_result
Definition: traits.hpp:244
unsigned getval(const unsigned short field)
Definition: traits.hpp:476
FieldType _ftype
Definition: traits.hpp:153
bool is_present(const unsigned short field) const
Definition: traits.hpp:591
void set(const unsigned short field, Presence::const_iterator &itr, FieldTrait::TraitTypes type)
Definition: traits.hpp:524
Fast index lookup for FieldTrait.
Definition: traits.hpp:198