include/corelib/ncbimisc.hpp

Go to the documentation of this file.
00001 #ifndef CORELIB___NCBIMISC__HPP
00002 #define CORELIB___NCBIMISC__HPP
00003 
00004 /*  $Id: ncbimisc.hpp 167884 2009-08-07 17:57:15Z lavr $
00005  * ===========================================================================
00006  *
00007  *                            PUBLIC DOMAIN NOTICE
00008  *               National Center for Biotechnology Information
00009  *
00010  *  This software/database is a "United States Government Work" under the
00011  *  terms of the United States Copyright Act.  It was written as part of
00012  *  the author's official duties as a United States Government employee and
00013  *  thus cannot be copyrighted.  This software/database is freely available
00014  *  to the public for use. The National Library of Medicine and the U.S.
00015  *  Government have not placed any restriction on its use or reproduction.
00016  *
00017  *  Although all reasonable efforts have been taken to ensure the accuracy
00018  *  and reliability of the software and data, the NLM and the U.S.
00019  *  Government do not and cannot warrant the performance or results that
00020  *  may be obtained by using this software or data. The NLM and the U.S.
00021  *  Government disclaim all warranties, express or implied, including
00022  *  warranties of performance, merchantability or fitness for any particular
00023  *  purpose.
00024  *
00025  *  Please cite the author in any work or product based on this material.
00026  *
00027  * ===========================================================================
00028  *
00029  * Author:  Denis Vakatov, Eugene Vasilchenko
00030  *
00031  *
00032  */
00033 
00034 /// @file ncbistd.hpp
00035 /// Miscellaneous common-use basic types and functionality
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 // Preemptively pull in <cctype>, which breaks if we've already
00044 // repointed is* at NCBI_is*.
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 /** @addtogroup AppFramework
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  * ATTENTION!   Do not change this enumeration!
00069  *
00070  * It must always be kept in sync with its plain C counterpart defined in
00071  * "connect/ncbi_types.h". If you absolutely(sic!) need to alter this
00072  * type, please apply equivalent changes to both definitions.
00073  */
00074 
00075 /** Aux. enum to set/unset/default various features
00076  */
00077 typedef enum {
00078     eOff = 0,
00079     eOn,
00080     eDefault
00081 } ESwitch;
00082 
00083 #ifdef __cplusplus
00084 }  /* extern "C" */
00085 #endif
00086 
00087 #endif  /* !defined(NCBI_ESWITCH_DEFINED) */
00088 
00089 
00090 BEGIN_NCBI_SCOPE
00091 
00092 
00093 /// Which type of ownership between objects.
00094 ///
00095 /// Can be used to specify ownership relationship between objects.
00096 /// For example, specify if a CSocket object owns the underlying
00097 /// SOCK object. 
00098 enum EOwnership {
00099     eNoOwnership,       ///< No ownership relationship
00100     eTakeOwnership      ///< An object can take ownership of another
00101 };
00102 
00103 
00104 /// Whether a value is nullable.
00105 enum ENullable {
00106     eNullable,          ///< Value can be null
00107     eNotNullable        ///< Value cannot be null
00108 };
00109 
00110 
00111 /// Whether a value is nullable.
00112 enum ESign {
00113     eNegative = -1,     ///< Value is negative
00114     eZero     =  0,     ///< Value is zero
00115     ePositive =  1      ///< Value is positive
00116 };
00117 
00118 
00119 /// Whether to truncate/round a value.
00120 enum ERound {
00121     eTrunc,             ///< Value must be truncated
00122     eRound              ///< Value must be rounded
00123 };
00124 
00125 
00126 /// Whether to follow symbolic links (also known as shortcuts or aliases)
00127 enum EFollowLinks {
00128     eIgnoreLinks,
00129     eFollowLinks
00130 };
00131 
00132 
00133 /// Interrupt on signal mode
00134 ///
00135 /// On UNIX some functions can be interrupted by a signal and EINTR errno
00136 /// value. We can restart or cancel its execution.
00137 enum EInterruptOnSignal {
00138     eInterruptOnSignal, ///< Cancel operation if interrapted by a signal
00139     eRestartOnSignal    ///< Restart operation if interrupted by a signal
00140 };
00141 
00142 
00143 /////////////////////////////////////////////////////////////////////////////
00144 /// Support for safe bool operators
00145 /////////////////////////////////////////////////////////////////////////////
00146 
00147 
00148 /// Macro to hide all oprators with bool argument which may be used
00149 /// unintentially when second argument is of class having operator bool().
00150 /// All methods are simply declared private without body definition.
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 /// Low level macro for declaring bool operator.
00165 #define DECLARE_SAFE_BOOL_METHOD(Expr)                  \
00166     operator bool(void) const {                         \
00167         return (Expr);                                  \
00168     }
00169 
00170 
00171 /// Declaration of safe bool operator from boolean expression.
00172 /// Actual operator declaration will be:
00173 ///    operator bool(void) const;
00174 #define DECLARE_OPERATOR_BOOL(Expr)             \
00175     HIDE_SAFE_BOOL_OPERATORS()                  \
00176     DECLARE_SAFE_BOOL_METHOD(Expr)
00177 
00178 
00179 /// Declaration of safe bool operator from pointer expression.
00180 /// Actual operator declaration will be:
00181 ///    operator bool(void) const;
00182 #define DECLARE_OPERATOR_BOOL_PTR(Ptr)          \
00183     DECLARE_OPERATOR_BOOL((Ptr) != 0)
00184 
00185 
00186 /// Declaration of safe bool operator from CRef<>/CConstRef<> expression.
00187 /// Actual operator declaration will be:
00188 ///    operator bool(void) const;
00189 #define DECLARE_OPERATOR_BOOL_REF(Ref)          \
00190     DECLARE_OPERATOR_BOOL((Ref).NotNull())
00191 
00192 
00193 /// Template used for empty base class optimization.
00194 /// See details in the August '97 "C++ Issue" of Dr. Dobb's Journal
00195 /// Also available from http://www.cantrip.org/emptyopt.html
00196 /// We store usually empty template argument class together with data member.
00197 /// This template is much like STL's pair<>, but the access to members
00198 /// is done though methods first() and second() returning references
00199 /// to corresponding members.
00200 /// First template argument is represented as private base class,
00201 /// while second template argument is represented as private member.
00202 /// In addition to constructor taking two arguments,
00203 /// we add constructor for initialization of only data member (second).
00204 /// This is useful since usually first type is empty and doesn't require
00205 /// non-trivial constructor.
00206 /// We do not define any comparison functions as this template is intented
00207 /// to be used internally within another templates,
00208 /// which themselves should provide any additional functionality.
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                 // work around an IBM compiler bug which causes it to perform
00257                 // a spurious 1-byte swap, yielding mixed-up values.
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 /// auto_ptr --
00274 ///
00275 /// Define auto_ptr if needed.
00276 ///
00277 /// Replacement of STL's std::auto_ptr for compilers with poor "auto_ptr"
00278 /// implementation.
00279 /// 
00280 /// See C++ Toolkit documentation for limitations and use of auto_ptr.
00281 
00282 template <class X>
00283 class auto_ptr
00284 {
00285     // temporary class for auto_ptr copying
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;         ///< Define element_type
00297 
00298     /// Explicit conversion to auto_ptr.
00299     explicit auto_ptr(X* p = 0) : m_Ptr(p) {}
00300 
00301     /// Copy constructor with implicit conversion.
00302     ///
00303     /// Note that the copy constructor parameter is not a const
00304     /// because it is modified -- ownership is transferred.
00305     auto_ptr(auto_ptr<X>& a) : m_Ptr(a.release()) {}
00306 
00307     /// Assignment operator.
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     /// Destructor.
00329     ~auto_ptr(void) {
00330         if ( m_Ptr )
00331             delete m_Ptr;
00332     }
00333 
00334     /// Deference operator.
00335     X&  operator*(void) const { return *m_Ptr; }
00336 
00337     /// Reference operator.
00338     X*  operator->(void) const { return m_Ptr; }
00339 
00340     /// Equality operator.
00341     int operator==(const X* p) const { return (m_Ptr == p); }
00342 
00343     /// Get pointer value.
00344     X*  get(void) const { return m_Ptr; }
00345 
00346     /// Release pointer.
00347     X* release(void) {
00348         X* x_Ptr = m_Ptr;  m_Ptr = 0;  return x_Ptr;
00349     }
00350 
00351     /// Reset pointer.
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;               ///< Internal pointer implementation.
00361 };
00362 
00363 #endif /* HAVE_NO_AUTO_PTR */
00364 
00365 
00366 
00367 /// Functor template for allocating object.
00368 template<class X>
00369 struct Creater
00370 {
00371     /// Default create function.
00372     static X* Create(void)
00373     { return new X; }
00374 };
00375 
00376 /// Functor tempate for deleting object.
00377 template<class X>
00378 struct Deleter
00379 {
00380     /// Default delete function.
00381     static void Delete(X* object)
00382     { delete object; }
00383 };
00384 
00385 /// Functor template for deleting array of objects.
00386 template<class X>
00387 struct ArrayDeleter
00388 {
00389     /// Array delete function.
00390     static void Delete(X* object)
00391     { delete[] object; }
00392 };
00393 
00394 /// Functor template for the C language deallocation function, free().
00395 template<class X>
00396 struct CDeleter
00397 {
00398     /// C Language deallocation function.
00399     static void Delete(X* object)
00400     { free(object); }
00401 };
00402 
00403 
00404 
00405 /////////////////////////////////////////////////////////////////////////////
00406 ///
00407 /// AutoPtr --
00408 ///
00409 /// Define an "auto_ptr" like class that can be used inside STL containers.
00410 ///
00411 /// The Standard auto_ptr template from STL doesn't allow the auto_ptr to be
00412 /// put in STL containers (list, vector, map etc.). The reason for this is
00413 /// the absence of copy constructor and assignment operator.
00414 /// We decided that it would be useful to have an analog of STL's auto_ptr
00415 /// without this restriction - AutoPtr.
00416 ///
00417 /// Due to nature of AutoPtr its copy constructor and assignment operator
00418 /// modify the state of the source AutoPtr object as it transfers ownership
00419 /// to the target AutoPtr object. Also, we added possibility to redefine the
00420 /// way pointer will be deleted: the second argument of template allows
00421 /// pointers from "malloc" in AutoPtr, or you can use "ArrayDeleter" (see
00422 /// above) to properly delete an array of objects using "delete[]" instead
00423 /// of "delete". By default, the internal pointer will be deleted by C++
00424 /// "delete" operator.
00425 ///
00426 /// @sa
00427 ///   Deleter(), ArrayDeleter(), CDeleter()
00428 
00429 template< class X, class Del = Deleter<X> >
00430 class AutoPtr
00431 {
00432 public:
00433     typedef X element_type;         ///< Define element type.
00434     typedef Del deleter_type;       ///< Alias for template argument.
00435 
00436     /// Constructor.
00437     AutoPtr(element_type* p = 0)
00438         : m_Ptr(p), m_Data(true)
00439     {
00440     }
00441 
00442     /// Constructor.
00443     AutoPtr(element_type* p, const deleter_type& deleter)
00444         : m_Ptr(p), m_Data(deleter, true)
00445     {
00446     }
00447 
00448     /// Constructor, own the pointed object if ownership == eTakeOwnership
00449     AutoPtr(element_type* p, EOwnership ownership)
00450         : m_Ptr(p), m_Data(ownership != eNoOwnership)
00451     {
00452     }
00453 
00454     /// Constructor, own the pointed object if ownership == eTakeOwnership
00455     AutoPtr(element_type* p, const deleter_type& deleter, EOwnership ownership)
00456         : m_Ptr(p), m_Data(deleter, ownership != eNoOwnership)
00457     {
00458     }
00459 
00460     /// Copy constructor.
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     /// Destructor.
00468     ~AutoPtr(void)
00469     {
00470         reset();
00471     }
00472 
00473     /// Assignment operator.
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     /// Assignment operator.
00485     AutoPtr<X, Del>& operator=(element_type* p)
00486     {
00487         reset(p);
00488         return *this;
00489     }
00490 
00491     /// Bool operator for use in if() clause.
00492     DECLARE_OPERATOR_BOOL_PTR(m_Ptr);
00493 
00494     // Standard getters.
00495 
00496     /// Dereference operator.
00497     element_type& operator* (void) const { return *m_Ptr; }
00498 
00499     /// Reference operator.
00500     element_type* operator->(void) const { return  m_Ptr; }
00501 
00502     /// Get pointer.
00503     element_type* get       (void) const { return  m_Ptr; }
00504 
00505     /// Release will release ownership of pointer to caller.
00506     element_type* release(void)
00507     {
00508         m_Data.second() = false;
00509         return m_Ptr;
00510     }
00511 
00512     /// Reset will delete old pointer, set content to new value,
00513     /// and accept ownership upon the new pointer.
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;                  ///< Internal pointer representation.
00533     mutable pair_base_member<deleter_type, bool> m_Data; ///< State info.
00534 
00535     /// Release for const object.
00536     element_type* x_Release(void) const
00537     {
00538         return const_cast<AutoPtr<X, Del>*>(this)->release();
00539     }
00540 };
00541 
00542 
00543 /////////////////////////////////////////////////////////////////////////////
00544 ///
00545 /// AutoArray --
00546 ///
00547 /// "AutoPtr" like class for using with arrays
00548 ///
00549 /// vector<> template comes with a performance penalty, since it always
00550 /// initializes its content. This template is not a vector replacement,
00551 /// it's a version of AutoPtr<> tuned for array pointers. For convenience
00552 /// it defines array style access operator [] and size based contructor.
00553 ///
00554 /// @sa AutoPtr
00555 ///
00556 
00557 template< class X, class Del = ArrayDeleter<X> >
00558 class AutoArray
00559 {
00560 public:
00561     typedef X element_type;         ///< Define element type.
00562     typedef Del deleter_type;       ///< Alias for template argument.
00563 
00564 public:
00565 
00566     /// Construct the array using C++ new[] operator
00567     /// @note In this case you should use ArrayDeleter<> or compatible
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     /// Assignment operator.
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     /// Assignment operator.
00604     AutoArray<X, Del>& operator=(element_type* p)
00605     {
00606         reset(p);
00607         return *this;
00608     }
00609     /// Bool operator for use in if() clause.
00610     DECLARE_OPERATOR_BOOL_PTR(m_Ptr);
00611 
00612     /// Get pointer.
00613     element_type* get       (void) const { return  m_Ptr; }
00614 
00615     /// Release will release ownership of pointer to caller.
00616     element_type* release(void)
00617     {
00618         m_Data.second() = false;
00619         return m_Ptr;
00620     }
00621 
00622     /// array style dereference (returns value)
00623     const element_type& operator[](size_t pos) const { return m_Ptr[pos]; }
00624 
00625     /// array style dereference (returns reference)
00626     element_type& operator[](size_t pos) { return m_Ptr[pos]; }
00627 
00628     /// Reset will delete old pointer, set content to new value,
00629     /// and accept ownership upon the new pointer.
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     /// Release for const object.
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; ///< State info.
00655 };
00656 
00657 
00658 
00659 // "min" and "max" templates
00660 //
00661 
00662 // Always get rid of the old non-conformant min/max macros
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 /// Min function template.
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 /// Max function template.
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 /* HAVE_NO_MINMAX_TEMPLATE */
00687 
00688 
00689 
00690 // strdup()
00691 //
00692 
00693 #ifndef HAVE_STRDUP
00694 /// Supply string duplicate function, if one is not defined.
00695 extern char* strdup(const char* str);
00696 #endif
00697 
00698 
00699 
00700 // ctype hacks
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 //  ITERATE
00863 //  NON_CONST_ITERATE
00864 //  ERASE_ITERATE
00865 //
00866 // Useful macro to write 'for' statements with the STL container iterator as
00867 // a variable.
00868 //
00869 
00870 /// ITERATE macro to sequence through container elements.
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 /// Non constant version of ITERATE macro.
00875 #define NON_CONST_ITERATE(Type, Var, Cont) \
00876     for ( Type::iterator Var = (Cont).begin();  Var != (Cont).end();  ++Var )
00877 
00878 /// Non constant version with ability to erase current element, if container permits.
00879 /// Use only on containers, for which erase do not ruin other iterators into the container
00880 /// e.g., map, list, but NOT vector.
00881 /// See also VECTOR_ERASE
00882 #define ERASE_ITERATE(Type, Var, Cont) \
00883     for ( Type::iterator Var, NCBI_NAME2(Var,_next) = (Cont).begin();   \
00884           (Var = NCBI_NAME2(Var,_next)) != (Cont).end() &&              \
00885               (++NCBI_NAME2(Var,_next), true); )
00886 /// Use this macro inside body of ERASE_ITERATE cycle to erase from
00887 /// vector-like container. Plain erase() call would invalidate Var_next
00888 /// iterator and would make the cycle controlling code to fail.
00889 #define VECTOR_ERASE(Var, Cont) (NCBI_NAME2(Var,_next) = (Cont).erase(Var))
00890 
00891 /// ITERATE macro to reverse sequence through container elements.
00892 #define REVERSE_ITERATE(Type, Var, Cont) \
00893     for ( Type::const_reverse_iterator Var = (Cont).rbegin(), NCBI_NAME2(Var,_end) = (Cont).rend();  Var != NCBI_NAME2(Var,_end);  ++Var )
00894 
00895 /// Non constant version of REVERSE_ITERATE macro.
00896 #define NON_CONST_REVERSE_ITERATE(Type, Var, Cont) \
00897     for ( Type::reverse_iterator Var = (Cont).rbegin();  Var != (Cont).rend();  ++Var )
00898 
00899 
00900 /// Type for sequence locations and lengths.
00901 ///
00902 /// Use this typedef rather than its expansion, which may change.
00903 typedef unsigned int TSeqPos;
00904 
00905 /// Define special value for invalid sequence position.
00906 const TSeqPos kInvalidSeqPos = ((TSeqPos) (-1));
00907 
00908 
00909 /// Type for signed sequence position.
00910 ///
00911 /// Use this type when and only when negative values are a possibility
00912 /// for reporting differences between positions, or for error reporting --
00913 /// though exceptions are generally better for error reporting.
00914 /// Use this typedef rather than its expansion, which may change.
00915 typedef int TSignedSeqPos;
00916 
00917 /// Helper address class
00918 class CRawPointer
00919 {
00920 public:
00921     /// add offset to object reference (to get object's member)
00922     static void* Add(void* object, ssize_t offset);
00923     static const void* Add(const void* object, ssize_t offset);
00924     /// calculate offset inside object
00925     static ssize_t Sub(const void* first, const void* second);
00926 };
00927 
00928 
00929 inline
00930 void* CRawPointer::Add(void* object, ssize_t offset)
00931 {
00932     return static_cast<char*> (object) + offset;
00933 }
00934 
00935 inline
00936 const void* CRawPointer::Add(const void* object, ssize_t offset)
00937 {
00938     return static_cast<const char*> (object) + offset;
00939 }
00940 
00941 inline
00942 ssize_t CRawPointer::Sub(const void* first, const void* second)
00943 {
00944     return (ssize_t)/*ptrdiff_t*/
00945         (static_cast<const char*> (first) - static_cast<const char*> (second));
00946 }
00947 
00948 /// Macro used to mark a constructor as deprecated.
00949 ///
00950 /// The correct syntax for this varies from compiler to compiler:
00951 /// older versions of GCC (prior to 3.4) require NCBI_DEPRECATED to
00952 /// follow any relevant constructor declarations, but some other
00953 /// compilers (Microsoft Visual Studio 2005, IBM Visual Age / XL)
00954 /// require it to precede any relevant declarations, whether or not
00955 /// they are for constructors.
00956 #if defined(NCBI_COMPILER_MSVC) || defined(NCBI_COMPILER_VISUALAGE)
00957 #  define NCBI_DEPRECATED_CTOR(decl) NCBI_DEPRECATED decl
00958 #else
00959 #  define NCBI_DEPRECATED_CTOR(decl) decl NCBI_DEPRECATED
00960 #endif
00961 
00962 END_NCBI_SCOPE
00963 
00964 BEGIN_STD_SCOPE
00965 
00966 template<class T1, class T2>
00967 inline
00968 void swap(NCBI_NS_NCBI::pair_base_member<T1,T2>& pair1,
00969           NCBI_NS_NCBI::pair_base_member<T1,T2>& pair2)
00970 {
00971     pair1.Swap(pair2);
00972 }
00973 
00974 
00975 template<class P, class D>
00976 inline
00977 void swap(NCBI_NS_NCBI::AutoPtr<P,D>& ptr1,
00978           NCBI_NS_NCBI::AutoPtr<P,D>& ptr2)
00979 {
00980     ptr1.Swap(ptr2);
00981 }
00982 
00983 
00984 #if (defined(NCBI_COMPILER_GCC) && NCBI_COMPILER_VERSION < 340)  ||  defined(NCBI_COMPILER_WORKSHOP)  ||  defined(NCBI_COMPILER_MIPSPRO)
00985 
00986 #define ArraySize(array) sizeof(array)/sizeof((array)[0])
00987 
00988 #else
00989 
00990 template<class Element, size_t Size>
00991 inline
00992 size_t ArraySize(const Element (&)[Size])
00993 {
00994     return Size;
00995 }
00996 
00997 #endif
00998 
00999 END_STD_SCOPE
01000 
01001 
01002 /* @} */
01003 
01004 #endif  /* CORELIB___NCBIMISC__HPP */
01005 
01006 

Generated on Sun Dec 6 21:58:51 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Dec 07 16:20:35 2009 by modify_doxy.py rev. 173732