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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: static_set.hpp,v $
  4.  * PRODUCTION Revision 1000.0  2004/02/12 22:03:20  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [CORE_001] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef UTIL___STATIC_SET__HPP
  10. #define UTIL___STATIC_SET__HPP
  11. /*  $Id: static_set.hpp,v 1000.0 2004/02/12 22:03:20 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.  * Authors:  Mike DiCuccio
  37.  *
  38.  * File Description:
  39.  *     CStaticArraySet<> -- template class to provide convenient access to
  40.  *                          a statically-defined array, while making sure that
  41.  *                          the order of the array meets sort criteria in
  42.  *                          debug builds.
  43.  *
  44.  */
  45. #include <utility>
  46. #include <algorithm>
  47. #include <functional>
  48. BEGIN_NCBI_SCOPE
  49. ///
  50. /// class CStaticArraySet<> is an array adaptor that provides an STLish
  51. /// interface to statically-defined arrays, while making efficient use
  52. /// of the inherent sort order of such arrays.
  53. ///
  54. /// This class can be used both to verify sorted order of a static array
  55. /// and to access a static array cleanly.  The template parameters are
  56. /// as follows:
  57. ///
  58. ///   KeyType    -- type of object used for access
  59. ///   KeyCompare -- comparison functor.  This must provide an operator(). 
  60. ///         This is patterned to accept PCase and PNocase and similar objects.
  61. ///
  62. /// To use this class, define your static array as follows:
  63. ///
  64. ///  static const char* sc_MyArray[] = {
  65. ///      "val1",
  66. ///      "val2",
  67. ///      "val3"
  68. ///  };
  69. ///
  70. /// Then, declare a static variable such as:
  71. ///
  72. ///     typedef StaticArraySet<const char*, PNocase> TStaticArray;
  73. ///     static TStaticArray sc_Array(sc_MyArray, sizeof(sc_MyArray));
  74. ///
  75. /// In debug mode, the constructor will scan the list of items and insure
  76. /// that they are in the sort order defined by the comparator used.  If the
  77. /// sort order is not correct, then the constructor will ASSERT().
  78. ///
  79. /// This can then be accessed as
  80. ///
  81. ///     if (sc_Array.find(some_value) != sc_Array.end()) {
  82. ///         ...
  83. ///     }
  84. ///
  85. /// or
  86. ///
  87. ///     size_t idx = sc_Array.index_of(some_value);
  88. ///     if (idx != TStaticArray::eNpos) {
  89. ///         ...
  90. ///     }
  91. ///
  92. ///
  93. template <typename KeyType, typename ValueType, typename ValueCompare>
  94. class CStaticArraySearchBase
  95. {
  96. public:
  97.     enum {
  98.         eNpos = -1
  99.     };
  100.     typedef KeyType             key_type;
  101.     typedef ValueType           value_type;
  102.     typedef ValueCompare        value_compare;
  103.     typedef const value_type&   const_reference;
  104.     typedef const value_type*   const_iterator;
  105.     typedef size_t              size_type;
  106.     typedef ssize_t             difference_type;
  107.     /// Default constructor.  This will build a set around a given array; the
  108.     /// storage of the end pointer is based on the supplied array size.  In
  109.     /// debug mode, this will verify that the array is sorted.
  110.     CStaticArraySearchBase(const_iterator obj, size_type array_size)
  111.         : m_Begin(obj)
  112.         , m_End(obj + array_size / sizeof(value_type))
  113.     {
  114.         x_Validate();
  115.     }
  116.     /// Constructor to initialize comparator object.
  117.     CStaticArraySearchBase(const_iterator obj, size_type array_size,
  118.                            const value_compare& comp)
  119.         : m_Begin(obj)
  120.         , m_End(obj + array_size / sizeof(value_type))
  121.         , m_Compare(comp)
  122.     {
  123.         x_Validate();
  124.     }
  125.     /// Return the start of the controlled sequence.
  126.     const_iterator begin() const
  127.     {
  128.         return m_Begin;
  129.     }
  130.     /// Return the end of the controlled sequence.
  131.     const_iterator end() const
  132.     {
  133.         return m_End;
  134.     }
  135.     /// Return true if the container is empty.
  136.     bool empty() const
  137.     {
  138.         return begin() == end();
  139.     }
  140.     /// Return number of elements in the container.
  141.     size_type size() const
  142.     {
  143.         return end() - begin();
  144.     }
  145.     /// Return an iterator into the sequence such that the iterator's key
  146.     /// is less than or equal to the indicated key.
  147.     const_iterator lower_bound(const key_type& key) const
  148.     {
  149.         return std::lower_bound(begin(), end(), key, m_Compare);
  150.     }
  151.     /// Return an iterator into the sequence such that the iterator's key
  152.     /// is greater than the indicated key.
  153.     const_iterator upper_bound(const key_type& key) const
  154.     {
  155.         return std::upper_bound(begin(), end(), key, m_Compare);
  156.     }
  157.     /// Return a const_iterator pointing to the specified element, or
  158.     /// to the end if the element is not found.
  159.     const_iterator find(const key_type& key) const
  160.     {
  161.         const_iterator iter = lower_bound(key);
  162.         return x_Bad(key, iter)? end(): iter;
  163.     }
  164.     /// Return the count of the elements in the sequence.  This will be
  165.     /// either 0 or 1, as this structure holds unique keys.
  166.     size_type count(const key_type& key) const
  167.     {
  168.         const_iterator iter = lower_bound(key);
  169.         return x_Bad(key, iter)? 0: 1;
  170.     }
  171.     /// Return a pair of iterators bracketing the given element in
  172.     /// the controlled sequence.
  173.     pair<const_iterator, const_iterator> equal_range(const key_type& key) const
  174.     {
  175.         const_iterator start = lower_bound(key);
  176.         const_iterator iter  = start;
  177.         if ( !x_Bad(key, iter) ) {
  178.             ++iter;
  179.         }
  180.         return make_pair(start, iter);
  181.     }
  182.     /// Return the index of the indicated element, or eNpos if the element is
  183.     /// not found.
  184.     difference_type index_of(const key_type& key) const
  185.     {
  186.         const_iterator iter = lower_bound(key);
  187.         return x_Bad(key, iter)? eNpos: iter - begin();
  188.     }
  189.     const value_compare& value_comp() const
  190.     {
  191.         return m_Compare;
  192.     }
  193. private:
  194.     const_iterator m_Begin;
  195.     const_iterator m_End;
  196.     value_compare m_Compare;
  197.     bool x_Bad(const key_type& key, const_iterator iter) const
  198.     {
  199.         return iter == end()  ||  m_Compare(key, *iter);
  200.     }
  201.     /// Perform sort-order validation.  This is a no-op in release mode.
  202.     void x_Validate() const
  203.     {
  204. #ifdef _DEBUG
  205.         if ( !empty() ) {
  206.             const_iterator curr = begin(), prev = curr;
  207.             while ( ++curr != end() ) {
  208.                 _ASSERT( m_Compare(*prev, *curr) );
  209.                 prev = curr;
  210.             }
  211.         }
  212. #endif
  213.     }
  214. };
  215. template <class KeyType, class KeyCompare = less<KeyType> >
  216. class CStaticArraySet
  217.     : public CStaticArraySearchBase<KeyType, KeyType, KeyCompare>
  218. {
  219.     typedef CStaticArraySearchBase<KeyType, KeyType, KeyCompare> TBase;
  220. public:
  221.     typedef typename TBase::key_type        key_type;
  222.     typedef KeyCompare                      key_compare;
  223.     typedef typename TBase::value_type      value_type;
  224.     typedef typename TBase::value_compare   value_compare;
  225.     typedef typename TBase::const_reference const_reference;
  226.     typedef typename TBase::const_iterator  const_iterator;
  227.     typedef typename TBase::size_type       size_type;
  228.     typedef typename TBase::difference_type difference_type;
  229.     /// default constructor.  This will build a map around a given array; the
  230.     /// storage of the end pointer is based on the supplied array size.  In
  231.     /// debug mode, this will verify that the array is sorted.
  232.     CStaticArraySet(const_iterator obj, size_type array_size)
  233.         : TBase(obj, array_size)
  234.     {
  235.     }
  236.     /// Constructor to initialize comparator object.
  237.     CStaticArraySet(const_iterator obj, size_type array_size,
  238.                     const key_compare& comp)
  239.         : TBase(obj, array_size, comp)
  240.     {
  241.     }
  242.     /// Return the key comparison object
  243.     const key_compare& key_comp() const
  244.     {
  245.         return value_compare();
  246.     }
  247. };
  248. END_NCBI_SCOPE
  249. /*
  250.  * ===========================================================================
  251.  * $Log: static_set.hpp,v $
  252.  * Revision 1000.0  2004/02/12 22:03:20  gouriano
  253.  * PRODUCTION: IMPORTED [CORE_001] Dev-tree R1.1
  254.  *
  255.  * Revision 1.1  2004/01/23 18:02:23  vasilche
  256.  * Cleaned implementation of CStaticArraySet & CStaticArrayMap.
  257.  * Added test utility test_staticmap.
  258.  *
  259.  * Revision 1.2  2004/01/22 14:51:03  dicuccio
  260.  * Fixed erroneous variable names
  261.  *
  262.  * Revision 1.1  2004/01/22 13:22:12  dicuccio
  263.  * Initial revision
  264.  *
  265.  * ===========================================================================
  266.  */
  267. #endif  // UTIL___STATIC_SET__HPP