quickfix_ruby 1.14.3.1 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }