LCOV - code coverage report
Current view: top level - src/bindings/cpp/include - keyset.hpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 90 96 93.8 %
Date: 2019-09-12 12:28:41 Functions: 8 14 57.1 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  */
       8             : 
       9             : #ifndef ELEKTRA_KEYSET_HPP
      10             : #define ELEKTRA_KEYSET_HPP
      11             : 
      12             : #ifndef ELEKTRA_WRONG
      13             : #define ELEKTRA_WRONG // make swig happy
      14             : #endif
      15             : 
      16             : #include <string>
      17             : 
      18             : #include <key.hpp>
      19             : 
      20             : #include <kdb.h>
      21             : 
      22             : namespace kdb
      23             : {
      24             : 
      25             : #ifndef ELEKTRA_WITHOUT_ITERATOR
      26             : class KeySetIterator;
      27             : class KeySetReverseIterator;
      28             : #endif
      29             : 
      30             : 
      31             : /**
      32             :  * @brief Needed to avoid constructor ambiguity
      33             :  *
      34             :  * when ... is same type as va_list
      35             :  */
      36             : struct VaAlloc
      37             : {
      38             :         explicit VaAlloc (size_t size) : alloc (size)
      39             :         {
      40             :         }
      41             :         size_t alloc;
      42             : };
      43             : 
      44             : /**
      45             :  * @brief A keyset holds together a set of keys.
      46             :  *
      47             :  * @copydoc keyset
      48             :  *
      49             :  * \invariant always holds an underlying elektra keyset.
      50             :  *
      51             :  * \note that the cursor is mutable,
      52             :  * so it might be changed even in const functions
      53             :  * as described.
      54             :  * */
      55             : class KeySet
      56             : {
      57             : public:
      58             :         inline KeySet ();
      59             :         inline KeySet (ckdb::KeySet * k);
      60             :         inline KeySet (const KeySet & other);
      61             : 
      62             :         ELEKTRA_WRONG explicit KeySet (Key, ...);
      63             : 
      64             :         inline explicit KeySet (size_t alloc, ...) ELEKTRA_SENTINEL;
      65             :         inline explicit KeySet (VaAlloc alloc, va_list ap);
      66             : 
      67             :         inline ~KeySet ();
      68             : 
      69             :         ckdb::KeySet * release ();
      70             : 
      71             :         ckdb::KeySet * getKeySet () const;
      72             :         void setKeySet (ckdb::KeySet * k);
      73             : 
      74             :         KeySet & operator= (KeySet const & other);
      75             : 
      76             :         ssize_t size () const;
      77             : 
      78             :         ckdb::KeySet * dup () const;
      79             : 
      80             :         void copy (const KeySet & other);
      81             :         void clear ();
      82             : 
      83             :         ssize_t append (const Key & toAppend);
      84             :         ssize_t append (const KeySet & toAppend);
      85             : 
      86             :         Key head () const;
      87             :         Key tail () const;
      88             : 
      89             :         void rewind () const;
      90             :         Key next () const;
      91             :         Key current () const;
      92             : 
      93             :         void setCursor (cursor_t cursor) const;
      94             :         cursor_t getCursor () const;
      95             : 
      96             :         Key pop ();
      97             :         Key at (cursor_t pos) const;
      98             : 
      99             :         KeySet cut (Key k);
     100             : 
     101             :         Key lookup (const Key & k, const option_t options = KDB_O_NONE) const;
     102             :         Key lookup (std::string const & name, const option_t options = KDB_O_NONE) const;
     103             :         template <typename T>
     104             :         T get (std::string const & name, const option_t options = KDB_O_NONE) const;
     105             : 
     106             : #ifndef ELEKTRA_WITHOUT_ITERATOR
     107             :         typedef KeySetIterator iterator;
     108             :         typedef KeySetIterator const_iterator;
     109             :         typedef KeySetReverseIterator reverse_iterator;
     110             :         typedef KeySetReverseIterator const_reverse_iterator;
     111             : 
     112             :         iterator begin ();
     113             :         const_iterator begin () const;
     114             :         iterator end ();
     115             :         const_iterator end () const;
     116             :         reverse_iterator rbegin ();
     117             :         const_reverse_iterator rbegin () const;
     118             :         reverse_iterator rend ();
     119             :         const_reverse_iterator rend () const;
     120             : 
     121             :         const_iterator cbegin () const noexcept;
     122             :         const_iterator cend () const noexcept;
     123             :         const_reverse_iterator crbegin () const noexcept;
     124             :         const_reverse_iterator crend () const noexcept;
     125             : #endif // ELEKTRA_WITHOUT_ITERATOR
     126             : 
     127             : private:
     128             :         ckdb::KeySet * ks; ///< holds an elektra keyset
     129             : };
     130             : 
     131             : 
     132             : #ifndef ELEKTRA_WITHOUT_ITERATOR
     133             : /**
     134             :  * For C++ forward Iteration over KeySets.
     135             :  * (External Iterator)
     136             :  * @code
     137             :         for (Key k:ks3)
     138             :         {
     139             :                 std::cout << k.getName() << std::endl;
     140             :         }
     141             :  * @endcode
     142             :  */
     143             : class KeySetIterator
     144             : {
     145             : public:
     146             :         typedef Key value_type;
     147             :         typedef cursor_t difference_type;
     148             :         typedef Key pointer;
     149             :         typedef Key reference;
     150             :         typedef std::random_access_iterator_tag iterator_category;
     151             : 
     152             :         KeySetIterator (KeySet const & k) : ks (k), current (){};
     153             :         KeySetIterator (KeySet const & k, const cursor_t c) : ks (k), current (c){};
     154             :         // conversion to const iterator?
     155             : 
     156       21397 :         Key get () const
     157             :         {
     158       64191 :                 return Key (ckdb::ksAtCursor (ks.getKeySet (), current));
     159             :         }
     160             :         Key get (cursor_t pos) const
     161             :         {
     162          72 :                 return Key (ckdb::ksAtCursor (ks.getKeySet (), pos));
     163             :         }
     164             : 
     165             :         KeySet const & getKeySet () const
     166             :         {
     167             :                 return ks;
     168             :         }
     169             : 
     170             :         // Forward iterator requirements
     171             :         reference operator* () const
     172             :         {
     173       19347 :                 return get ();
     174             :         }
     175             :         pointer operator-> () const
     176             :         {
     177        2048 :                 return get ();
     178             :         }
     179             :         KeySetIterator & operator++ ()
     180             :         {
     181       20453 :                 ++current;
     182             :                 return *this;
     183             :         }
     184             :         KeySetIterator operator++ (int)
     185             :         {
     186          12 :                 return KeySetIterator (ks, current++);
     187             :         }
     188             : 
     189             :         // Bidirectional iterator requirements
     190             :         KeySetIterator & operator-- ()
     191             :         {
     192           6 :                 --current;
     193             :                 return *this;
     194             :         }
     195             :         KeySetIterator operator-- (int)
     196             :         {
     197          12 :                 return KeySetIterator (ks, current--);
     198             :         }
     199             : 
     200             :         // Random access iterator requirements
     201             :         reference operator[] (const difference_type & pos) const
     202             :         {
     203          48 :                 return get (pos);
     204             :         }
     205             :         KeySetIterator & operator+= (const difference_type & pos)
     206             :         {
     207          12 :                 current += pos;
     208             :                 return *this;
     209             :         }
     210             :         KeySetIterator operator+ (const difference_type & pos) const
     211             :         {
     212          46 :                 return KeySetIterator (ks, current + pos);
     213             :         }
     214             :         KeySetIterator & operator-= (const difference_type & pos)
     215             :         {
     216          12 :                 current -= pos;
     217             :                 return *this;
     218             :         }
     219             :         KeySetIterator operator- (const difference_type & pos) const
     220             :         {
     221             :                 return KeySetIterator (ks, current - pos);
     222             :         }
     223             :         const cursor_t & base () const
     224             :         {
     225             :                 return current;
     226             :         }
     227             : 
     228             : private:
     229             :         KeySet const & ks;
     230             :         cursor_t current;
     231             : };
     232             : 
     233             : 
     234             : // Forward iterator requirements
     235             : inline bool operator== (const KeySetIterator & lhs, const KeySetIterator & rhs)
     236             : {
     237          69 :         return &lhs.getKeySet () == &rhs.getKeySet () && lhs.base () == rhs.base ();
     238             : }
     239             : 
     240             : inline bool operator!= (const KeySetIterator & lhs, const KeySetIterator & rhs)
     241             : {
     242       24995 :         return &lhs.getKeySet () != &rhs.getKeySet () || lhs.base () != rhs.base ();
     243             : }
     244             : 
     245             : // Random access iterator requirements
     246             : inline bool operator< (const KeySetIterator & lhs, const KeySetIterator & rhs)
     247             : {
     248             :         return lhs.base () < rhs.base ();
     249             : }
     250             : 
     251             : inline bool operator> (const KeySetIterator & lhs, const KeySetIterator & rhs)
     252             : {
     253             :         return lhs.base () > rhs.base ();
     254             : }
     255             : 
     256             : inline bool operator<= (const KeySetIterator & lhs, const KeySetIterator & rhs)
     257             : {
     258             :         return lhs.base () <= rhs.base ();
     259             : }
     260             : 
     261             : inline bool operator>= (const KeySetIterator & lhs, const KeySetIterator & rhs)
     262             : {
     263             :         return lhs.base () >= rhs.base ();
     264             : }
     265             : 
     266             : // DR 685.
     267             : inline auto operator- (const KeySetIterator & lhs, const KeySetIterator & rhs) -> decltype (lhs.base () - rhs.base ())
     268             : {
     269           3 :         return lhs.base () - rhs.base ();
     270             : }
     271             : 
     272             : inline KeySetIterator operator+ (KeySetIterator::difference_type n, const KeySetIterator & i)
     273             : {
     274             :         return KeySetIterator (i.getKeySet (), i.base () + n);
     275             : }
     276             : 
     277             : 
     278             : // some code duplication because std::reverse_iterator
     279             : // does not work on value_types
     280             : /**
     281             :  * For C++ reverse Iteration over KeySets.
     282             :  * (External Iterator)
     283             :  */
     284             : class KeySetReverseIterator
     285             : {
     286             : public:
     287             :         typedef Key value_type;
     288             :         typedef cursor_t difference_type;
     289             :         typedef Key pointer;
     290             :         typedef Key reference;
     291             :         typedef std::random_access_iterator_tag iterator_category;
     292             : 
     293             :         KeySetReverseIterator (KeySet const & k) : ks (k), current (){};
     294             :         KeySetReverseIterator (KeySet const & k, const cursor_t c) : ks (k), current (c){};
     295             :         // conversion to const iterator?
     296             : 
     297          72 :         Key get () const
     298             :         {
     299         216 :                 return Key (ckdb::ksAtCursor (ks.getKeySet (), current));
     300             :         }
     301             :         Key get (cursor_t pos) const
     302             :         {
     303          72 :                 return Key (ckdb::ksAtCursor (ks.getKeySet (), pos));
     304             :         }
     305             : 
     306             :         KeySet const & getKeySet () const
     307             :         {
     308             :                 return ks;
     309             :         }
     310             : 
     311             :         // Forward iterator requirements
     312             :         reference operator* () const
     313             :         {
     314          40 :                 return get ();
     315             :         }
     316             :         pointer operator-> () const
     317             :         {
     318          32 :                 return get ();
     319             :         }
     320             :         KeySetReverseIterator & operator++ ()
     321             :         {
     322          24 :                 --current;
     323             :                 return *this;
     324             :         }
     325             :         KeySetReverseIterator operator++ (int)
     326             :         {
     327             :                 return KeySetReverseIterator (ks, current--);
     328             :         }
     329             : 
     330             :         // Bidirectional iterator requirements
     331             :         KeySetReverseIterator & operator-- ()
     332             :         {
     333           0 :                 ++current;
     334             :                 return *this;
     335             :         }
     336             :         KeySetReverseIterator operator-- (int)
     337             :         {
     338             :                 return KeySetReverseIterator (ks, current++);
     339             :         }
     340             : 
     341             :         // Random access iterator requirements
     342          24 :         reference operator[] (const difference_type & pos) const
     343             :         {
     344          72 :                 return get (ks.size () - pos - 1);
     345             :         }
     346             :         KeySetReverseIterator & operator+= (const difference_type & pos)
     347             :         {
     348             :                 current -= pos;
     349             :                 return *this;
     350             :         }
     351             :         KeySetReverseIterator operator+ (const difference_type & pos) const
     352             :         {
     353          40 :                 return KeySetReverseIterator (ks, current - pos);
     354             :         }
     355             :         KeySetReverseIterator & operator-= (const difference_type & pos)
     356             :         {
     357             :                 current += pos;
     358             :                 return *this;
     359             :         }
     360             :         KeySetReverseIterator operator- (const difference_type & pos) const
     361             :         {
     362             :                 return KeySetReverseIterator (ks, current + pos);
     363             :         }
     364             :         const cursor_t & base () const
     365             :         {
     366             :                 return current;
     367             :         }
     368             : 
     369             : private:
     370             :         KeySet const & ks;
     371             :         cursor_t current;
     372             : };
     373             : 
     374             : 
     375             : // Forward iterator requirements
     376             : inline bool operator== (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs)
     377             : {
     378          26 :         return &lhs.getKeySet () == &rhs.getKeySet () && lhs.base () == rhs.base ();
     379             : }
     380             : 
     381             : inline bool operator!= (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs)
     382             : {
     383           0 :         return &lhs.getKeySet () != &rhs.getKeySet () || lhs.base () != rhs.base ();
     384             : }
     385             : 
     386             : // Random access iterator requirements
     387             : inline bool operator< (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs)
     388             : {
     389             :         return lhs.base () < rhs.base ();
     390             : }
     391             : 
     392             : inline bool operator> (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs)
     393             : {
     394             :         return lhs.base () > rhs.base ();
     395             : }
     396             : 
     397             : inline bool operator<= (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs)
     398             : {
     399             :         return lhs.base () <= rhs.base ();
     400             : }
     401             : 
     402             : inline bool operator>= (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs)
     403             : {
     404             :         return lhs.base () >= rhs.base ();
     405             : }
     406             : 
     407             : // DR 685.
     408             : inline auto operator- (const KeySetReverseIterator & lhs, const KeySetReverseIterator & rhs) -> decltype (lhs.base () - rhs.base ())
     409             : {
     410           0 :         return lhs.base () - rhs.base ();
     411             : }
     412             : 
     413             : inline KeySetReverseIterator operator+ (KeySetReverseIterator::difference_type n, const KeySetReverseIterator & i)
     414             : {
     415             :         return KeySetReverseIterator (i.getKeySet (), i.base () + n);
     416             : }
     417             : 
     418             : 
     419             : inline KeySet::iterator KeySet::begin ()
     420             : {
     421        4448 :         return KeySet::iterator (*this, 0);
     422             : }
     423             : 
     424             : inline KeySet::const_iterator KeySet::begin () const
     425             : {
     426        4027 :         return KeySet::const_iterator (*this, 0);
     427             : }
     428             : 
     429             : inline KeySet::iterator KeySet::end ()
     430             : {
     431        7267 :         return KeySet::iterator (*this, size ());
     432             : }
     433             : 
     434             : inline KeySet::const_iterator KeySet::end () const
     435             : {
     436        1049 :         return KeySet::const_iterator (*this, size ());
     437             : }
     438             : 
     439             : inline KeySet::reverse_iterator KeySet::rbegin ()
     440             : {
     441          28 :         return KeySet::reverse_iterator (*this, size () - 1);
     442             : }
     443             : 
     444             : inline KeySet::const_reverse_iterator KeySet::rbegin () const
     445             : {
     446          24 :         return KeySet::const_reverse_iterator (*this, size () - 1);
     447             : }
     448             : 
     449             : inline KeySet::reverse_iterator KeySet::rend ()
     450             : {
     451           4 :         return KeySet::reverse_iterator (*this, -1);
     452             : }
     453             : 
     454             : inline KeySet::const_reverse_iterator KeySet::rend () const
     455             : {
     456           2 :         return KeySet::const_reverse_iterator (*this, -1);
     457             : }
     458             : 
     459             : inline KeySet::const_iterator KeySet::cbegin () const noexcept
     460             : {
     461          48 :         return KeySet::const_iterator (*this, 0);
     462             : }
     463             : 
     464             : inline KeySet::const_iterator KeySet::cend () const noexcept
     465             : {
     466           4 :         return KeySet::const_iterator (*this, size ());
     467             : }
     468             : 
     469             : inline KeySet::const_reverse_iterator KeySet::crbegin () const noexcept
     470             : {
     471          48 :         return KeySet::const_reverse_iterator (*this, size () - 1);
     472             : }
     473             : 
     474             : inline KeySet::const_reverse_iterator KeySet::crend () const noexcept
     475             : {
     476           4 :         return KeySet::const_reverse_iterator (*this, -1);
     477             : }
     478             : #endif // ELEKTRA_WITHOUT_ITERATOR
     479             : 
     480             : 
     481             : /**
     482             :  * Creates a new empty keyset with no keys
     483             :  *
     484             :  * @copydoc ksNew
     485             :  */
     486       79764 : inline KeySet::KeySet () : ks (ckdb::ksNew (0, KS_END))
     487             : {
     488             : }
     489             : 
     490             : /**
     491             :  * Takes ownership of keyset!
     492             :  *
     493             :  * Keyset will be destroyed at destructor
     494             :  * you cant continue to use keyset afterwards!
     495             :  *
     496             :  * Use KeySet::release() to avoid destruction.
     497             :  *
     498             :  * @param k the keyset to take the ownership from
     499             :  * @see release()
     500             :  * @see setKeySet()
     501             :  */
     502       14986 : inline KeySet::KeySet (ckdb::KeySet * k) : ks (k)
     503             : {
     504             : }
     505             : 
     506             : /**
     507             :  * Duplicate a keyset.
     508             :  *
     509             :  *  This keyset will be a duplicate of the other afterwards.
     510             :  *
     511             :  * @note that they still reference to the same Keys, so
     512             :  *       if you change key values also the keys in the original keyset
     513             :  *       will be changed.
     514             :  *
     515             :  * So it is shallow copy, to create a deep copy you have to dup() every
     516             :  * key (it still won't copy metadata, but they are COW):
     517             :  * @snippet cpp_example_dup.cpp ksDeepCopy
     518             :  *
     519             :  * @see dup
     520             :  */
     521      112193 : inline KeySet::KeySet (const KeySet & other)
     522             : {
     523      112193 :         ks = other.dup ();
     524             : }
     525             : 
     526             : /**
     527             :  * @brief Create a new keyset.
     528             :  *
     529             :  * @param alloc minimum number of keys to allocate
     530             :  * @param ap variable arguments list
     531             :  *
     532             :  * Use va as first argument to use this constructor, e.g.:
     533             :  * @code
     534             :  * KeySet ks(va, 23, ...);
     535             :  * @endcode
     536             :  *
     537             :  * @copydoc ksVNew
     538             :  */
     539             : inline KeySet::KeySet (VaAlloc alloc, va_list av)
     540             : {
     541           4 :         ks = ckdb::ksVNew (alloc.alloc, av);
     542             : }
     543             : 
     544             : /**
     545             :  * @brief Create a new keyset
     546             :  *
     547             :  * @param alloc minimum number of keys to allocate
     548             :  * @param ... variable argument list
     549             :  *
     550             :  * @copydoc ksVNew
     551             :  */
     552        4438 : inline KeySet::KeySet (size_t alloc, ...)
     553             : {
     554             :         va_list vl;
     555             : 
     556        4438 :         va_start (vl, alloc);
     557        4438 :         ks = ckdb::ksVNew (alloc, vl);
     558        4438 :         va_end (vl);
     559        4438 : }
     560             : 
     561             : /**
     562             :  * @brief Deconstruct a keyset
     563             :  *
     564             :  * @copydoc ksDel
     565             :  */
     566      124252 : inline KeySet::~KeySet ()
     567             : {
     568      212664 :         ckdb::ksDel (ks);
     569           0 : }
     570             : 
     571             : /**
     572             :  * If you don't want destruction of keyset at
     573             :  * the end you can release the pointer.
     574             :  * */
     575             : inline ckdb::KeySet * KeySet::release ()
     576             : {
     577        5365 :         ckdb::KeySet * ret = ks;
     578        5365 :         ks = ckdb::ksNew (0, KS_END);
     579             :         return ret;
     580             : }
     581             : 
     582             : /**
     583             :  * @brief Passes out the raw keyset pointer
     584             :  *
     585             :  * @return pointer to internal ckdb KeySet
     586             :  *
     587             :  * @see release()
     588             :  * @see setKeySet()
     589             :  */
     590             : inline ckdb::KeySet * KeySet::getKeySet () const
     591             : {
     592       84889 :         return ks;
     593             : }
     594             : 
     595             : /**
     596             :  * @brief Take ownership of passed keyset
     597             :  *
     598             :  * @param k the keyset to take ownership from
     599             :  * @see release()
     600             :  * @see getKeySet()
     601             :  */
     602             : inline void KeySet::setKeySet (ckdb::KeySet * k)
     603             : {
     604           0 :         ckdb::ksDel (ks);
     605           0 :         ks = k;
     606             : }
     607             : 
     608             : /**
     609             :  * Duplicate a keyset.
     610             :  *
     611             :  * This keyset will be a duplicate of the other afterwards.
     612             :  *
     613             :  * @note that they still reference to the same Keys, so
     614             :  *       if you change key values also the keys in the original keyset
     615             :  *       will be changed.
     616             :  */
     617        7358 : inline KeySet & KeySet::operator= (KeySet const & other)
     618             : {
     619        7358 :         if (this != &other)
     620             :         {
     621        8356 :                 ckdb::ksDel (ks);
     622        8356 :                 ks = other.dup ();
     623             :         }
     624        7358 :         return *this;
     625             : }
     626             : 
     627             : /**
     628             :  * @brief The size of the keyset
     629             :  *
     630             :  * @return the number of keys in the keyset
     631             :  */
     632             : inline ssize_t KeySet::size () const
     633             : {
     634      216578 :         return ckdb::ksGetSize (ks);
     635             : }
     636             : 
     637             : /**
     638             :  * @brief Duplicate a keyset
     639             :  *
     640             :  * @return a copy of the keys
     641             :  *
     642             :  * This is only a shallow copy. For a deep copy you need to dup every
     643             :  * key.
     644             :  *
     645             :  * @copydoc ksDup()
     646             :  */
     647             : inline ckdb::KeySet * KeySet::dup () const
     648             : {
     649      139881 :         return ckdb::ksDup (ks);
     650             : }
     651             : 
     652             : /**
     653             :  * @brief Copy a keyset
     654             :  *
     655             :  * @param other other keyset to copy
     656             :  *
     657             :  * This is only a shallow copy. For a deep copy you need to dup every
     658             :  * key.
     659             :  *
     660             :  * @copydoc ksCopy()
     661             :  */
     662             : inline void KeySet::copy (const KeySet & other)
     663             : {
     664           2 :         ckdb::ksCopy (ks, other.ks);
     665             : }
     666             : 
     667             : /**
     668             :  * @brief Clear the keyset
     669             :  *
     670             :  * Keyset will have no keys afterwards.
     671             :  */
     672             : inline void KeySet::clear ()
     673             : {
     674         445 :         ckdb::ksCopy (ks, nullptr);
     675             : }
     676             : 
     677             : /**
     678             :  * @brief append a key
     679             :  *
     680             :  * @param toAppend key to append
     681             :  *
     682             :  * @return number of keys in the keyset
     683             :  *
     684             :  * @copydoc ksAppendKey()
     685             :  */
     686             : inline ssize_t KeySet::append (const Key & toAppend)
     687             : {
     688      238783 :         return ckdb::ksAppendKey (ks, toAppend.getKey ());
     689             : }
     690             : 
     691             : /**
     692             :  * @brief append a keyset
     693             :  *
     694             :  * @param toAppend keyset to append
     695             :  *
     696             :  * @return number of keys in the keyset
     697             :  *
     698             :  * @copydoc ksAppend()
     699             :  */
     700             : inline ssize_t KeySet::append (KeySet const & toAppend)
     701             : {
     702        9475 :         return ckdb::ksAppend (ks, toAppend.getKeySet ());
     703             : }
     704             : 
     705             : /**
     706             :  * @return alphabetical first key
     707             :  *
     708             :  * @copydoc ksHead()
     709             :  */
     710             : inline Key KeySet::head () const
     711             : {
     712         214 :         return Key (ckdb::ksHead (ks));
     713             : }
     714             : 
     715             : /**
     716             :  * @return alphabetical last key
     717             :  *
     718             :  * @copydoc ksTail()
     719             :  */
     720             : inline Key KeySet::tail () const
     721             : {
     722          42 :         return Key (ckdb::ksTail (ks));
     723             : }
     724             : 
     725             : 
     726             : /**
     727             :  * @copydoc ksRewind()
     728             :  */
     729             : inline void KeySet::rewind () const
     730             : {
     731       32812 :         ckdb::ksRewind (ks);
     732             : }
     733             : 
     734             : /**
     735             :  * @copydoc ksNext()
     736             :  */
     737             : inline Key KeySet::next () const
     738             : {
     739      434000 :         ckdb::Key * k = ckdb::ksNext (ks);
     740      433927 :         return Key (k);
     741             : }
     742             : 
     743             : /**
     744             :  * @copydoc ksCurrent()
     745             :  */
     746             : inline Key KeySet::current () const
     747             : {
     748       15152 :         return Key (ckdb::ksCurrent (ks));
     749             : }
     750             : 
     751             : /**
     752             :  * @copydoc ksSetCursor()
     753             :  */
     754             : inline void KeySet::setCursor (cursor_t cursor) const
     755             : {
     756         909 :         ckdb::ksSetCursor (ks, cursor);
     757             : }
     758             : 
     759             : /**
     760             :  * @copydoc ksGetCursor()
     761             :  */
     762             : inline cursor_t KeySet::getCursor () const
     763             : {
     764         932 :         return ckdb::ksGetCursor (ks);
     765             : }
     766             : 
     767             : /**
     768             :  * @copydoc ksPop()
     769             :  */
     770             : inline Key KeySet::pop ()
     771             : {
     772         500 :         ckdb::Key * k = ckdb::ksPop (ks);
     773         500 :         Key key (k);
     774             :         return key;
     775             : }
     776             : 
     777             : /**
     778             :  * @brief Lookup a key by index
     779             :  *
     780             :  * @param pos cursor position
     781             :  *
     782             :  * @return the found key
     783             :  */
     784         102 : inline Key KeySet::at (cursor_t pos) const
     785             : {
     786         111 :         if (pos < 0) pos += size ();
     787        1032 :         return Key (ckdb::ksAtCursor (ks, pos));
     788             : }
     789             : 
     790             : /**
     791             :  * @copydoc ksCut()
     792             :  */
     793             : inline KeySet KeySet::cut (Key k)
     794             : {
     795        9868 :         return KeySet (ckdb::ksCut (ks, k.getKey ()));
     796             : }
     797             : 
     798             : /**
     799             :  * @copydoc ksLookup()
     800             :  *
     801             :  * @note That the internal key cursor will point to the found key
     802             :  */
     803             : inline Key KeySet::lookup (const Key & key, const option_t options) const
     804             : {
     805      160241 :         ckdb::Key * k = ckdb::ksLookup (ks, key.getKey (), options);
     806      160270 :         return Key (k);
     807             : }
     808             : 
     809             : /**
     810             :  * @brief Lookup a key by name
     811             :  *
     812             :  * @param name the name to look for
     813             :  * @param options some options to pass
     814             :  *
     815             :  * @return the found key
     816             :  * @see lookup (const Key &key, const option_t options)
     817             :  *
     818             :  * @note That the internal key cursor will point to the found key
     819             :  */
     820             : inline Key KeySet::lookup (std::string const & name, option_t const options) const
     821             : {
     822      170829 :         ckdb::Key * k = ckdb::ksLookupByName (ks, name.c_str (), options);
     823      170855 :         return Key (k);
     824             : }
     825             : 
     826             : template <typename T>
     827             : struct KeySetTypeWrapper;
     828             : 
     829             : template <typename T>
     830             : struct KeySetTypeWrapper
     831             : {
     832          14 :         T operator() (KeySet const & ks, std::string const & name, option_t const options) const
     833             :         {
     834          28 :                 Key k = ks.lookup (name, options);
     835          26 :                 if (!k) throw kdb::KeyNotFoundException ("key " + name + " was not found");
     836          16 :                 return k.get<T> ();
     837             :         }
     838             : };
     839             : 
     840             : /**
     841             :  * @brief Generic lookup+get for keysets
     842             :  *
     843             :  * @param name the key name to get
     844             :  * @param options the options to be passed to lookup()
     845             :  *
     846             :  * @throw KeyNotFoundException if no key found
     847             :  *
     848             :  * @note To specialize more complex types (which are generic themselves) you
     849             :  * can also specialize KeySetTypeWrapper<T>.
     850             :  *
     851             :  * Use
     852             :  * @code
     853             : #include <keysetget.hpp>
     854             :  * @endcode
     855             :  * to include specializations for std types.
     856             :  *
     857             :  * @return the requested type
     858             :  */
     859             : template <typename T>
     860             : inline T KeySet::get (std::string const & name, option_t const options) const
     861             : {
     862             :         KeySetTypeWrapper<T> typeWrapper;
     863       10766 :         return typeWrapper (*this, name, options);
     864             : }
     865             : 
     866         579 : inline bool operator== (const KeySet & lhs, const KeySet & rhs)
     867             : {
     868        3398 :         return lhs.size () == rhs.size () && std::equal (lhs.begin (), lhs.end (), rhs.begin ());
     869             : }
     870             : 
     871             : 
     872             : inline bool operator!= (const KeySet & lhs, const KeySet & rhs)
     873             : {
     874          64 :         return !(lhs == rhs);
     875             : }
     876             : 
     877             : 
     878             : } // end of namespace kdb
     879             : 
     880             : #endif

Generated by: LCOV version 1.13