optional.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:10k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: optional.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:06:46  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef ALGO_BLAST_API_DEMO___OPTIONAL__HPP
  10. #define ALGO_BLAST_API_DEMO___OPTIONAL__HPP
  11. /*  $Id: optional.hpp,v 1000.1 2004/06/01 18:06:46 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author:  Kevin Bealer
  37.  *
  38.  */
  39. /// @file optional.hpp
  40. /// Optional value idiom for remote_blast.
  41. ///
  42. /// Optional value concept (but not the actual code) is from the Boost
  43. /// libraries.  Many times in programming, we have the concept of a
  44. /// parameter which can either take a value or be omitted.  The
  45. /// Optional<> template expresses this idea directly in code, wrapping
  46. /// any value type.  Each optional object contains a boolean which is
  47. /// set to true if there is a meaningful value present, or false
  48. /// otherwise.  Attempts to read a false value will result in an
  49. /// assertion.  The presence of the value can be checked.  Also
  50. /// provided are functions which return an optional value from a CArgs
  51. /// object based on name; CArgs (unlike the C toolkit counterpart)
  52. /// preserves the information of whether an option was selected or
  53. /// omitted.  This obviates the need for 'sentinel' values, special
  54. /// "unreasonable" default values for each parameter, used to detect
  55. /// the absence of the parameter.  Optional values semantics are
  56. /// important to remote_blast because of the design of the blast4
  57. /// (netblast) network protocols.  This design states that the blast4
  58. /// server would provide default values for (most) options if a value
  59. /// is not specified by the client.  It is therefore important to
  60. /// track which optional values are present.
  61. #include <corelib/ncbiargs.hpp>
  62. BEGIN_NCBI_SCOPE
  63. /// Optional template - wrap any value type as an optional value.
  64. ///
  65. /// Optional template - any value type may be wrapped as an optional
  66. /// value.  If no value has been set, the object is considered invalid
  67. /// and will fail an assertion if an attempt is made to read the
  68. /// value.  This class also provides a few basic 'logic' operations on
  69. /// optional values.
  70. template <typename T>
  71. class COptional
  72. {
  73. public:
  74.     /// Value constructor - produces a valid (present) object.
  75.     ///
  76.     /// Copy the value from the value type, set object to valid.
  77.     //  @param value The value to set.
  78.     COptional(T value)
  79.         : m_Value(value),
  80.           m_Exists(true)
  81.     {
  82.     }
  83.     
  84.     /// Copy constructor - copies an existing object.
  85.     ///
  86.     /// Copy from another optional object.
  87.     /// @param other COptional object (valid or not) to copy.
  88.     COptional(const COptional<T> & other)
  89.         : m_Exists(other.m_Exists)
  90.     {
  91.         if (m_Exists) {
  92.             m_Value = other.m_Value;
  93.         }
  94.     }
  95.     
  96.     /// Blank constructor - construct an invalid object.
  97.     COptional(void)
  98.         : m_Exists(false)
  99.     {
  100.     }
  101.     
  102.     /// Returns true if the value is present/exists.
  103.     bool Exists(void) const
  104.     {
  105.         return m_Exists;
  106.     }
  107.     
  108.     /// Returns the value, or throws an assertion (if not valid).
  109.     const T & GetValue(void) const
  110.     {
  111.         _ASSERT(m_Exists);
  112.         return m_Value;
  113.     }
  114.         
  115.     /// Boolean max() operator - return the max of existing values.
  116.     ///
  117.     /// If both arguments exist: return the max.  If neither argument
  118.     /// exists, returns an invalid object.  Otherwise, one argument
  119.     /// exists, so return that object.
  120.     ///
  121.     /// @param lhs One argument.
  122.     /// @param rhs The other argument.
  123.     static COptional<T> Max(const COptional<T> & lhs,
  124.                             const COptional<T> & rhs);
  125.     
  126.     /// Boolean min() operator - return the min of existing values.
  127.     ///
  128.     /// If both arguments exist: return the min.  If neither argument
  129.     /// exists, returns an invalid object.  Otherwise, one argument
  130.     /// exists, so return that object.
  131.     ///
  132.     /// @param lhs One argument.
  133.     /// @param rhs The other argument.
  134.     static COptional<T> Min(const COptional<T> & lhs,
  135.                             const COptional<T> & rhs);
  136.     
  137.     /// Unary inversion operator - return the inverse of the value.
  138.     ///
  139.     /// If the argument exists: return ! value().  Otherwise, return
  140.     /// an invalid object.
  141.     ///
  142.     /// @param v The (possibly unset) value.
  143.     
  144.     static COptional<T> Invert(const COptional<T> & v);
  145.     
  146.     /// Assignment operator.
  147.     ///
  148.     /// Copy the state of another object.  If it exists, copy
  149.     /// the value as well.
  150.     
  151.     const COptional<T> & operator= (const COptional<T> & other)
  152.     {
  153.         if (this != &other) {
  154.             m_Exists = other.m_Exists;
  155.                         
  156.             if (m_Exists) {
  157.                 m_Value = other.m_Value;
  158.             }
  159.         }
  160.                 
  161.         return *this;
  162.     }
  163.         
  164. private:
  165.     /// The actual value (if m_Exists is true).
  166.     T    m_Value;
  167.     
  168.     /// If true, m_Value is meaningful.
  169.     bool m_Exists;
  170. };
  171. using std::string;
  172. /// Optional integer.
  173. typedef COptional<int>            TOptInteger;
  174. /// Optional bool.
  175. typedef COptional<bool>           TOptBool;
  176. /// Optional double prec float.
  177. typedef COptional<double>         TOptDouble;
  178. /// Optional string (pointer) value - be sure to delete the actual object.
  179. typedef COptional<string> TOptString;
  180. /// Optional input stream pointer - be sure to delete the actual object.
  181. typedef COptional<CNcbiIstream *> TOptInfile;
  182. /// Get existence and value from a boolean program parameter.
  183. inline TOptBool CheckArgsBool(const CArgValue & val)
  184. {
  185.     if (val.HasValue()) {
  186.         return TOptBool(val.AsBoolean());
  187.     } else {
  188.         return TOptBool();
  189.     }
  190. }
  191. /// Get existence and value from a double program parameter.
  192. inline TOptDouble CheckArgsDouble(const CArgValue & val)
  193. {
  194.     if (val.HasValue()) {
  195.         return TOptDouble(val.AsDouble());
  196.     } else {
  197.         return TOptDouble();
  198.     }
  199. }
  200. /// Get existence and value from an integer program parameter.
  201. inline TOptInteger CheckArgsInteger(const CArgValue & val)
  202. {
  203.     if (val.HasValue()) {
  204.         return TOptInteger(val.AsInteger());
  205.     } else {
  206.         return TOptInteger();
  207.     }
  208. }
  209. /// Get existence and value from a string program parameter.
  210. inline TOptString CheckArgsString(const CArgValue & val)
  211. {
  212.     if (val.HasValue()) {
  213.         return TOptString(val.AsString());
  214.     } else {
  215.         return TOptString();
  216.     }
  217. }
  218. template <class T>
  219. inline COptional<T> COptional<T>::Max(const COptional<T> & lhs,
  220.                                       const COptional<T> & rhs)
  221. {
  222.     COptional<T> result;
  223.                 
  224.     if (lhs.m_Exists) {
  225.         if (rhs.m_Exists) {
  226.             result.m_Exists = true;
  227.             result.m_Value = ((lhs.m_Value > rhs.m_Value)
  228.                               ? lhs.m_Value
  229.                               : rhs.m_Value);
  230.         } else {
  231.             result = lhs;
  232.         }
  233.     } else {
  234.         if (rhs.m_Exists) {
  235.             result = rhs;
  236.         }
  237.     }
  238.                 
  239.     return result;
  240. }
  241. template <class T>
  242. inline COptional<T> COptional<T>::Min(const COptional<T> & lhs,
  243.                                       const COptional<T> & rhs)
  244. {
  245.     COptional<T> result;
  246.                 
  247.     if (lhs.m_Exists) {
  248.         if (rhs.m_Exists) {
  249.             result.m_Exists = true;
  250.             result.m_Value = ((lhs.m_Value < rhs.m_Value)
  251.                               ? lhs.m_Value
  252.                               : rhs.m_Value);
  253.         } else {
  254.             result = lhs;
  255.         }
  256.     } else {
  257.         if (rhs.m_Exists) {
  258.             result = rhs;
  259.         }
  260.     }
  261.                 
  262.     return result;
  263. }
  264. template <class T>
  265. inline COptional<T> COptional<T>::Invert(const COptional<T> & v)
  266. {
  267.     COptional<T> result;
  268.     
  269.     if (v.m_Exists) {
  270.         result.m_Exists = true;
  271.         result.m_Value = ! v.m_Value;
  272.     }
  273.     
  274.     return result;
  275. }
  276. /*
  277.  * ===========================================================================
  278.  *
  279.  * $Log: optional.hpp,v $
  280.  * Revision 1000.1  2004/06/01 18:06:46  gouriano
  281.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  282.  *
  283.  * Revision 1.2  2004/05/19 14:52:02  camacho
  284.  * 1. Added doxygen tags to enable doxygen processing of algo/blast/core
  285.  * 2. Standardized copyright, CVS $Id string, $Log and rcsid formatting and i
  286.  *    location
  287.  * 3. Added use of @todo doxygen keyword
  288.  *
  289.  * Revision 1.1  2004/02/18 17:04:41  bealer
  290.  * - Adapt blast_client code for Remote Blast API, merging code into the
  291.  *   remote_blast demo application.
  292.  *
  293.  * ===========================================================================
  294.  */
  295. END_NCBI_SCOPE
  296. #endif // ALGO_BLAST_API_DEMO___OPTIONAL__HPP