quickfix_ruby 1.14.3.1 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/ext/quickfix/Acceptor.h +2 -0
  3. data/ext/quickfix/AtomicCount.h +82 -12
  4. data/ext/quickfix/DOMDocument.h +9 -7
  5. data/ext/quickfix/DataDictionary.cpp +77 -14
  6. data/ext/quickfix/DataDictionary.h +90 -16
  7. data/ext/quickfix/Dictionary.cpp +1 -2
  8. data/ext/quickfix/Exceptions.h +3 -5
  9. data/ext/quickfix/Field.h +83 -32
  10. data/ext/quickfix/FieldConvertors.cpp +93 -0
  11. data/ext/quickfix/FieldConvertors.h +129 -275
  12. data/ext/quickfix/FieldMap.cpp +53 -13
  13. data/ext/quickfix/FieldMap.h +200 -62
  14. data/ext/quickfix/FieldTypes.cpp +10 -10
  15. data/ext/quickfix/FieldTypes.h +293 -44
  16. data/ext/quickfix/FileLog.cpp +6 -10
  17. data/ext/quickfix/FileLog.h +4 -10
  18. data/ext/quickfix/FileStore.cpp +19 -6
  19. data/ext/quickfix/FileStore.h +4 -0
  20. data/ext/quickfix/FixFieldNumbers.h +1462 -1461
  21. data/ext/quickfix/FixFields.h +1462 -1461
  22. data/ext/quickfix/FixValues.h +3230 -3227
  23. data/ext/quickfix/HttpConnection.cpp +1 -1
  24. data/ext/quickfix/Initiator.cpp +7 -1
  25. data/ext/quickfix/Initiator.h +2 -0
  26. data/ext/quickfix/Log.h +6 -12
  27. data/ext/quickfix/Message.cpp +186 -57
  28. data/ext/quickfix/Message.h +109 -47
  29. data/ext/quickfix/MySQLConnection.h +1 -1
  30. data/ext/quickfix/PostgreSQLConnection.h +1 -1
  31. data/ext/quickfix/QuickfixRuby.cpp +79141 -77959
  32. data/ext/quickfix/QuickfixRuby.h +1 -1
  33. data/ext/quickfix/SSLSocketAcceptor.cpp +410 -0
  34. data/ext/quickfix/SSLSocketAcceptor.h +185 -0
  35. data/ext/quickfix/SSLSocketConnection.cpp +427 -0
  36. data/ext/quickfix/SSLSocketConnection.h +206 -0
  37. data/ext/quickfix/SSLSocketInitiator.cpp +485 -0
  38. data/ext/quickfix/SSLSocketInitiator.h +196 -0
  39. data/ext/quickfix/Session.cpp +113 -20
  40. data/ext/quickfix/Session.h +18 -4
  41. data/ext/quickfix/SessionFactory.cpp +10 -3
  42. data/ext/quickfix/SessionSettings.cpp +5 -3
  43. data/ext/quickfix/SessionSettings.h +97 -5
  44. data/ext/quickfix/Settings.cpp +72 -2
  45. data/ext/quickfix/Settings.h +3 -0
  46. data/ext/quickfix/SharedArray.h +140 -6
  47. data/ext/quickfix/SocketConnection.cpp +2 -2
  48. data/ext/quickfix/SocketConnector.cpp +5 -2
  49. data/ext/quickfix/SocketConnector.h +3 -2
  50. data/ext/quickfix/SocketInitiator.cpp +28 -4
  51. data/ext/quickfix/SocketInitiator.h +1 -1
  52. data/ext/quickfix/SocketMonitor.cpp +5 -5
  53. data/ext/quickfix/ThreadedSSLSocketAcceptor.cpp +455 -0
  54. data/ext/quickfix/ThreadedSSLSocketAcceptor.h +217 -0
  55. data/ext/quickfix/ThreadedSSLSocketConnection.cpp +404 -0
  56. data/ext/quickfix/ThreadedSSLSocketConnection.h +189 -0
  57. data/ext/quickfix/ThreadedSSLSocketInitiator.cpp +469 -0
  58. data/ext/quickfix/ThreadedSSLSocketInitiator.h +201 -0
  59. data/ext/quickfix/ThreadedSocketAcceptor.cpp +5 -1
  60. data/ext/quickfix/ThreadedSocketConnection.cpp +8 -2
  61. data/ext/quickfix/ThreadedSocketConnection.h +4 -1
  62. data/ext/quickfix/ThreadedSocketInitiator.cpp +24 -4
  63. data/ext/quickfix/ThreadedSocketInitiator.h +1 -1
  64. data/ext/quickfix/Utility.cpp +23 -1
  65. data/ext/quickfix/Utility.h +28 -2
  66. data/ext/quickfix/UtilitySSL.cpp +1733 -0
  67. data/ext/quickfix/UtilitySSL.h +277 -0
  68. data/ext/quickfix/config-all.h +10 -0
  69. data/ext/quickfix/dirent_windows.h +838 -0
  70. data/ext/quickfix/double-conversion/bignum-dtoa.cc +641 -0
  71. data/ext/quickfix/double-conversion/bignum-dtoa.h +84 -0
  72. data/ext/quickfix/double-conversion/bignum.cc +766 -0
  73. data/ext/quickfix/double-conversion/bignum.h +144 -0
  74. data/ext/quickfix/double-conversion/cached-powers.cc +176 -0
  75. data/ext/quickfix/double-conversion/cached-powers.h +64 -0
  76. data/ext/quickfix/double-conversion/diy-fp.cc +57 -0
  77. data/ext/quickfix/double-conversion/diy-fp.h +118 -0
  78. data/ext/quickfix/double-conversion/double-conversion.cc +994 -0
  79. data/ext/quickfix/double-conversion/double-conversion.h +543 -0
  80. data/ext/quickfix/double-conversion/fast-dtoa.cc +665 -0
  81. data/ext/quickfix/double-conversion/fast-dtoa.h +88 -0
  82. data/ext/quickfix/double-conversion/fixed-dtoa.cc +404 -0
  83. data/ext/quickfix/double-conversion/fixed-dtoa.h +56 -0
  84. data/ext/quickfix/double-conversion/ieee.h +402 -0
  85. data/ext/quickfix/double-conversion/strtod.cc +557 -0
  86. data/ext/quickfix/double-conversion/strtod.h +45 -0
  87. data/ext/quickfix/double-conversion/utils.h +372 -0
  88. data/ext/quickfix/stdint_msvc.h +254 -0
  89. data/lib/quickfix44.rb +3329 -10
  90. data/lib/quickfix50.rb +6649 -81
  91. data/lib/quickfix50sp1.rb +8054 -142
  92. data/lib/quickfix50sp2.rb +10900 -234
  93. data/lib/quickfix_fields.rb +7662 -7649
  94. data/spec/FIX40.xml +28 -28
  95. data/spec/FIX41.xml +29 -29
  96. data/spec/FIX42.xml +47 -47
  97. data/spec/FIX43.xml +148 -148
  98. data/spec/FIX44.xml +1078 -1081
  99. data/spec/FIX50.xml +1292 -1289
  100. data/spec/FIX50SP1.xml +1811 -1802
  101. data/spec/FIX50SP2.xml +1948 -1939
  102. data/spec/FIXT11.xml +5 -8
  103. data/test/test_FieldBaseTestCase.rb +1 -1
  104. data/test/test_MessageTestCase.rb +2 -2
  105. metadata +42 -6
