00001 #ifndef CORELIB___NCBIMISC__HPP
00002 #define CORELIB___NCBIMISC__HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <corelib/ncbistl.hpp>
00039 #ifdef HAVE_SYS_TYPES_H
00040 # include <sys/types.h>
00041 #endif
00042 #ifdef NCBI_COMPILER_ICC
00043
00044
00045 # include <cctype>
00046 #else
00047 # include <ctype.h>
00048 #endif
00049
00050 #if defined(_DEBUG) && !defined(NCBI_NO_STRICT_CTYPE_ARGS)
00051 # define NCBI_STRICT_CTYPE_ARGS
00052 #endif
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef NCBI_ESWITCH_DEFINED
00061 #define NCBI_ESWITCH_DEFINED
00062
00063 #ifdef __cplusplus
00064 extern "C" {
00065 #endif
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 typedef enum {
00078 eOff = 0,
00079 eOn,
00080 eDefault
00081 } ESwitch;
00082
00083 #ifdef __cplusplus
00084 }
00085 #endif
00086
00087 #endif
00088
00089
00090 BEGIN_NCBI_SCOPE
00091
00092
00093
00094
00095
00096
00097
00098 enum EOwnership {
00099 eNoOwnership,
00100 eTakeOwnership
00101 };
00102
00103
00104
00105 enum ENullable {
00106 eNullable,
00107 eNotNullable
00108 };
00109
00110
00111
00112 enum ESign {
00113 eNegative = -1,
00114 eZero = 0,
00115 ePositive = 1
00116 };
00117
00118
00119
00120 enum ERound {
00121 eTrunc,
00122 eRound
00123 };
00124
00125
00126
00127 enum EFollowLinks {
00128 eIgnoreLinks,
00129 eFollowLinks
00130 };
00131
00132
00133
00134
00135
00136
00137 enum EInterruptOnSignal {
00138 eInterruptOnSignal,
00139 eRestartOnSignal
00140 };
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 #define HIDE_SAFE_BOOL_OPERATORS() \
00152 private: \
00153 void operator<(bool) const; \
00154 void operator>(bool) const; \
00155 void operator<=(bool) const; \
00156 void operator>=(bool) const; \
00157 void operator==(bool) const; \
00158 void operator!=(bool) const; \
00159 void operator+(bool) const; \
00160 void operator-(bool) const; \
00161 public:
00162
00163
00164
00165 #define DECLARE_SAFE_BOOL_METHOD(Expr) \
00166 operator bool(void) const { \
00167 return (Expr); \
00168 }
00169
00170
00171
00172
00173
00174 #define DECLARE_OPERATOR_BOOL(Expr) \
00175 HIDE_SAFE_BOOL_OPERATORS() \
00176 DECLARE_SAFE_BOOL_METHOD(Expr)
00177
00178
00179
00180
00181
00182 #define DECLARE_OPERATOR_BOOL_PTR(Ptr) \
00183 DECLARE_OPERATOR_BOOL((Ptr) != 0)
00184
00185
00186
00187
00188
00189 #define DECLARE_OPERATOR_BOOL_REF(Ref) \
00190 DECLARE_OPERATOR_BOOL((Ref).NotNull())
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 template<class Base, class Member>
00211 class pair_base_member : private Base
00212 {
00213 public:
00214 typedef Base base_type;
00215 typedef Base first_type;
00216 typedef Member member_type;
00217 typedef Member second_type;
00218
00219 pair_base_member(void)
00220 : base_type(), m_Member()
00221 {
00222 }
00223
00224 explicit pair_base_member(const member_type& member_value)
00225 : base_type(), m_Member(member_value)
00226 {
00227 }
00228
00229 explicit pair_base_member(const first_type& first_value,
00230 const second_type& second_value)
00231 : base_type(first_value), m_Member(second_value)
00232 {
00233 }
00234
00235 const first_type& first() const
00236 {
00237 return *this;
00238 }
00239 first_type& first()
00240 {
00241 return *this;
00242 }
00243
00244 const second_type& second() const
00245 {
00246 return m_Member;
00247 }
00248 second_type& second()
00249 {
00250 return m_Member;
00251 }
00252
00253 void Swap(pair_base_member<first_type, second_type>& p)
00254 {
00255 if (static_cast<void*>(&first()) != static_cast<void*>(&second())) {
00256
00257
00258 swap(first(), p.first());
00259 }
00260 swap(second(), p.second());
00261 }
00262
00263 private:
00264 member_type m_Member;
00265 };
00266
00267
00268 #ifdef HAVE_NO_AUTO_PTR
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 template <class X>
00283 class auto_ptr
00284 {
00285
00286 template<class Y>
00287 struct auto_ptr_ref
00288 {
00289 auto_ptr_ref(auto_ptr<Y>& ptr)
00290 : m_AutoPtr(ptr)
00291 {
00292 }
00293 auto_ptr<Y>& m_AutoPtr;
00294 };
00295 public:
00296 typedef X element_type;
00297
00298
00299 explicit auto_ptr(X* p = 0) : m_Ptr(p) {}
00300
00301
00302
00303
00304
00305 auto_ptr(auto_ptr<X>& a) : m_Ptr(a.release()) {}
00306
00307
00308 auto_ptr<X>& operator=(auto_ptr<X>& a) {
00309 if (this != &a) {
00310 if (m_Ptr && m_Ptr != a.m_Ptr) {
00311 delete m_Ptr;
00312 }
00313 m_Ptr = a.release();
00314 }
00315 return *this;
00316 }
00317
00318 auto_ptr(auto_ptr_ref<X> ref)
00319 : m_Ptr(ref.m_AutoPtr.release())
00320 {
00321 }
00322 template <typename Y>
00323 operator auto_ptr_ref<Y>()
00324 {
00325 return auto_ptr_ref<Y>(*this);
00326 }
00327
00328
00329 ~auto_ptr(void) {
00330 if ( m_Ptr )
00331 delete m_Ptr;
00332 }
00333
00334
00335 X& operator*(void) const { return *m_Ptr; }
00336
00337
00338 X* operator->(void) const { return m_Ptr; }
00339
00340
00341 int operator==(const X* p) const { return (m_Ptr == p); }
00342
00343
00344 X* get(void) const { return m_Ptr; }
00345
00346
00347 X* release(void) {
00348 X* x_Ptr = m_Ptr; m_Ptr = 0; return x_Ptr;
00349 }
00350
00351
00352 void reset(X* p = 0) {
00353 if (m_Ptr != p) {
00354 delete m_Ptr;
00355 m_Ptr = p;
00356 }
00357 }
00358
00359 private:
00360 X* m_Ptr;
00361 };
00362
00363 #endif
00364
00365
00366
00367
00368 template<class X>
00369 struct Creater
00370 {
00371
00372 static X* Create(void)
00373 { return new X; }
00374 };
00375
00376
00377 template<class X>
00378 struct Deleter
00379 {
00380
00381 static void Delete(X* object)
00382 { delete object; }
00383 };
00384
00385
00386 template<class X>
00387 struct ArrayDeleter
00388 {
00389
00390 static void Delete(X* object)
00391 { delete[] object; }
00392 };
00393
00394
00395 template<class X>
00396 struct CDeleter
00397 {
00398
00399 static void Delete(X* object)
00400 { free(object); }
00401 };
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 template< class X, class Del = Deleter<X> >
00430 class AutoPtr
00431 {
00432 public:
00433 typedef X element_type;
00434 typedef Del deleter_type;
00435
00436
00437 AutoPtr(element_type* p = 0)
00438 : m_Ptr(p), m_Data(true)
00439 {
00440 }
00441
00442
00443 AutoPtr(element_type* p, const deleter_type& deleter)
00444 : m_Ptr(p), m_Data(deleter, true)
00445 {
00446 }
00447
00448
00449 AutoPtr(element_type* p, EOwnership ownership)
00450 : m_Ptr(p), m_Data(ownership != eNoOwnership)
00451 {
00452 }
00453
00454
00455 AutoPtr(element_type* p, const deleter_type& deleter, EOwnership ownership)
00456 : m_Ptr(p), m_Data(deleter, ownership != eNoOwnership)
00457 {
00458 }
00459
00460
00461 AutoPtr(const AutoPtr<X, Del>& p)
00462 : m_Ptr(0), m_Data(p.m_Data)
00463 {
00464 m_Ptr = p.x_Release();
00465 }
00466
00467
00468 ~AutoPtr(void)
00469 {
00470 reset();
00471 }
00472
00473
00474 AutoPtr<X, Del>& operator=(const AutoPtr<X, Del>& p)
00475 {
00476 if (this != &p) {
00477 bool owner = p.m_Data.second();
00478 reset(p.x_Release());
00479 m_Data.second() = owner;
00480 }
00481 return *this;
00482 }
00483
00484
00485 AutoPtr<X, Del>& operator=(element_type* p)
00486 {
00487 reset(p);
00488 return *this;
00489 }
00490
00491
00492 DECLARE_OPERATOR_BOOL_PTR(m_Ptr);
00493
00494
00495
00496
00497 element_type& operator* (void) const { return *m_Ptr; }
00498
00499
00500 element_type* operator->(void) const { return m_Ptr; }
00501
00502
00503 element_type* get (void) const { return m_Ptr; }
00504
00505
00506 element_type* release(void)
00507 {
00508 m_Data.second() = false;
00509 return m_Ptr;
00510 }
00511
00512
00513
00514 void reset(element_type* p = 0, EOwnership ownership = eTakeOwnership)
00515 {
00516 if ( m_Ptr != p ) {
00517 if (m_Ptr && m_Data.second()) {
00518 m_Data.first().Delete(release());
00519 }
00520 m_Ptr = p;
00521 }
00522 m_Data.second() = p != 0 && ownership == eTakeOwnership;
00523 }
00524
00525 void Swap(AutoPtr<X, Del>& a)
00526 {
00527 swap(m_Ptr, a.m_Ptr);
00528 swap(m_Data, a.m_Data);
00529 }
00530
00531 private:
00532 element_type* m_Ptr;
00533 mutable pair_base_member<deleter_type, bool> m_Data;
00534
00535
00536 element_type* x_Release(void) const
00537 {
00538 return const_cast<AutoPtr<X, Del>*>(this)->release();
00539 }
00540 };
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 template< class X, class Del = ArrayDeleter<X> >
00558 class AutoArray
00559 {
00560 public:
00561 typedef X element_type;
00562 typedef Del deleter_type;
00563
00564 public:
00565
00566
00567
00568 explicit AutoArray(size_t size)
00569 : m_Ptr(new element_type[size]), m_Data(true)
00570 {}
00571
00572 explicit AutoArray(element_type* p = 0)
00573 : m_Ptr(p), m_Data(true)
00574 {}
00575
00576 AutoArray(element_type* p, const deleter_type& deleter)
00577 : m_Ptr(p), m_Data(deleter, true)
00578 {
00579 }
00580
00581 AutoArray(const AutoArray<X, Del>& p)
00582 : m_Ptr(0), m_Data(p.m_Data)
00583 {
00584 m_Ptr = p.x_Release();
00585 }
00586
00587 ~AutoArray(void)
00588 {
00589 reset();
00590 }
00591
00592
00593 AutoArray<X, Del>& operator=(const AutoArray<X, Del>& p)
00594 {
00595 if (this != &p) {
00596 bool owner = p.m_Data.second();
00597 reset(p.x_Release());
00598 m_Data.second() = owner;
00599 }
00600 return *this;
00601 }
00602
00603
00604 AutoArray<X, Del>& operator=(element_type* p)
00605 {
00606 reset(p);
00607 return *this;
00608 }
00609
00610 DECLARE_OPERATOR_BOOL_PTR(m_Ptr);
00611
00612
00613 element_type* get (void) const { return m_Ptr; }
00614
00615
00616 element_type* release(void)
00617 {
00618 m_Data.second() = false;
00619 return m_Ptr;
00620 }
00621
00622
00623 const element_type& operator[](size_t pos) const { return m_Ptr[pos]; }
00624
00625
00626 element_type& operator[](size_t pos) { return m_Ptr[pos]; }
00627
00628
00629
00630 void reset(element_type* p = 0)
00631 {
00632 if (m_Ptr && m_Data.second()) {
00633 m_Data.first().Delete(release());
00634 }
00635 m_Ptr = p;
00636 m_Data.second() = true;
00637 }
00638
00639 void Swap(AutoPtr<X, Del>& a)
00640 {
00641 swap(m_Ptr, a.m_Ptr);
00642 swap(m_Data, a.m_Data);
00643 }
00644
00645 private:
00646
00647 element_type* x_Release(void) const
00648 {
00649 return const_cast<AutoArray<X, Del>*>(this)->release();
00650 }
00651
00652 private:
00653 element_type* m_Ptr;
00654 mutable pair_base_member<deleter_type, bool> m_Data;
00655 };
00656
00657
00658
00659
00660
00661
00662
00663 #ifdef min
00664 # undef min
00665 #endif
00666 #ifdef max
00667 # undef max
00668 #endif
00669
00670 #if defined(HAVE_NO_MINMAX_TEMPLATE)
00671 # define NOMINMAX
00672
00673
00674 template <class T>
00675 inline
00676 const T& min(const T& a, const T& b) {
00677 return b < a ? b : a;
00678 }
00679
00680
00681 template <class T>
00682 inline
00683 const T& max(const T& a, const T& b) {
00684 return a < b ? b : a;
00685 }
00686 #endif
00687
00688
00689
00690
00691
00692
00693 #ifndef HAVE_STRDUP
00694
00695 extern char* strdup(const char* str);
00696 #endif
00697
00698
00699
00700
00701
00702
00703 #ifdef NCBI_STRICT_CTYPE_ARGS
00704
00705 END_NCBI_SCOPE
00706
00707 #define NCBI_CTYPEFAKEBODY \
00708 { return See_the_standard_on_proper_argument_type_for_ctype_macros(c); }
00709
00710 #ifdef isalpha
00711 inline int NCBI_isalpha(unsigned char c) { return isalpha(c); }
00712 inline int NCBI_isalpha(int c) { return isalpha(c); }
00713 template<class C>
00714 inline int NCBI_isalpha(C c) NCBI_CTYPEFAKEBODY
00715 #undef isalpha
00716 #define isalpha NCBI_isalpha
00717 #endif
00718
00719 #ifdef isalnum
00720 inline int NCBI_isalnum(unsigned char c) { return isalnum(c); }
00721 inline int NCBI_isalnum(int c) { return isalnum(c); }
00722 template<class C>
00723 inline int NCBI_isalnum(C c) NCBI_CTYPEFAKEBODY
00724 #undef isalnum
00725 #define isalnum NCBI_isalnum
00726 #endif
00727
00728 #ifdef isascii
00729 inline int NCBI_isascii(unsigned char c) { return isascii(c); }
00730 inline int NCBI_isascii(int c) { return isascii(c); }
00731 template<class C>
00732 inline int NCBI_isascii(C c) NCBI_CTYPEFAKEBODY
00733 #undef isascii
00734 #define isascii NCBI_isascii
00735 #endif
00736
00737 #ifdef isblank
00738 inline int NCBI_isblank(unsigned char c) { return isblank(c); }
00739 inline int NCBI_isblank(int c) { return isblank(c); }
00740 template<class C>
00741 inline int NCBI_isblank(C c) NCBI_CTYPEFAKEBODY
00742 #undef isblank
00743 #define isblank NCBI_isblank
00744 #endif
00745
00746 #ifdef iscntrl
00747 inline int NCBI_iscntrl(unsigned char c) { return iscntrl(c); }
00748 inline int NCBI_iscntrl(int c) { return iscntrl(c); }
00749 template<class C>
00750 inline int NCBI_iscntrl(C c) NCBI_CTYPEFAKEBODY
00751 #undef iscntrl
00752 #define iscntrl NCBI_iscntrl
00753 #endif
00754
00755 #ifdef isdigit
00756 inline int NCBI_isdigit(unsigned char c) { return isdigit(c); }
00757 inline int NCBI_isdigit(int c) { return isdigit(c); }
00758 template<class C>
00759 inline int NCBI_isdigit(C c) NCBI_CTYPEFAKEBODY
00760 #undef isdigit
00761 #define isdigit NCBI_isdigit
00762 #endif
00763
00764 #ifdef isgraph
00765 inline int NCBI_isgraph(unsigned char c) { return isgraph(c); }
00766 inline int NCBI_isgraph(int c) { return isgraph(c); }
00767 template<class C>
00768 inline int NCBI_isgraph(C c) NCBI_CTYPEFAKEBODY
00769 #undef isgraph
00770 #define isgraph NCBI_isgraph
00771 #endif
00772
00773 #ifdef islower
00774 inline int NCBI_islower(unsigned char c) { return islower(c); }
00775 inline int NCBI_islower(int c) { return islower(c); }
00776 template<class C>
00777 inline int NCBI_islower(C c) NCBI_CTYPEFAKEBODY
00778 #undef islower
00779 #define islower NCBI_islower
00780 #endif
00781
00782 #ifdef isprint
00783 inline int NCBI_isprint(unsigned char c) { return isprint(c); }
00784 inline int NCBI_isprint(int c) { return isprint(c); }
00785 template<class C>
00786 inline int NCBI_isprint(C c) NCBI_CTYPEFAKEBODY
00787 #undef isprint
00788 #define isprint NCBI_isprint
00789 #endif
00790
00791 #ifdef ispunct
00792 inline int NCBI_ispunct(unsigned char c) { return ispunct(c); }
00793 inline int NCBI_ispunct(int c) { return ispunct(c); }
00794 template<class C>
00795 inline int NCBI_ispunct(C c) NCBI_CTYPEFAKEBODY
00796 #undef ispunct
00797 #define ispunct NCBI_ispunct
00798 #endif
00799
00800 #ifdef isspace
00801 inline int NCBI_isspace(unsigned char c) { return isspace(c); }
00802 inline int NCBI_isspace(int c) { return isspace(c); }
00803 template<class C>
00804 inline int NCBI_isspace(C c) NCBI_CTYPEFAKEBODY
00805 #undef isspace
00806 #define isspace NCBI_isspace
00807 #endif
00808
00809 #ifdef isupper
00810 inline int NCBI_isupper(unsigned char c) { return isupper(c); }
00811 inline int NCBI_isupper(int c) { return isupper(c); }
00812 template<class C>
00813 inline int NCBI_isupper(C c) NCBI_CTYPEFAKEBODY
00814 #undef isupper
00815 #define isupper NCBI_isupper
00816 #endif
00817
00818 #ifdef isxdigit
00819 inline int NCBI_isxdigit(unsigned char c) { return isxdigit(c); }
00820 inline int NCBI_isxdigit(int c) { return isxdigit(c); }
00821 template<class C>
00822 inline int NCBI_isxdigit(C c) NCBI_CTYPEFAKEBODY
00823 #undef isxdigit
00824 #define isxdigit NCBI_isxdigit
00825 #endif
00826
00827 #ifdef toascii
00828 inline int NCBI_toascii(unsigned char c) { return toascii(c); }
00829 inline int NCBI_toascii(int c) { return toascii(c); }
00830 template<class C>
00831 inline int NCBI_toascii(C c) NCBI_CTYPEFAKEBODY
00832 #undef toascii
00833 #define toascii NCBI_toascii
00834 #endif
00835
00836 #ifdef tolower
00837 inline int NCBI_tolower(unsigned char c) { return tolower(c); }
00838 inline int NCBI_tolower(int c) { return tolower(c); }
00839 template<class C>
00840 inline int NCBI_tolower(C c) NCBI_CTYPEFAKEBODY
00841 #undef tolower
00842 #define tolower NCBI_tolower
00843 #endif
00844
00845 #ifdef toupper
00846 inline int NCBI_toupper(unsigned char c) { return toupper(c); }
00847 inline int NCBI_toupper(int c) { return toupper(c); }
00848 template<class C>
00849 inline int NCBI_toupper(C c) NCBI_CTYPEFAKEBODY
00850 #undef toupper
00851 #define toupper NCBI_toupper
00852 #endif
00853
00854 #undef NCBI_CTYPEFAKEBODY
00855
00856 BEGIN_NCBI_SCOPE
00857
00858 #endif // NCBI_STRICT_CTYPE_ARGS
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 #define ITERATE(Type, Var, Cont) \
00872 for ( Type::const_iterator Var = (Cont).begin(), NCBI_NAME2(Var,_end) = (Cont).end(); Var != NCBI_NAME2(Var,_end); ++Var )
00873
00874
00875 #define NON_CONST_ITERATE(Type, Var, Cont) \
00876 for ( Type::iterator Var = (Cont).begin(); Var != (Cont).end(); ++Var )
00877
00878
00879
00880
00881 #define ERASE_ITERATE(Type, Var, Cont) \
00882 for ( Type::iterator NCBI_NAME2(Var,_next) = (Cont).begin(), \
00883 Var = NCBI_NAME2(Var,_next) != (Cont).end() ? NCBI_NAME2(Var,_next)++ : (Cont).end(); \
00884 NCBI_NAME2(Var,_next) != (Cont).end(); \
00885 Var = NCBI_NAME2(Var,_next) != (Cont).end() ? NCBI_NAME2(Var,_next)++ : (Cont).end())
00886
00887
00888
00889 #define REVERSE_ITERATE(Type, Var, Cont) \
00890 for ( Type::const_reverse_iterator Var = (Cont).rbegin(), NCBI_NAME2(Var,_end) = (Cont).rend(); Var != NCBI_NAME2(Var,_end); ++Var )
00891
00892
00893 #define NON_CONST_REVERSE_ITERATE(Type, Var, Cont) \
00894 for ( Type::reverse_iterator Var = (Cont).rbegin(); Var != (Cont).rend(); ++Var )
00895
00896
00897
00898
00899
00900 typedef unsigned int TSeqPos;
00901
00902
00903 const TSeqPos kInvalidSeqPos = ((TSeqPos) (-1));
00904
00905
00906
00907
00908
00909
00910
00911
00912 typedef int TSignedSeqPos;
00913
00914
00915 class CRawPointer
00916 {
00917 public:
00918
00919 static void* Add(void* object, ssize_t offset);
00920 static const void* Add(const void* object, ssize_t offset);
00921
00922 static ssize_t Sub(const void* first, const void* second);
00923 };
00924
00925
00926 inline
00927 void* CRawPointer::Add(void* object, ssize_t offset)
00928 {
00929 return static_cast<char*> (object) + offset;
00930 }
00931
00932 inline
00933 const void* CRawPointer::Add(const void* object, ssize_t offset)
00934 {
00935 return static_cast<const char*> (object) + offset;
00936 }
00937
00938 inline
00939 ssize_t CRawPointer::Sub(const void* first, const void* second)
00940 {
00941 return (ssize_t)
00942 (static_cast<const char*> (first) - static_cast<const char*> (second));
00943 }
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953 #if defined(NCBI_COMPILER_MSVC) || defined(NCBI_COMPILER_VISUALAGE)
00954 # define NCBI_DEPRECATED_CTOR(decl) NCBI_DEPRECATED decl
00955 #else
00956 # define NCBI_DEPRECATED_CTOR(decl) decl NCBI_DEPRECATED
00957 #endif
00958
00959 END_NCBI_SCOPE
00960
00961 BEGIN_STD_SCOPE
00962
00963 template<class T1, class T2>
00964 inline
00965 void swap(NCBI_NS_NCBI::pair_base_member<T1,T2>& pair1,
00966 NCBI_NS_NCBI::pair_base_member<T1,T2>& pair2)
00967 {
00968 pair1.Swap(pair2);
00969 }
00970
00971
00972 template<class P, class D>
00973 inline
00974 void swap(NCBI_NS_NCBI::AutoPtr<P,D>& ptr1,
00975 NCBI_NS_NCBI::AutoPtr<P,D>& ptr2)
00976 {
00977 ptr1.Swap(ptr2);
00978 }
00979
00980
00981 #if (defined(NCBI_COMPILER_GCC) && NCBI_COMPILER_VERSION < 340) || defined(NCBI_COMPILER_WORKSHOP) || defined(NCBI_COMPILER_MIPSPRO)
00982
00983 #define ArraySize(array) sizeof(array)/sizeof((array)[0])
00984
00985 #else
00986
00987 template<class Element, size_t Size>
00988 inline
00989 size_t ArraySize(const Element (&)[Size])
00990 {
00991 return Size;
00992 }
00993
00994 #endif
00995
00996 END_STD_SCOPE
00997
00998
00999
01000
01001 #endif
01002
01003