LCOV - code coverage report
Current view: top level - usr/include/boost/spirit/home/classic/symbols/impl - tst.ipp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 73 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*=============================================================================
       2             :     Copyright (c) 2001-2003 Joel de Guzman
       3             :     http://spirit.sourceforge.net/
       4             : 
       5             :     Use, modification and distribution is subject to the Boost Software
       6             :     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
       7             :     http://www.boost.org/LICENSE_1_0.txt)
       8             : =============================================================================*/
       9             : #ifndef BOOST_SPIRIT_TST_IPP
      10             : #define BOOST_SPIRIT_TST_IPP
      11             : 
      12             : ///////////////////////////////////////////////////////////////////////////////
      13             : #include <boost/move/unique_ptr.hpp>
      14             : #include <boost/spirit/home/classic/core/assert.hpp>
      15             : 
      16             : ///////////////////////////////////////////////////////////////////////////////
      17             : namespace boost { namespace spirit {
      18             : 
      19             : BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
      20             : 
      21             :     namespace impl
      22             :     {
      23             : 
      24             : ///////////////////////////////////////////////////////////////////////////////
      25             : //
      26             : //  tst class
      27             : //
      28             : //      Ternary Search Tree implementation. The data structure is faster than
      29             : //      hashing for many typical search problems especially when the search
      30             : //      interface is iterator based. Searching for a string of length k in a
      31             : //      ternary search tree with n strings will require at most O(log n+k)
      32             : //      character comparisons. TSTs are many times faster than hash tables
      33             : //      for unsuccessful searches since mismatches are discovered earlier
      34             : //      after examining only a few characters. Hash tables always examine an
      35             : //      entire key when searching.
      36             : //
      37             : //      For details see http://www.cs.princeton.edu/~rs/strings/.
      38             : //
      39             : //      *** This is a low level class and is
      40             : //          not meant for public consumption ***
      41             : //
      42             : ///////////////////////////////////////////////////////////////////////////////
      43             :     template <typename T, typename CharT>
      44             :     struct tst_node
      45             :     {
      46           0 :         tst_node(CharT value_)
      47             :         : value(value_)
      48             :         , left(0)
      49           0 :         , right(0)
      50           0 :         { middle.link = 0; }
      51             : 
      52           0 :         ~tst_node()
      53             :         {
      54           0 :             delete left;
      55           0 :             delete right;
      56           0 :             if (value)
      57           0 :                 delete middle.link;
      58             :             else
      59           0 :                 delete middle.data;
      60           0 :         }
      61             : 
      62             :         tst_node*
      63             :         clone() const
      64             :         {
      65             :             boost::movelib::unique_ptr<tst_node> copy(new tst_node(value));
      66             : 
      67             :             if (left)
      68             :                 copy->left = left->clone();
      69             :             if (right)
      70             :                 copy->right = right->clone();
      71             : 
      72             :             if (value && middle.link)
      73             :             {
      74             :                 copy->middle.link = middle.link->clone();
      75             :             }
      76             :             else
      77             :             {
      78             :                 boost::movelib::unique_ptr<T> mid_data(new T(*middle.data));
      79             :                 copy->middle.data = mid_data.release();
      80             :             }
      81             : 
      82             :             return copy.release();
      83             :         }
      84             : 
      85             :         union center {
      86             : 
      87             :             tst_node*   link;
      88             :             T*          data;
      89             :         };
      90             : 
      91             :         CharT       value;
      92             :         tst_node*   left;
      93             :         center      middle;
      94             :         tst_node*   right;
      95             :     };
      96             : 
      97             :     ///////////////////////////////////////////////////////////////////////////
      98             :     template <typename T, typename CharT>
      99             :     class tst
     100             :     {
     101             :     public:
     102             : 
     103             :         struct search_info
     104             :         {
     105             :             T*          data;
     106             :             std::size_t length;
     107             :         };
     108             : 
     109           0 :         tst()
     110           0 :         : root(0) {}
     111             : 
     112             :         tst(tst const& other)
     113             :         : root(other.root ? other.root->clone() : 0) {}
     114             : 
     115           0 :         ~tst()
     116           0 :         { delete root; }
     117             : 
     118             :         tst&
     119             :         operator=(tst const& other)
     120             :         {
     121             :             if (this != &other)
     122             :             {
     123             :                 node_t* new_root = other.root ? other.root->clone() : 0;
     124             :                 delete root;
     125             :                 root = new_root;
     126             :             }
     127             :             return *this;
     128             :         }
     129             : 
     130             :         template <typename IteratorT>
     131           0 :         T* add(IteratorT first, IteratorT const& last, T const& data)
     132             :         {
     133           0 :             if (first == last)
     134             :                 return 0;
     135             : 
     136           0 :             node_t**  np = &root;
     137           0 :             CharT   ch = *first;
     138             : 
     139           0 :             BOOST_SPIRIT_ASSERT((first == last || ch != 0)
     140             :                 && "Won't add string containing null character");
     141             : 
     142             :             for (;;)
     143             :             {
     144           0 :                 if (*np == 0 || ch == 0)
     145             :                 {
     146             :                     node_t* right = 0;
     147             :                     if (np != 0)
     148             :                         right = *np;
     149           0 :                     *np = new node_t(ch);
     150           0 :                     if (right)
     151           0 :                         (**np).right = right;
     152             :                 }
     153             : 
     154           0 :                 if (ch < (**np).value)
     155             :                 {
     156           0 :                     np = &(**np).left;
     157             :                 }
     158             :                 else
     159             :                 {
     160           0 :                     if (ch == (**np).value)
     161             :                     {
     162           0 :                         if (ch == 0)
     163             :                         {
     164           0 :                             if ((**np).middle.data == 0)
     165             :                             {
     166           0 :                                 (**np).middle.data = new T(data);
     167           0 :                                 return (**np).middle.data;
     168             :                             }
     169             :                             else
     170             :                             {
     171             :                                 //  re-addition is disallowed
     172             :                                 return 0;
     173             :                             }
     174             :                        }
     175           0 :                         ++first;
     176           0 :                         ch = (first == last) ? CharT(0) : *first;
     177           0 :                         BOOST_SPIRIT_ASSERT((first == last || ch != 0)
     178             :                             && "Won't add string containing null character");
     179           0 :                         np = &(**np).middle.link;
     180             :                     }
     181             :                     else
     182             :                     {
     183           0 :                         np = &(**np).right;
     184             :                     }
     185             :                 }
     186             :             }
     187             :         }
     188             : 
     189             :         template <typename ScannerT>
     190           0 :         search_info find(ScannerT const& scan) const
     191             :         {
     192           0 :             search_info result = { 0, 0 };
     193           0 :             if (scan.at_end()) {
     194           0 :                 return result;
     195             :             }
     196             : 
     197             :             typedef typename ScannerT::iterator_t iterator_t;
     198           0 :             node_t*     np = root;
     199           0 :             CharT       ch = *scan;
     200           0 :             iterator_t  save = scan.first;
     201           0 :             iterator_t  latest = scan.first;
     202           0 :             std::size_t latest_len = 0;
     203             : 
     204           0 :             while (np)
     205             :             {
     206             : 
     207           0 :                 if (ch < np->value) // => go left!
     208             :                 {
     209           0 :                     if (np->value == 0)
     210             :                     {
     211           0 :                         result.data = np->middle.data;
     212           0 :                         if (result.data)
     213             :                         {
     214           0 :                             latest = scan.first;
     215           0 :                             latest_len = result.length;
     216             :                         }
     217             :                     }
     218             : 
     219           0 :                     np = np->left;
     220             :                 }
     221           0 :                 else if (ch == np->value) // => go middle!
     222             :                 {
     223             :                     // Matching the null character is not allowed.
     224           0 :                     if (np->value == 0)
     225             :                     {
     226           0 :                         result.data = np->middle.data;
     227           0 :                         if (result.data)
     228             :                         {
     229           0 :                             latest = scan.first;
     230           0 :                             latest_len = result.length;
     231             :                         }
     232             :                         break;
     233             :                     }
     234             : 
     235           0 :                     ++scan;
     236           0 :                     ch = scan.at_end() ? CharT(0) : *scan;
     237           0 :                     np = np->middle.link;
     238           0 :                     ++result.length;
     239             :                 }
     240             :                 else // (ch > np->value) => go right!
     241             :                 {
     242           0 :                     if (np->value == 0)
     243             :                     {
     244           0 :                         result.data = np->middle.data;
     245           0 :                         if (result.data)
     246             :                         {
     247           0 :                             latest = scan.first;
     248           0 :                             latest_len = result.length;
     249             :                         }
     250             :                     }
     251             : 
     252           0 :                     np = np->right;
     253             :                 }
     254             :             }
     255             : 
     256           0 :             if (result.data == 0)
     257             :             {
     258           0 :                 scan.first = save;
     259             :             }
     260             :             else
     261             :             {
     262           0 :                 scan.first = latest;
     263           0 :                 result.length = latest_len;
     264             :             }
     265           0 :             return result;
     266             :         }
     267             : 
     268             :     private:
     269             : 
     270             :         typedef tst_node<T, CharT> node_t;
     271             :         node_t* root;
     272             :     };
     273             : 
     274             : ///////////////////////////////////////////////////////////////////////////////
     275             :     } // namespace impl
     276             : 
     277             : BOOST_SPIRIT_CLASSIC_NAMESPACE_END
     278             : 
     279             : }} // namespace boost::spirit
     280             : 
     281             : #endif

Generated by: LCOV version 1.14