LCOV - code coverage report
Current view: top level - gfx/graphite2/src/inc - Sparse.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 37 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*  GRAPHITE2 LICENSING
       2             : 
       3             :     Copyright 2011, SIL International
       4             :     All rights reserved.
       5             : 
       6             :     This library is free software; you can redistribute it and/or modify
       7             :     it under the terms of the GNU Lesser General Public License as published
       8             :     by the Free Software Foundation; either version 2.1 of License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     This program is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :     Lesser General Public License for more details.
      15             : 
      16             :     You should also have received a copy of the GNU Lesser General Public
      17             :     License along with this library in the file named "LICENSE".
      18             :     If not, write to the Free Software Foundation, 51 Franklin Street, 
      19             :     Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
      20             :     internet at http://www.fsf.org/licenses/lgpl.html.
      21             : 
      22             : Alternatively, the contents of this file may be used under the terms of the
      23             : Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
      24             : License, as published by the Free Software Foundation, either version 2
      25             : of the License or (at your option) any later version.
      26             : */
      27             : #pragma once
      28             : #include <iterator>
      29             : #include <utility>
      30             : 
      31             : #include "inc/Main.h"
      32             : 
      33             : namespace graphite2 {
      34             : 
      35             : 
      36             : // A read-only packed fast sparse array of uint16 with uint16 keys.
      37             : // Like most container classes this has capacity and size properties and these
      38             : // refer to the number of stored entries and the number of addressable entries
      39             : // as normal. However due the sparse nature the capacity is always <= than the
      40             : // size.
      41             : class sparse
      42             : {
      43             : public:
      44             :     typedef uint16  key_type;
      45             :     typedef uint16  mapped_type;
      46             :     typedef std::pair<const key_type, mapped_type> value_type;
      47             : 
      48             : private:
      49             :     typedef unsigned long   mask_t;
      50             : 
      51             :     static const unsigned char  SIZEOF_CHUNK = (sizeof(mask_t) - sizeof(key_type))*8;
      52             : 
      53             :     struct chunk
      54             :     {
      55             :         mask_t          mask:SIZEOF_CHUNK;
      56             :         key_type        offset;
      57             :     };
      58             : 
      59             :     static const chunk  empty_chunk;
      60             :     sparse(const sparse &);
      61             :     sparse & operator = (const sparse &);
      62             : 
      63             : public:
      64             :     template<typename I>
      65             :     sparse(I first, const I last);
      66             :     sparse() throw();
      67             :     ~sparse() throw();
      68             : 
      69             :     operator bool () const throw();
      70             :     mapped_type     operator [] (const key_type k) const throw();
      71             : 
      72             :     size_t capacity() const throw();
      73             :     size_t size()     const throw();
      74             : 
      75             :     size_t _sizeof() const throw();
      76             :     
      77             :     CLASS_NEW_DELETE;
      78             : 
      79             : private:
      80             :     union {
      81             :         chunk         * map;
      82             :         mapped_type   * values;
      83             :     }           m_array;
      84             :     key_type    m_nchunks;
      85             : };
      86             : 
      87             : 
      88             : inline
      89           0 : sparse::sparse() throw() : m_nchunks(0)
      90             : {
      91           0 :     m_array.map = const_cast<graphite2::sparse::chunk *>(&empty_chunk);
      92           0 : }
      93             : 
      94             : 
      95             : template <typename I>
      96           0 : sparse::sparse(I attr, const I last)
      97           0 : : m_nchunks(0)
      98             : {
      99           0 :     m_array.map = 0;
     100             : 
     101             :     // Find the maximum extent of the key space.
     102           0 :     size_t n_values=0;
     103           0 :     long lastkey = -1;
     104           0 :     for (I i = attr; i != last; ++i, ++n_values)
     105             :     {
     106           0 :         const typename std::iterator_traits<I>::value_type v = *i;
     107           0 :         if (v.second == 0)      { --n_values; continue; }
     108           0 :         if (v.first <= lastkey) { m_nchunks = 0; return; }
     109             : 
     110           0 :         lastkey = v.first;
     111           0 :         const key_type k = v.first / SIZEOF_CHUNK;
     112           0 :         if (k >= m_nchunks) m_nchunks = k+1;
     113             :     }
     114           0 :     if (m_nchunks == 0)
     115             :     {
     116           0 :         m_array.map=const_cast<graphite2::sparse::chunk *>(&empty_chunk);
     117           0 :         return;
     118             :     }
     119             : 
     120           0 :     m_array.values = grzeroalloc<mapped_type>((m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)
     121           0 :                                                  / sizeof(mapped_type)
     122             :                                                  + n_values);
     123             : 
     124           0 :     if (m_array.values == 0)
     125             :     {
     126           0 :         free(m_array.values); m_array.map=0;
     127           0 :         return;
     128             :     }
     129             : 
     130             :     // coverity[forward_null : FALSE] Since m_array is union and m_array.values is not NULL
     131           0 :     chunk * ci = m_array.map;
     132           0 :     ci->offset = (m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)/sizeof(mapped_type);
     133           0 :     mapped_type * vi = m_array.values + ci->offset;
     134           0 :     for (; attr != last; ++attr, ++vi)
     135             :     {
     136           0 :         const typename std::iterator_traits<I>::value_type v = *attr;
     137           0 :         if (v.second == 0)  { --vi; continue; }
     138             : 
     139           0 :         chunk * const ci_ = m_array.map + v.first/SIZEOF_CHUNK;
     140             : 
     141           0 :         if (ci != ci_)
     142             :         {
     143           0 :             ci = ci_;
     144           0 :             ci->offset = vi - m_array.values;
     145             :         }
     146             : 
     147           0 :         ci->mask |= 1UL << (SIZEOF_CHUNK - 1 - (v.first % SIZEOF_CHUNK));
     148           0 :         *vi = v.second;
     149             :     }
     150             : }
     151             : 
     152             : 
     153             : inline
     154           0 : sparse::operator bool () const throw()
     155             : {
     156           0 :     return m_array.map != 0;
     157             : }
     158             : 
     159             : inline
     160             : size_t sparse::size() const throw()
     161             : {
     162             :     return m_nchunks*SIZEOF_CHUNK;
     163             : }
     164             : 
     165             : inline
     166             : size_t sparse::_sizeof() const throw()
     167             : {
     168             :     return sizeof(sparse) + capacity()*sizeof(mapped_type) + m_nchunks*sizeof(chunk);
     169             : }
     170             : 
     171             : } // namespace graphite2

Generated by: LCOV version 1.13