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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: optional.hpp,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 18:24:29  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef APP_BLAST_CLIENT___OPTIONAL__HPP
  10. #define APP_BLAST_CLIENT___OPTIONAL__HPP
  11. /*  $Id: optional.hpp,v 1000.0 2003/10/29 18:24:29 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. /// Optional value idiom for blast_client.
  40. ///
  41. /// Optional value concept (but not the actual code) is from the Boost
  42. /// libraries.  Many times in programming, we have the concept of a
  43. /// parameter which can either take a value or be omitted.  The
  44. /// Optional<> template expresses this idea directly in code, wrapping
  45. /// any value type.  Each optional object contains a boolean which is
  46. /// set to true if there is a meaningful value present, or false
  47. /// otherwise.  Attempts to read a false value will result in an
  48. /// assertion.  The presence of the value can be checked.  Also
  49. /// provided are functions which return an optional value from a CArgs
  50. /// object based on name; CArgs (unlike the C toolkit counterpart)
  51. /// preserves the information of whether an option was selected or
  52. /// omitted.  This obviates the need for 'sentinel' values, special
  53. /// "unreasonable" default values for each parameter, used to detect
  54. /// the absence of the parameter.  Optional values semantics are
  55. /// important to blast_client because of the design of the blast4
  56. /// (netblast) network protocols.  This design states that the blast4
  57. /// server would provide default values for (most) options if a value
  58. /// is not specified by the client.  It is therefore important to
  59. /// track which optional values are present.
  60. #include <corelib/ncbiargs.hpp>
  61. BEGIN_NCBI_SCOPE
  62. /// Optional template - wrap any value type as an optional value.
  63. ///
  64. /// Optional template - any value type may be wrapped as an optional
  65. /// value.  If no value has been set, the object is considered invalid
  66. /// and will fail an assertion if an attempt is made to read the
  67. /// value.  This class also provides a few basic 'logic' operations on
  68. /// optional values.
  69. template <typename T>
  70. class COptional
  71. {
  72. public:
  73.     /// Value constructor - produces a valid (present) object.
  74.     ///
  75.     /// Copy the value from the value type, set object to valid.
  76.     //  @param value The value to set.
  77.     COptional(T value)
  78.         : m_Value(value),
  79.           m_Exists(true)
  80.     {
  81.     }
  82.     
  83.     /// Copy constructor - copies an existing object.
  84.     ///
  85.     /// Copy from another optional object.
  86.     /// @param other COptional object (valid or not) to copy.
  87.     COptional(const COptional<T> & other)
  88.         : m_Exists(other.m_Exists)
  89.     {
  90.         if (m_Exists) {
  91.             m_Value = other.m_Value;
  92.         }
  93.     }
  94.     
  95.     /// Blank constructor - construct an invalid object.
  96.     COptional(void)
  97.         : m_Exists(false)
  98.     {
  99.     }
  100.     
  101.     /// Returns true if the value is present/exists.
  102.     bool Exists(void) const
  103.     {
  104.         return m_Exists;
  105.     }
  106.     
  107.     /// Returns the value, or throws an assertion (if not valid).
  108.     const T & GetValue(void) const
  109.     {
  110.         _ASSERT(m_Exists);
  111.         return m_Value;
  112.     }
  113.         
  114.     /// Boolean max() operator - return the max of existing values.
  115.     ///
  116.     /// If both arguments exist: return the max.  If neither argument
  117.     /// exists, returns an invalid object.  Otherwise, one argument
  118.     /// exists, so return that object.
  119.     ///
  120.     /// @param lhs One argument.
  121.     /// @param rhs The other argument.
  122.     static COptional<T> Max(const COptional<T> & lhs,
  123.                             const COptional<T> & rhs);
  124.     
  125.     /// Boolean min() operator - return the min of existing values.
  126.     ///
  127.     /// If both arguments exist: return the min.  If neither argument
  128.     /// exists, returns an invalid object.  Otherwise, one argument
  129.     /// exists, so return that object.
  130.     ///
  131.     /// @param lhs One argument.
  132.     /// @param rhs The other argument.
  133.     static COptional<T> Min(const COptional<T> & lhs,
  134.                             const COptional<T> & rhs);
  135.     
  136.     /// Unary inversion operator - return the inverse of the value.
  137.     ///
  138.     /// If the argument exists: return ! value().  Otherwise, return
  139.     /// an invalid object.
  140.     ///
  141.     /// @param v The (possibly unset) value.
  142.     
  143.     static COptional<T> Invert(const COptional<T> & v);
  144.     
  145.     /// Assignment operator.
  146.     ///
  147.     /// Copy the state of another object.  If it exists, copy
  148.     /// the value as well.
  149.     
  150.     const COptional<T> & operator= (const COptional<T> & other)
  151.     {
  152.         if (this != &other) {
  153.             m_Exists = other.m_Exists;
  154.                         
  155.             if (m_Exists) {
  156.                 m_Value = other.m_Value;
  157.             }
  158.         }
  159.                 
  160.         return *this;
  161.     }
  162.         
  163. private:
  164.     /// The actual value (if m_Exists is true).
  165.     T    m_Value;
  166.     
  167.     /// If true, m_Value is meaningful.
  168.     bool m_Exists;
  169. };
  170. using std::string;
  171. /// Optional integer.
  172. typedef COptional<int>            TOptInteger;
  173. /// Optional bool.
  174. typedef COptional<bool>           TOptBool;
  175. /// Optional double prec float.
  176. typedef COptional<double>         TOptDouble;
  177. /// Optional string (pointer) value - be sure to delete the actual object.
  178. typedef COptional<string> TOptString;
  179. /// Optional input stream pointer - be sure to delete the actual object.
  180. typedef COptional<CNcbiIstream *> TOptInfile;
  181. /// Get existence and value from a boolean program parameter.
  182. inline TOptBool CheckArgsBool(const CArgValue & val)
  183. {
  184.     if (val.HasValue()) {
  185.         return TOptBool(val.AsBoolean());
  186.     } else {
  187.         return TOptBool();
  188.     }
  189. }
  190. /// Get existence and value from a double program parameter.
  191. inline TOptDouble CheckArgsDouble(const CArgValue & val)
  192. {
  193.     if (val.HasValue()) {
  194.         return TOptDouble(val.AsDouble());
  195.     } else {
  196.         return TOptDouble();
  197.     }
  198. }
  199. /// Get existence and value from an integer program parameter.
  200. inline TOptInteger CheckArgsInteger(const CArgValue & val)
  201. {
  202.     if (val.HasValue()) {
  203.         return TOptInteger(val.AsInteger());
  204.     } else {
  205.         return TOptInteger();
  206.     }
  207. }
  208. /// Get existence and value from a string program parameter.
  209. inline TOptString CheckArgsString(const CArgValue & val)
  210. {
  211.     if (val.HasValue()) {
  212.         return TOptString(val.AsString());
  213.     } else {
  214.         return TOptString();
  215.     }
  216. }
  217. template <class T>
  218. inline COptional<T> COptional<T>::Max(const COptional<T> & lhs,
  219.                                       const COptional<T> & rhs)
  220. {
  221.     COptional<T> result;
  222.                 
  223.     if (lhs.m_Exists) {
  224.         if (rhs.m_Exists) {
  225.             result.m_Exists = true;
  226.             result.m_Value = ((lhs.m_Value > rhs.m_Value)
  227.                               ? lhs.m_Value
  228.                               : rhs.m_Value);
  229.         } else {
  230.             result = lhs;
  231.         }
  232.     } else {
  233.         if (rhs.m_Exists) {
  234.             result = rhs;
  235.         }
  236.     }
  237.                 
  238.     return result;
  239. }
  240. template <class T>
  241. inline COptional<T> COptional<T>::Min(const COptional<T> & lhs,
  242.                                       const COptional<T> & rhs)
  243. {
  244.     COptional<T> result;
  245.                 
  246.     if (lhs.m_Exists) {
  247.         if (rhs.m_Exists) {
  248.             result.m_Exists = true;
  249.             result.m_Value = ((lhs.m_Value < rhs.m_Value)
  250.                               ? lhs.m_Value
  251.                               : rhs.m_Value);
  252.         } else {
  253.             result = lhs;
  254.         }
  255.     } else {
  256.         if (rhs.m_Exists) {
  257.             result = rhs;
  258.         }
  259.     }
  260.                 
  261.     return result;
  262. }
  263. template <class T>
  264. inline COptional<T> COptional<T>::Invert(const COptional<T> & v)
  265. {
  266.     COptional<T> result;
  267.     
  268.     if (v.m_Exists) {
  269.         result.m_Exists = true;
  270.         result.m_Value = ! v.m_Value;
  271.     }
  272.     
  273.     return result;
  274. }
  275. /*
  276.  * ===========================================================================
  277.  *
  278.  * $Log: optional.hpp,v $
  279.  * Revision 1000.0  2003/10/29 18:24:29  gouriano
  280.  * PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1
  281.  *
  282.  * Revision 1.1  2003/09/26 16:53:49  bealer
  283.  * - Add blast_client project for netblast protocol, initial code commit.
  284.  *
  285.  * ===========================================================================
  286.  */
  287. END_NCBI_SCOPE
  288. #endif // APP_BLAST_CLIENT___OPTIONAL__HPP