@@ -30,6 +30,30 @@
30
30
 
31
31
  namespace FIX
32
32
  {
33
+
34
+ FieldMap::FieldMap( const message_order& order, int size )
35
+ : m_order(order)
36
+ {
37
+ m_fields.reserve(size);
38
+ }
39
+
40
+ FieldMap::FieldMap( const message_order& order /*= message_order(message_order::normal)*/)
41
+ : m_order(order)
42
+ {
43
+ m_fields.reserve(DEFAULT_SIZE);
44
+ }
45
+
46
+ FieldMap::FieldMap( const int order[] )
47
+ : m_order(message_order(order))
48
+ {
49
+ m_fields.reserve(DEFAULT_SIZE);
50
+ }
51
+
52
+ FieldMap::FieldMap( const FieldMap& copy )
53
+ {
54
+ *this = copy;
55
+ }
56
+
33
57
  FieldMap::~FieldMap()
34
58
  {
35
59
  clear();
@@ -40,6 +64,7 @@ FieldMap& FieldMap::operator=( const FieldMap& rhs )
40
64
  clear();
41
65
 
42
66
  m_fields = rhs.m_fields;
67
+ m_order = rhs.m_order;
43
68
 
44
69
  Groups::const_iterator i;
45
70
  for ( i = rhs.m_groups.begin(); i != rhs.m_groups.end(); ++i )
@@ -99,24 +124,38 @@ void FieldMap::removeGroup( int num, int field )
99
124
 
100
125
  if( vector.size() == 0 )
101
126
  {
102
- m_groups.erase( field );
127
+ m_groups.erase( i );
103
128
  removeField( field );
104
129
  }
105
130
  else
106
131
  {
107
132
  IntField groupCount( field, (int)vector.size() );
108
- setField( groupCount, true );
133
+ setField( groupCount );
109
134
  }
110
135
  }
111
136
 
112
137
  void FieldMap::removeGroup( int field )
113
138
  {
114
- removeGroup( (int)groupCount(field), field );
139
+ Groups::iterator i = m_groups.find( field );
140
+ if ( i == m_groups.end() ) return;
141
+
142
+ removeField( field );
143
+
144
+ std::vector< FieldMap* > tmp;
145
+ tmp.swap( i->second );
146
+
147
+ m_groups.erase( i );
148
+
149
+ while ( !tmp.empty() )
150
+ {
151
+ delete tmp.back();
152
+ tmp.pop_back();
153
+ }
115
154
  }
116
155
 
117
156
  void FieldMap::removeField( int field )
118
157
  {
119
- Fields::iterator i = m_fields.find( field );
158
+ Fields::iterator i = findTag( field );
120
159
  if ( i != m_fields.end() )
121
160
  m_fields.erase( i );
122
161
  }
@@ -156,7 +195,7 @@ void FieldMap::clear()
156
195
 
157
196
  bool FieldMap::isEmpty()
158
197
  {
159
- return m_fields.size() == 0;
198
+ return m_fields.empty();
160
199
  }
161
200
 
162
201
  size_t FieldMap::totalFields() const
@@ -178,11 +217,11 @@ std::string& FieldMap::calculateString( std::string& result ) const
178
217
  Fields::const_iterator i;
179
218
  for ( i = m_fields.begin(); i != m_fields.end(); ++i )
180
219
  {
181
- result += i->second.getFixString();
220
+ result += i->getFixString();
182
221
 
183
222
  // add groups if they exist
184
223
  if( !m_groups.size() ) continue;
185
- Groups::const_iterator j = m_groups.find( i->first );
224
+ Groups::const_iterator j = m_groups.find( i->getTag() );
186
225
  if ( j == m_groups.end() ) continue;
187
226
  std::vector < FieldMap* > ::const_iterator k;
188
227
  for ( k = j->second.begin(); k != j->second.end(); ++k )
@@ -199,10 +238,11 @@ int FieldMap::calculateLength( int beginStringField,
199
238
  Fields::const_iterator i;
200
239
  for ( i = m_fields.begin(); i != m_fields.end(); ++i )
201
240
  {
202
- if ( i->first != beginStringField
203
- && i->first != bodyLengthField
204
- && i->first != checkSumField )
205
- { result += i->second.getLength(); }
241
+ int tag = i->getTag();
242
+ if ( tag != beginStringField
243
+ && tag != bodyLengthField
244
+ && tag != checkSumField )
245
+ { result += i->getLength(); }
206
246
  }
207
247
 
208
248
  Groups::const_iterator j;
@@ -221,8 +261,8 @@ int FieldMap::calculateTotal( int checkSumField ) const
221
261
  Fields::const_iterator i;
222
262
  for ( i = m_fields.begin(); i != m_fields.end(); ++i )
223
263
  {
224
- if ( i->first != checkSumField )
225
- result += i->second.getTotal();
264
+ if ( i->getTag() != checkSumField )
265
+ result += i->getTotal();
226
266
  }
227
267
 
228
268
  Groups::const_iterator j;
@@ -45,31 +45,68 @@ namespace FIX
45
45
  */
46
46
  class FieldMap
47
47
  {
48
+
49
+ class sorter
50
+ {
51
+ public:
52
+ explicit sorter( const message_order& order ) : m_order( order ) {}
53
+
54
+ bool operator()( int tag, const FieldBase& right ) const
55
+ {
56
+ return m_order( tag, right.getTag() );
57
+ }
58
+
59
+ bool operator()( const FieldBase& left, int tag ) const
60
+ {
61
+ return m_order( left.getTag(), tag );
62
+ }
63
+
64
+ bool operator()( const FieldBase& left, const FieldBase& right ) const
65
+ {
66
+ return m_order( left.getTag(), right.getTag() );
67
+ }
68
+
69
+ private:
70
+ const message_order& m_order;
71
+ };
72
+
73
+ class finder
74
+ {
75
+ public:
76
+ explicit finder( int tag ) : m_tag( tag ) {}
77
+
78
+ bool operator()( const FieldBase& field ) const
79
+ {
80
+ return m_tag == field.getTag();
81
+ }
82
+
83
+ private:
84
+ int m_tag;
85
+ };
86
+
87
+ enum { DEFAULT_SIZE = 16 };
88
+
89
+ protected:
90
+
91
+ FieldMap( const message_order& order, int size );
92
+
48
93
  public:
49
- #if defined(_MSC_VER) && _MSC_VER < 1300
50
- typedef std::multimap < int, FieldBase, message_order > Fields;
51
- typedef std::map < int, std::vector < FieldMap* >, std::less<int> > Groups;
52
- #else
53
- typedef std::multimap < int, FieldBase, message_order,
54
- ALLOCATOR<std::pair<const int,FieldBase> > > Fields;
55
- typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
94
+
95
+ typedef std::vector < FieldBase, ALLOCATOR< FieldBase > > Fields;
96
+ typedef std::map < int, std::vector < FieldMap* >, std::less<int>,
56
97
  ALLOCATOR<std::pair<const int, std::vector< FieldMap* > > > > Groups;
57
- #endif
58
98
 
59
- typedef Fields::const_iterator iterator;
60
- typedef iterator const_iterator;
61
- typedef Groups::const_iterator g_iterator;
99
+ typedef Fields::iterator iterator;
100
+ typedef Fields::const_iterator const_iterator;
101
+ typedef Groups::iterator g_iterator;
62
102
  typedef Groups::const_iterator g_const_iterator;
63
103
 
64
104
  FieldMap( const message_order& order =
65
- message_order( message_order::normal ) )
66
- : m_fields( order ) {}
105
+ message_order( message_order::normal ) );
67
106
 
68
- FieldMap( const int order[] )
69
- : m_fields( message_order(order) ) {}
107
+ FieldMap( const int order[] );
70
108
 
71
- FieldMap( const FieldMap& copy )
72
- { *this = copy; }
109
+ FieldMap( const FieldMap& copy );
73
110
 
74
111
  virtual ~FieldMap();
75
112
 
@@ -79,32 +116,39 @@ public:
79
116
  void setField( const FieldBase& field, bool overwrite = true )
80
117
  throw( RepeatedTag )
81
118
  {
82
- if(!overwrite)
83
- m_fields.insert( Fields::value_type( field.getField(), field ) );
119
+ if( !overwrite )
120
+ {
121
+ addField( field );
122
+ }
123
+ else
124
+ {
125
+ Fields::iterator i = findTag( field.getTag() );
126
+ if( i == m_fields.end() )
127
+ {
128
+ addField( field );
129
+ }
84
130
  else
85
131
  {
86
- Fields::iterator i = m_fields.find( field.getField() );
87
- if( i == m_fields.end() )
88
- m_fields.insert( Fields::value_type( field.getField(), field ) );
89
- else
90
- i->second = field;
132
+ i->setString( field.getString() );
91
133
  }
134
+ }
92
135
  }
136
+
93
137
  /// Set a field without a field class
94
- void setField( int field, const std::string& value )
138
+ void setField( int tag, const std::string& value )
95
139
  throw( RepeatedTag, NoTagValue )
96
140
  {
97
- FieldBase fieldBase( field, value );
141
+ FieldBase fieldBase( tag, value );
98
142
  setField( fieldBase );
99
143
  }
100
144
 
101
145
  /// Get a field if set
102
146
  bool getFieldIfSet( FieldBase& field ) const
103
147
  {
104
- Fields::const_iterator iter = m_fields.find( field.getField() );
148
+ Fields::const_iterator iter = findTag( field.getTag() );
105
149
  if ( iter == m_fields.end() )
106
150
  return false;
107
- field = iter->second;
151
+ field = (*iter);
108
152
  return true;
109
153
  }
110
154
 
@@ -112,89 +156,89 @@ public:
112
156
  FieldBase& getField( FieldBase& field )
113
157
  const throw( FieldNotFound )
114
158
  {
115
- field = getFieldRef( field.getField() );
159
+ field = getFieldRef( field.getTag() );
116
160
  return field;
117
161
  }
118
162
 
119
163
  /// Get a field without a field class
120
- const std::string& getField( int field )
164
+ const std::string& getField( int tag )
121
165
  const throw( FieldNotFound )
122
166
  {
123
- return getFieldRef( field ).getString();
167
+ return getFieldRef( tag ).getString();
124
168
  }
125
169
 
126
170
  /// Get direct access to a field through a reference
127
- const FieldBase& getFieldRef( int field )
171
+ const FieldBase& getFieldRef( int tag )
128
172
  const throw( FieldNotFound )
129
173
  {
130
- Fields::const_iterator iter = m_fields.find( field );
174
+ Fields::const_iterator iter = findTag( tag );
131
175
  if ( iter == m_fields.end() )
132
- throw FieldNotFound( field );
133
- return iter->second;
176
+ throw FieldNotFound( tag );
177
+ return (*iter);
134
178
  }
135
179
 
136
180
  /// Get direct access to a field through a pointer
137
- const FieldBase* const getFieldPtr( int field )
181
+ const FieldBase* const getFieldPtr( int tag )
138
182
  const throw( FieldNotFound )
139
183
  {
140
- return &getFieldRef( field );
184
+ return &getFieldRef( tag );
141
185
  }
142
186
 
143
187
  /// Check to see if a field is set
144
188
  bool isSetField( const FieldBase& field ) const
145
- { return isSetField( field.getField() ); }
189
+ { return isSetField( field.getTag() ); }
146
190
  /// Check to see if a field is set by referencing its number
147
- bool isSetField( int field ) const
148
- { return m_fields.find( field ) != m_fields.end(); }
191
+ bool isSetField( int tag ) const
192
+ { return findTag( tag ) != m_fields.end(); }
149
193
 
150
194
  /// Remove a field. If field is not present, this is a no-op.
151
- void removeField( int field );
195
+ void removeField( int tag );
152
196
 
153
197
  /// Add a group.
154
- void addGroup( int field, const FieldMap& group, bool setCount = true );
198
+ void addGroup( int tag, const FieldMap& group, bool setCount = true );
155
199
 
156
200
  /// Acquire ownership of Group object
157
- void addGroupPtr( int field, FieldMap * group, bool setCount = true );
201
+ void addGroupPtr( int tag, FieldMap * group, bool setCount = true );
158
202
 
159
203
  /// Replace a specific instance of a group.
160
- void replaceGroup( int num, int field, const FieldMap& group );
204
+ void replaceGroup( int num, int tag, const FieldMap& group );
161
205
 
162
206
  /// Get a specific instance of a group.
163
- FieldMap& getGroup( int num, int field, FieldMap& group ) const
207
+ FieldMap& getGroup( int num, int tag, FieldMap& group ) const
164
208
  throw( FieldNotFound )
165
209
  {
166
- return group = getGroupRef( num, field );
210
+ return group = getGroupRef( num, tag );
167
211
  }
168
212
 
169
213
  /// Get direct access to a field through a reference
170
- FieldMap& getGroupRef( int num, int field ) const
214
+ FieldMap& getGroupRef( int num, int tag ) const
171
215
  throw( FieldNotFound )
172
216
  {
173
- Groups::const_iterator i = m_groups.find( field );
174
- if( i == m_groups.end() ) throw FieldNotFound( field );
175
- if( num <= 0 ) throw FieldNotFound( field );
176
- if( i->second.size() < (unsigned)num ) throw FieldNotFound( field );
217
+ Groups::const_iterator i = m_groups.find( tag );
218
+ if( i == m_groups.end() ) throw FieldNotFound( tag );
219
+ if( num <= 0 ) throw FieldNotFound( tag );
220
+ if( i->second.size() < (unsigned)num ) throw FieldNotFound( tag );
177
221
  return *( *(i->second.begin() + (num-1) ) );
178
222
  }
179
223
 
180
224
  /// Get direct access to a field through a pointer
181
- FieldMap* getGroupPtr( int num, int field ) const
225
+ FieldMap* getGroupPtr( int num, int tag ) const
182
226
  throw( FieldNotFound )
183
227
  {
184
- return &getGroupRef( num, field );
228
+ return &getGroupRef( num, tag );
185
229
  }
186
230
 
187
231
  /// Remove a specific instance of a group.
188
- void removeGroup( int num, int field );
232
+ void removeGroup( int num, int tag );
189
233
  /// Remove all instances of a group.
190
- void removeGroup( int field );
234
+ void removeGroup( int tag );
191
235
 
192
236
  /// Check to see any instance of a group exists
193
- bool hasGroup( int field ) const;
237
+ bool hasGroup( int tag ) const;
194
238
  /// Check to see if a specific instance of a group exists
195
- bool hasGroup( int num, int field ) const;
239
+ bool hasGroup( int num, int tag ) const;
196
240
  /// Count the number of instance of a group
197
- size_t groupCount( int field ) const;
241
+ size_t groupCount( int tag ) const;
198
242
 
199
243
  /// Clear all fields from the map
200
244
  void clear();
@@ -211,14 +255,108 @@ public:
211
255
 
212
256
  int calculateTotal( int checkSumField = FIELD::CheckSum ) const;
213
257
 
214
- iterator begin() const { return m_fields.begin(); }
215
- iterator end() const { return m_fields.end(); }
216
- g_iterator g_begin() const { return m_groups.begin(); }
217
- g_iterator g_end() const { return m_groups.end(); }
258
+ iterator begin() { return m_fields.begin(); }
259
+ iterator end() { return m_fields.end(); }
260
+ const_iterator begin() const { return m_fields.begin(); }
261
+ const_iterator end() const { return m_fields.end(); }
262
+ g_iterator g_begin() { return m_groups.begin(); }
263
+ g_iterator g_end() { return m_groups.end(); }
264
+ g_const_iterator g_begin() const { return m_groups.begin(); }
265
+ g_const_iterator g_end() const { return m_groups.end(); }
266
+
267
+ protected:
268
+
269
+ friend class Message;
270
+
271
+ void addField( const FieldBase& field )
272
+ {
273
+ Fields::iterator iter = findPositionFor( field.getTag() );
274
+ if( iter == m_fields.end() )
275
+ {
276
+ m_fields.push_back( field );
277
+ }
278
+ else
279
+ {
280
+ m_fields.insert( iter, field );
281
+ }
282
+ }
283
+
284
+ // used to find data length fields during message decoding
285
+ // message fields are not yet sorted so regular find*** functions might return wrong results
286
+ const FieldBase& reverse_find( int tag ) const
287
+ {
288
+ Fields::const_reverse_iterator iter = std::find_if( m_fields.rbegin(), m_fields.rend(), finder( tag ) );
289
+ if( iter == m_fields.rend() )
290
+ throw FieldNotFound( tag );
291
+
292
+ return *iter;
293
+ }
294
+
295
+ // append field to message without sorting
296
+ // only applicable during message decoding
297
+ void appendField( const FieldBase& field )
298
+ {
299
+ m_fields.push_back( field );
300
+ }
301
+
302
+ // sort fields after message decoding
303
+ void sortFields()
304
+ {
305
+ std::sort( m_fields.begin(), m_fields.end(), sorter(m_order) );
306
+ }
218
307
 
219
308
  private:
309
+
310
+ Fields::const_iterator findTag( int tag ) const
311
+ {
312
+ return lookup( m_fields.begin(), m_fields.end(), tag );
313
+ }
314
+
315
+ Fields::iterator findTag( int tag )
316
+ {
317
+ return lookup( m_fields.begin(), m_fields.end(), tag );
318
+ }
319
+
320
+ template <typename Iterator>
321
+ Iterator lookup(Iterator begin, Iterator end, int tag) const
322
+ {
323
+ #if defined(__SUNPRO_CC)
324
+ std::size_t numElements;
325
+ std::distance( begin, end, numElements );
326
+ #else
327
+ std::size_t numElements = std::distance( begin, end );
328
+ #endif
329
+ if( numElements < 16 )
330
+ return std::find_if( begin, end, finder( tag ) );
331
+
332
+ Iterator iter = std::lower_bound( begin, end, tag, sorter( m_order ) );
333
+ if( iter != end &&
334
+ iter->getTag() == tag )
335
+ {
336
+ return iter;
337
+ }
338
+
339
+ return end;
340
+ }
341
+
342
+ Fields::iterator findPositionFor( int tag )
343
+ {
344
+ if( m_fields.empty() )
345
+ return m_fields.end();
346
+
347
+ const FieldBase& last = m_fields.back();
348
+ if( m_order( last.getTag(), tag ) ||
349
+ last.getTag() == tag )
350
+ {
351
+ return m_fields.end();
352
+ }
353
+
354
+ return std::upper_bound( m_fields.begin(), m_fields.end(), tag, sorter( m_order ) );
355
+ }
356
+
220
357
  Fields m_fields;
221
358
  Groups m_groups;
359
+ message_order m_order;
222
360
  };
223
361
  /*! @} */
224
362
  }