NCBI C++ ToolKit
sequence_util_macros.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef OBJECTS_MISC___SEQUENCE_UTIL_MACROS__HPP
2 #define OBJECTS_MISC___SEQUENCE_UTIL_MACROS__HPP
3 
4 /* $Id: sequence_util_macros.hpp 76016 2017-01-06 14:10:35Z kornbluh $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Jonathan Kans, Michael Kornbluh, Colleen Bollin
30  *
31  */
32 
33 /// @file sequence_util_macros.hpp
34 /// Generic utility macros and templates for exploring NCBI objects.
35 
36 
37 #include <serial/iterator.hpp>
38 
39 
40 /// @NAME Convenience macros for NCBI objects
41 /// @{
42 
43 
46 
47 
48 /// NCBI_SERIAL_TEST_EXPLORE base macro tests to see if loop should be entered
49 // If okay, calls CTypeConstIterator for recursive exploration
50 
51 #define NCBI_SERIAL_TEST_EXPLORE(Test, Type, Var, Cont) \
52 if (! (Test)) {} else for (CTypeConstIterator<Type> Var (Cont); Var; ++Var)
53 
54 #define NCBI_SERIAL_NC_EXPLORE(Test, Type, Var, Cont) \
55 if (! (Test)) {} else for (CTypeIterator<Type> Var (Cont); Var; ++Var)
56 
57 
58 /////////////////////////////////////////////////////////////////////////////
59 /// Macros to iterate over standard template containers (non-recursive)
60 /////////////////////////////////////////////////////////////////////////////
61 
62 
63 /// NCBI_CS_ITERATE base macro tests to see if loop should be entered
64 // If okay, calls ITERATE for linear STL iteration
65 
66 #define NCBI_CS_ITERATE(Test, Type, Var, Cont) \
67 if (! (Test)) {} else ITERATE (Type, Var, Cont)
68 
69 /// NCBI_NC_ITERATE base macro tests to see if loop should be entered
70 // If okay, calls ERASE_ITERATE for linear STL iteration
71 
72 #define NCBI_NC_ITERATE(Test, Type, Var, Cont) \
73 if (! (Test)) {} else ERASE_ITERATE (Type, Var, Cont)
74 
75 /// NCBI_SWITCH base macro tests to see if switch should be performed
76 // If okay, calls switch statement
77 
78 #define NCBI_SWITCH(Test, Chs) \
79 if (! (Test)) {} else switch(Chs)
80 
81 
82 /// FOR_EACH base macro calls NCBI_CS_ITERATE with generated components
83 
84 #define FOR_EACH(Base, Itr, Var) \
85 NCBI_CS_ITERATE (Base##_Test(Var), Base##_Type, Itr, Base##_Get(Var))
86 
87 /// EDIT_EACH base macro calls NCBI_NC_ITERATE with generated components
88 
89 #define EDIT_EACH(Base, Itr, Var) \
90 NCBI_NC_ITERATE (Base##_Test(Var), Base##_Type, Itr, Base##_Set(Var))
91 
92 /// ADD_ITEM base macro
93 
94 #define ADD_ITEM(Base, Var, Ref) \
95 (Base##_Set(Var).push_back(Ref))
96 
97 /// LIST_ERASE_ITEM base macro
98 
99 #define LIST_ERASE_ITEM(Base, Itr, Var) \
100 (Base##_Set(Var).erase(Itr))
101 
102 /// VECTOR_ERASE_ITEM base macro
103 
104 #define VECTOR_ERASE_ITEM(Base, Itr, Var) \
105 (VECTOR_ERASE (Itr, Base##_Set(Var)))
106 
107 /// ITEM_HAS base macro
108 
109 #define ITEM_HAS(Base, Var) \
110 (Base##_Test(Var))
111 
112 /// FIELD_IS_EMPTY base macro
113 
114 #define FIELD_IS_EMPTY(Base, Var) \
115  (Base##_Test(Var) && Base##_Get(Var).empty() )
116 
117 /// RAW_FIELD_IS_EMPTY base macro
118 
119 #define RAW_FIELD_IS_EMPTY(Var, Fld) \
120  ( (Var).IsSet##Fld() && (Var).Get##Fld().empty() )
121 
122 /// FIELD_IS_EMPTY_OR_UNSET base macro
123 
124 #define FIELD_IS_EMPTY_OR_UNSET(Base, Var) \
125  ( ! Base##_Test(Var) || Base##_Get(Var).empty() )
126 
127 /// RAW_FIELD_IS_EMPTY_OR_UNSET macro
128 
129 #define RAW_FIELD_IS_EMPTY_OR_UNSET(Var, Fld) \
130  ( ! (Var).IsSet##Fld() || (Var).Get##Fld().empty() )
131 
132 /// RAW_FIELD_GET_SIZE_IF_SET
133 
134 // returns the size of the field if it's set; else zero.
135 #define RAW_FIELD_GET_SIZE_IF_SET(Var, Fld) \
136  ( (Var).IsSet##Fld() ? (Var).Get##Fld().size() : 0 )
137 
138 /// SET_FIELD_IF_UNSET macro
139 
140 // (The do-while is just so the user has to put a semi-colon after it)
141 #define SET_FIELD_IF_UNSET(Var, Fld, Val) \
142  do { if( ! (Var).IsSet##Fld() ) { (Var).Set##Fld(Val); ChangeMade(CCleanupChange::eChangeQualifiers); } } while(false)
143 
144 /// RESET_FIELD_IF_EMPTY base macro
145 
146 // (The do-while is just so the user has to put a semi-colon after it)
147 #define REMOVE_IF_EMPTY_FIELD(Base, Var) \
148  do { if( FIELD_IS_EMPTY(Base, Var) ) { Base##_Reset(Var); ChangeMade(CCleanupChange::eChangeQualifiers); } } while(false)
149 
150 /// GET_STRING_OR_BLANK base macro
151 
152 #define GET_STRING_OR_BLANK(Base, Var) \
153  (Base##_Test(Var) ? Base##_Get(Var) : kEmptyStr )
154 
155 /// CHOICE_IS base macro
156 
157 #define CHOICE_IS(Base, Var, Chs) \
158 (Base##_Test(Var) && Base##_Chs(Var) == Chs)
159 
160 
161 /// SWITCH_ON base macro calls NCBI_SWITCH with generated components
162 
163 #define SWITCH_ON(Base, Var) \
164 NCBI_SWITCH (Base##_Test(Var), Base##_Chs(Var))
165 
166 
167 // is_sorted template
168 
169 template <class Iter, class Comp>
170 bool seq_mac_is_sorted(Iter first, Iter last, Comp comp)
171 {
172  if (first == last)
173  return true;
174 
175  Iter next = first;
176  for (++next; next != last; first = next, ++next) {
177  if (comp(*next, *first))
178  return false;
179  }
180 
181  return true;
182 }
183 
184 
185 // is_unique template assumes that the container is already sorted
186 
187 template <class Iterator, class Predicate>
188 bool seq_mac_is_unique(Iterator iter1, Iterator iter2, Predicate pred)
189 {
190  Iterator prev = iter1;
191  if (iter1 == iter2) {
192  return true;
193  }
194  for (++iter1; iter1 != iter2; ++iter1, ++prev) {
195  if (pred(*iter1, *prev)) {
196  return false;
197  }
198  }
199  return true;
200 }
201 
202 
203 /// IS_SORTED base macro
204 
205 #define IS_SORTED(Base, Var, Func) \
206 ((! Base##_Test(Var)) || \
207 seq_mac_is_sorted (Base##_Set(Var).begin(), \
208  Base##_Set(Var).end(), \
209  Func))
210 
211 /// DO_LIST_SORT base macro
212 
213 #define DO_LIST_SORT(Base, Var, Func) \
214 (Base##_Set(Var).sort (Func))
215 
216 /// DO_VECTOR_SORT base macro
217 
218 #define DO_VECTOR_SORT(Base, Var, Func) \
219 (stable_sort (Base##_Set(Var).begin(), \
220  Base##_Set(Var).end(), \
221  Func))
222 
223 /// DO_LIST_SORT_HACK base macro
224 
225 // This is more complex than some of the others
226 // to get around the WorkShop compiler's lack of support
227 // for member template functions.
228 // This should only be needed when you're sorting
229 // by a function object rather than a plain function.
230 #define DO_LIST_SORT_HACK(Base, Var, Func) \
231  do { \
232  vector< Base##_Type::value_type > vec; \
233  copy( Base##_Get(Var).begin(), Base##_Get(Var).end(), back_inserter(vec) ); \
234  stable_sort( vec.begin(), vec.end(), Func ); \
235  Base##_Set(Var).clear(); \
236  copy( vec.begin(), vec.end(), back_inserter(Base##_Set(Var)) ); \
237  } while(false) // The purpose of the one-time do-while is to force a semicolon
238 
239 
240 /// IS_UNIQUE base macro
241 
242 #define IS_UNIQUE(Base, Var, Func) \
243 ((! Base##_Test(Var)) || \
244 seq_mac_is_unique (Base##_Set(Var).begin(), \
245  Base##_Set(Var).end(), \
246  Func))
247 
248 /// DO_UNIQUE base macro
249 
250 #define DO_UNIQUE(Base, Var, Func) \
251 { \
252  Base##_Type::iterator it = unique (Base##_Set(Var).begin(), \
253  Base##_Set(Var).end(), \
254  Func); \
255  it = Base##_Set(Var).erase(it, Base##_Set(Var).end()); \
256 }
257 
258 // keeps only the first of all the ones that match
259 #define UNIQUE_WITHOUT_SORT(Base, Var, FuncType, CleanupChangeType) \
260 { \
261  if( Base##_Test(Var) ) { \
262  set<Base##_Type::value_type, FuncType> valuesAlreadySeen; \
263  Base##_Type non_duplicate_items; \
264  FOR_EACH(Base, iter, Var ) { \
265  if( valuesAlreadySeen.find(*iter) == valuesAlreadySeen.end() ) { \
266  non_duplicate_items.push_back( *iter ); \
267  valuesAlreadySeen.insert( *iter ); \
268  } \
269  } \
270  if( Base##_Get(Var).size() != non_duplicate_items.size() ) { \
271  ChangeMade(CleanupChangeType); \
272  } \
273  Base##_Set(Var).swap( non_duplicate_items ); \
274  } \
275 }
276 
277 // careful of side effects
278 #define BEGIN_COMMA_END(container) \
279  (container).begin(), (container).end()
280 
281 
282 // "FOR_EACH_XXX_ON_YYY" does a linear const traversal of STL containers
283 // "EDIT_EACH_XXX_ON_YYY" does a linear non-const traversal of STL containers
284 
285 // "SWITCH_ON_XXX_CHOICE" switches on the item subtype
286 
287 // "ADD_XXX_TO_YYY" adds an element to a specified object
288 // "ERASE_XXX_ON_YYY" deletes a specified object within an iterator
289 
290 // Miscellaneous macros for testing objects include
291 // "XXX_IS_YYY" or "XXX_HAS_YYY"
292 // "XXX_CHOICE_IS"
293 
294 
295 ///
296 /// list <string> macros
297 
298 /// STRING_IN_LIST macros
299 
300 #define STRING_IN_LIST_Type list <string>
301 #define STRING_IN_LIST_Test(Var) (! (Var).empty())
302 #define STRING_IN_LIST_Get(Var) (Var)
303 #define STRING_IN_LIST_Set(Var) (Var)
304 
305 /// LIST_HAS_STRING
306 
307 #define LIST_HAS_STRING(Var) \
308 ITEM_HAS (STRING_IN_LIST, Var)
309 
310 /// FOR_EACH_STRING_IN_LIST
311 /// EDIT_EACH_STRING_IN_LIST
312 // list <string>& as input, dereference with [const] string& str = *itr;
313 
314 #define FOR_EACH_STRING_IN_LIST(Itr, Var) \
315 FOR_EACH (STRING_IN_LIST, Itr, Var)
316 
317 #define EDIT_EACH_STRING_IN_LIST(Itr, Var) \
318 EDIT_EACH (STRING_IN_LIST, Itr, Var)
319 
320 /// ADD_STRING_TO_LIST
321 
322 #define ADD_STRING_TO_LIST(Var, Ref) \
323 ADD_ITEM (STRING_IN_LIST, Var, Ref)
324 
325 /// ERASE_STRING_IN_LIST
326 
327 #define ERASE_STRING_IN_LIST(Itr, Var) \
328 LIST_ERASE_ITEM (STRING_IN_LIST, Itr, Var)
329 
330 /// STRING_IN_LIST_IS_SORTED
331 
332 #define STRING_IN_LIST_IS_SORTED(Var, Func) \
333 IS_SORTED (STRING_IN_LIST, Var, Func)
334 
335 /// SORT_STRING_IN_LIST
336 
337 #define SORT_STRING_IN_LIST(Var, Func) \
338 DO_LIST_SORT (STRING_IN_LIST, Var, Func)
339 
340 /// STRING_IN_LIST_IS_UNIQUE
341 
342 #define STRING_IN_LIST_IS_UNIQUE(Var, Func) \
343 IS_UNIQUE (STRING_IN_LIST, Var, Func)
344 
345 /// UNIQUE_STRING_IN_LIST
346 
347 #define UNIQUE_STRING_IN_LIST(Var, Func) \
348 DO_UNIQUE (STRING_IN_LIST, Var, Func)
349 
350 
351 ///
352 /// vector <string> macros
353 
354 /// STRING_IN_VECTOR macros
355 
356 #define STRING_IN_VECTOR_Type vector <string>
357 #define STRING_IN_VECTOR_Test(Var) (! (Var).empty())
358 #define STRING_IN_VECTOR_Get(Var) (Var)
359 #define STRING_IN_VECTOR_Set(Var) (Var)
360 
361 /// VECTOR_HAS_STRING
362 
363 #define VECTOR_HAS_STRING(Var) \
364 ITEM_HAS (STRING_IN_VECTOR, Var)
365 
366 /// FOR_EACH_STRING_IN_VECTOR
367 /// EDIT_EACH_STRING_IN_VECTOR
368 // vector <string>& as input, dereference with [const] string& str = *itr;
369 
370 #define FOR_EACH_STRING_IN_VECTOR(Itr, Var) \
371 FOR_EACH (STRING_IN_VECTOR, Itr, Var)
372 
373 #define EDIT_EACH_STRING_IN_VECTOR(Itr, Var) \
374 EDIT_EACH (STRING_IN_VECTOR, Itr, Var)
375 
376 /// ADD_STRING_TO_VECTOR
377 
378 #define ADD_STRING_TO_VECTOR(Var, Ref) \
379 ADD_ITEM (STRING_IN_VECTOR, Var, Ref)
380 
381 /// ERASE_STRING_IN_VECTOR
382 
383 #define ERASE_STRING_IN_VECTOR(Itr, Var) \
384 VECTOR_ERASE_ITEM (STRING_IN_VECTOR, Itr, Var)
385 
386 /// STRING_IN_VECTOR_IS_SORTED
387 
388 #define STRING_IN_VECTOR_IS_SORTED(Var, Func) \
389 IS_SORTED (STRING_IN_VECTOR, Var, Func)
390 
391 /// SORT_STRING_IN_VECTOR
392 
393 #define SORT_STRING_IN_VECTOR(Var, Func) \
394 DO_VECTOR_SORT (STRING_IN_VECTOR, Var, Func)
395 
396 /// STRING_IN_VECTOR_IS_UNIQUE
397 
398 #define STRING_IN_VECTOR_IS_UNIQUE(Var, Func) \
399 IS_UNIQUE (STRING_IN_VECTOR, Var, Func)
400 
401 /// UNIQUE_STRING_IN_VECTOR
402 
403 #define UNIQUE_STRING_IN_VECTOR(Var, Func) \
404 DO_UNIQUE (STRING_IN_VECTOR, Var, Func)
405 
406 
407 ///
408 /// <string> macros
409 
410 /// CHAR_IN_STRING macros
411 
412 #define CHAR_IN_STRING_Type string
413 #define CHAR_IN_STRING_Test(Var) (! (Var).empty())
414 #define CHAR_IN_STRING_Get(Var) (Var)
415 #define CHAR_IN_STRING_Set(Var) (Var)
416 
417 /// STRING_HAS_CHAR
418 
419 #define STRING_HAS_CHAR(Var) \
420 ITEM_HAS (CHAR_IN_STRING, Var)
421 
422 /// FOR_EACH_CHAR_IN_STRING
423 /// EDIT_EACH_CHAR_IN_STRING
424 // string& as input, dereference with [const] char& ch = *itr;
425 
426 #define FOR_EACH_CHAR_IN_STRING(Itr, Var) \
427 FOR_EACH (CHAR_IN_STRING, Itr, Var)
428 
429 #define EDIT_EACH_CHAR_IN_STRING(Itr, Var) \
430 EDIT_EACH (CHAR_IN_STRING, Itr, Var)
431 
432 /// ADD_CHAR_TO_STRING
433 
434 #define ADD_CHAR_TO_STRING(Var, Ref) \
435 ADD_ITEM (CHAR_IN_STRING, Var, Ref)
436 
437 /// ERASE_CHAR_IN_STRING
438 
439 #define ERASE_CHAR_IN_STRING(Itr, Var) \
440 LIST_ERASE_ITEM (CHAR_IN_STRING, Itr, Var)
441 
442 /// CHAR_IN_STRING_IS_SORTED
443 
444 #define CHAR_IN_STRING_IS_SORTED(Var, Func) \
445 IS_SORTED (CHAR_IN_STRING, Var, Func)
446 
447 /// SORT_CHAR_IN_STRING
448 
449 #define SORT_CHAR_IN_STRING(Var, Func) \
450 DO_LIST_SORT (CHAR_IN_STRING, Var, Func)
451 
452 /// CHAR_IN_STRING_IS_UNIQUE
453 
454 #define CHAR_IN_STRING_IS_UNIQUE(Var, Func) \
455 IS_UNIQUE (CHAR_IN_STRING, Var, Func)
456 
457 /// UNIQUE_CHAR_IN_STRING
458 
459 #define UNIQUE_CHAR_IN_STRING(Var, Func) \
460 DO_UNIQUE (CHAR_IN_STRING, Var, Func)
461 
462 /// CHAR_IN_STRING_IS_EMPTY
463 
464 #define CHAR_IN_STRING_IS_EMPTY(Var) \
465  FIELD_IS_EMPTY(CHAR_IN_STRING, Var, Func)
466 
467 
468 ///
469 /// Generic FIELD macros
470 
471 /// FIELD_IS base macro
472 
473 #define FIELD_IS(Var, Fld) \
474  ((Var).Is##Fld())
475 
476 /// FIELD_CHAIN_OF_2_IS base macro
477 
478 #define FIELD_CHAIN_OF_2_IS(Var, Fld1, Fld2) \
479  ( (Var).Is##Fld1() && \
480  (Var).Get##Fld1().Is##Fld2() )
481 
482 /// FIELD_IS_SET_AND_IS base macro
483 
484 #define FIELD_IS_SET_AND_IS(Var, Fld, Chs) \
485  ( (Var).IsSet##Fld() && (Var).Get##Fld().Is##Chs() )
486 
487 /// FIELD_IS_AND_IS_SET base macro
488 
489 #define FIELD_IS_AND_IS_SET(Var, Chs, Fld) \
490  ( (Var).Is##Chs() && (Var).Get##Chs().IsSet##Fld() )
491 
492 /// FIELD_IS_SET base macro
493 
494 #define FIELD_IS_SET(Var, Fld) \
495  ((Var).IsSet##Fld())
496 
497 /// FIELD_CHAIN_OF_2_IS_SET
498 
499 #define FIELD_CHAIN_OF_2_IS_SET(Var, Fld1, Fld2) \
500  ( (Var).IsSet##Fld1() && \
501  (Var).Get##Fld1().IsSet##Fld2() )
502 
503 /// FIELD_CHAIN_OF_3_IS_SET
504 
505 #define FIELD_CHAIN_OF_3_IS_SET(Var, Fld1, Fld2, Fld3) \
506  ( (Var).IsSet##Fld1() && \
507  (Var).Get##Fld1().IsSet##Fld2() && \
508  (Var).Get##Fld1().Get##Fld2().IsSet##Fld3() )
509 
510 /// FIELD_CHAIN_OF_4_IS_SET
511 
512 #define FIELD_CHAIN_OF_4_IS_SET(Var, Fld1, Fld2, Fld3, Fld4) \
513  ( (Var).IsSet##Fld1() && \
514  (Var).Get##Fld1().IsSet##Fld2() && \
515  (Var).Get##Fld1().Get##Fld2().IsSet##Fld3() && \
516  (Var).Get##Fld1().Get##Fld2().Get##Fld3().IsSet##Fld4() )
517 
518 
519 /// FIELD_CHAIN_OF_5_IS_SET
520 
521 #define FIELD_CHAIN_OF_5_IS_SET(Var, Fld1, Fld2, Fld3, Fld4, Fld5) \
522  ( (Var).IsSet##Fld1() && \
523  (Var).Get##Fld1().IsSet##Fld2() && \
524  (Var).Get##Fld1().Get##Fld2().IsSet##Fld3() && \
525  (Var).Get##Fld1().Get##Fld2().Get##Fld3().IsSet##Fld4() && \
526  (Var).Get##Fld1().Get##Fld2().Get##Fld3().Get##Fld4().IsSet##Fld5() )
527 
528 /// GET_FIELD base macro
529 
530 #define GET_FIELD(Var, Fld) \
531  ((Var).Get##Fld())
532 
533 /// GET_FIELD_OR_DEFAULT base macro
534 
535 #define GET_FIELD_OR_DEFAULT(Var, Fld, Dflt) \
536  ((Var).IsSet##Fld() ? (Var).Get##Fld() : Dflt )
537 
538 /// GET_FIELD_CHOICE_OR_DEFAULT base macro
539 
540 #define GET_FIELD_CHOICE_OR_DEFAULT(Var, Fld, Dflt) \
541  ((Var).Is##Fld() ? (Var).Get##Fld() : Dflt )
542 
543 
544 /// GET_MUTABLE base macro
545 
546 #define GET_MUTABLE(Var, Fld) \
547  ((Var).Set##Fld())
548 
549 /// SET_FIELD base macro
550 
551 #define SET_FIELD(Var, Fld, Val) \
552  ((Var).Set##Fld(Val))
553 
554 /// RESET_FIELD base macro
555 
556 #define RESET_FIELD(Var, Fld) \
557  ((Var).Reset##Fld())
558 
559 
560 /// STRING_FIELD_MATCH base macro
561 
562 #define STRING_FIELD_MATCH(Var, Fld, Str) \
563  ((Var).IsSet##Fld() && NStr::EqualNocase((Var).Get##Fld(), Str))
564 
565 /// STRING_FIELD_MATCH_BUT_ONLY_CASE_INSENSITIVE base macro
566 
567 #define STRING_FIELD_MATCH_BUT_ONLY_CASE_INSENSITIVE(Var, Fld, Str) \
568  ((Var).IsSet##Fld() && NStr::EqualNocase((Var).Get##Fld(), (Str)) && \
569  (Var).Get##Fld() != (Str) )
570 
571 /// STRING_FIELD_CHOICE_MATCH base macro
572 
573 #define STRING_FIELD_CHOICE_MATCH( Var, Fld, Chs, Value) \
574  ( (Var).IsSet##Fld() && (Var).Get##Fld().Is##Chs() && \
575  NStr::EqualNocase((Var).Get##Fld().Get##Chs(), (Value)) )
576 
577 
578 /// GET_STRING_FLD_OR_BLANK base macro
579 
580 #define GET_STRING_FLD_OR_BLANK(Var, Fld) \
581  ( (Var).IsSet##Fld() ? (Var).Get##Fld() : kEmptyStr )
582 
583 /// STRING_FIELD_NOT_EMPTY base macro
584 
585 #define STRING_FIELD_NOT_EMPTY(Var, Fld) \
586  ( (Var).IsSet##Fld() && ! (Var).Get##Fld().empty() )
587 
588 /// STRING_FIELD_APPEND base macro
589 /// Appends Str to Var's Fld, putting Delim between if Fld was previously non-empty
590 /// Nothing is done if Str is empty.
591 #define STRING_FIELD_APPEND(Var, Fld, Delim, Str) \
592  do { \
593  const string sStr = (Str); \
594  if( ! sStr.empty() ) { \
595  if( ! (Var).IsSet##Fld() ) { \
596  (Var).Set##Fld(""); \
597  } \
598  string & field = (Var).Set##Fld(); \
599  if( ! field.empty() ) { \
600  field += (Delim); \
601  } \
602  field += sStr; \
603  } \
604  } while(false)
605 
606 
607 /// STRING_SET_MATCH base macro (for list or vectors)
608 
609 #define STRING_SET_MATCH(Var, Fld, Str) \
610  ((Var).IsSet##Fld() && NStr::FindNoCase((Var).Get##Fld(), Str) != NULL)
611 
612 /// FIELD_OUT_OF_RANGE base macro
613 
614 #define FIELD_OUT_OF_RANGE(Var, Fld, Lower, Upper) \
615  ( (Var).IsSet##Fld() && ( (Var).Get##Fld() < (Lower) || (Var).Get##Fld() > (Upper) ) )
616 
617 /// FIELD_EQUALS base macro
618 
619 #define FIELD_EQUALS( Var, Fld, Value ) \
620  ( (Var).IsSet##Fld() && (Var).Get##Fld() == (Value) )
621 
622 /// FIELD_CHOICE_EQUALS base macro
623 
624 #define FIELD_CHOICE_EQUALS( Var, Fld, Chs, Value) \
625  ( (Var).IsSet##Fld() && (Var).Get##Fld().Is##Chs() && \
626  (Var).Get##Fld().Get##Chs() == (Value) )
627 
628 #define FIELD_CHOICE_EMPTY( Var, Fld, Chs) \
629  ( ! (Var).IsSet##Fld() || ! (Var).Get##Fld().Is##Chs() || \
630  (Var).Get##Fld().Get##Chs().empty() )
631 
632 /// CALL_IF_SET base macro
633 
634 #define CALL_IF_SET( Func, Var, Fld ) \
635  { \
636  if( (Var).IsSet##Fld() ) { \
637  Func( GET_MUTABLE( (Var), Fld) ); \
638  } \
639  }
640 
641 /// CALL_IF_SET_CHAIN_2 base macro
642 
643 #define CALL_IF_SET_CHAIN_2( Func, Var, Fld1, Fld2 ) \
644  { \
645  if( (Var).IsSet##Fld1() ) { \
646  CALL_IF_SET( Func, (Var).Set##Fld1(), Fld2 ); \
647  } \
648  }
649 
650 /// CLONE_IF_SET base macro
651 /// (Useful to copy and object from a variable of one
652 /// type to a variable of another type)
653 /// If SrcVar doesn't have SrcFld set, it's reset on the DestVar also.
654 
655 #define CLONE_IF_SET_ELSE_RESET(DestVar, DestFld, SrcVar, SrcFld) \
656  do { \
657  if( FIELD_IS_SET(SrcVar, SrcFld) ) { \
658  (DestVar).Set##DestFld( *SerialClone( GET_FIELD(SrcVar, SrcFld) ) ); \
659  } else { \
660  (DestVar).Reset##DestFld(); \
661  } \
662  } while(0)
663 
664 /// ASSIGN_IF_SET_ELSE_RESET
665 
666 #define ASSIGN_IF_SET_ELSE_RESET(DestVar, DestFld, SrcVar, SrcFld) \
667  do { \
668  if( FIELD_IS_SET(SrcVar, SrcFld) ) { \
669  (DestVar).Set##DestFld( GET_FIELD(SrcVar, SrcFld) ); \
670  } else { \
671  (DestVar).Reset##DestFld(); \
672  } \
673  } while(0)
674 
675 /// TEST_FIELD_CHOICE
676 
677 #define TEST_FIELD_CHOICE( Var, Fld, Chs ) \
678  ( (Var).IsSet##Fld() && (Var).Get##Fld().Which() == (Chs) )
679 
682 
683 
684 /* @} */
685 
686 #endif /* OBJECTS_MISC___SEQUENCE_UTIL_MACROS__HPP */
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:51
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:61
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
bool seq_mac_is_sorted(Iter first, Iter last, Comp comp)
bool seq_mac_is_unique(Iterator iter1, Iterator iter2, Predicate pred)
Modified on Sat May 18 11:39:46 2024 by modify_doxy.py rev. 669887