STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

winstl_reg_key_sequence.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_reg_key_sequence.h
00003  *
00004  * Purpose:     Contains the basic_reg_key_sequence template class, and ANSI
00005  *              and Unicode specialisations thereof.
00006  *
00007  * Notes:       The original implementation of the class had the const_iterator
00008  *              and value_type as nested classes. Unfortunately, Visual C++ 5 &
00009  *              6 both had either compilation or linking problems so these are
00010  *              regretably now implemented as independent classes.
00011  *
00012  * Created:     19th January 2002
00013  * Updated:     11th September 2004
00014  *
00015  * Home:        http://stlsoft.org/
00016  *
00017  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00018  * All rights reserved.
00019  *
00020  * Redistribution and use in source and binary forms, with or without
00021  * modification, are permitted provided that the following conditions are met:
00022  *
00023  * - Redistributions of source code must retain the above copyright notice, this
00024  *   list of conditions and the following disclaimer.
00025  * - Redistributions in binary form must reproduce the above copyright notice,
00026  *   this list of conditions and the following disclaimer in the documentation
00027  *   and/or other materials provided with the distribution.
00028  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00029  *   any contributors may be used to endorse or promote products derived from
00030  *   this software without specific prior written permission.
00031  *
00032  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00033  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00034  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00035  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00036  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00037  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00038  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00039  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00040  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00041  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00042  * POSSIBILITY OF SUCH DAMAGE.
00043  *
00044  * 
00045 
00046 
00050 
00051 #ifndef WINSTL_INCL_H_WINSTL_REG_KEY_SEQUENCE
00052 #define WINSTL_INCL_H_WINSTL_REG_KEY_SEQUENCE
00053 
00054 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00055 # define WINSTL_VER_H_WINSTL_REG_KEY_SEQUENCE_MAJOR     2
00056 # define WINSTL_VER_H_WINSTL_REG_KEY_SEQUENCE_MINOR     0
00057 # define WINSTL_VER_H_WINSTL_REG_KEY_SEQUENCE_REVISION  1
00058 # define WINSTL_VER_H_WINSTL_REG_KEY_SEQUENCE_EDIT      66
00059 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00060 
00061 /* 
00062  * Includes
00063  */
00064 
00065 #ifndef WINSTL_INCL_H_WINSTL
00066 # include "winstl.h"                        // Include the WinSTL root header
00067 #endif /* !WINSTL_INCL_H_WINSTL */
00068 #ifndef WINSTL_INCL_H_WINSTL_REG_DEFS
00069 # include "winstl_reg_defs.h"               // The WinSTL reg API standard types
00070 #endif /* WINSTL_INCL_H_WINSTL_REG_DEFS */
00071 #ifndef WINSTL_INCL_H_WINSTL_REG_TRAITS
00072 # include "winstl_reg_traits.h"             // The WinSTL reg API reg_traits class
00073 #endif /* WINSTL_INCL_H_WINSTL_REG_TRAITS */
00074 #ifndef WINSTL_INCL_H_WINSTL_REG_KEY
00075 # include "winstl_reg_key.h"                // The WinSTL reg API reg_key class
00076 #endif /* WINSTL_INCL_H_WINSTL_REG_KEY */
00077 #ifndef STLSOFT_INCL_H_STLSOFT_AUTO_DESTRUCTOR
00078 # include "stlsoft_auto_buffer.h"           // Include the STLSoft auto_buffer
00079 #endif /* STLSOFT_INCL_H_STLSOFT_AUTO_DESTRUCTOR */
00080 #ifndef WINSTL_INCL_H_WINSTL_AUTO_DESTRUCTOR
00081 # include "winstl_processheap_allocator.h"  // winstl::processheap_allocator
00082 #endif /* WINSTL_INCL_H_WINSTL_AUTO_DESTRUCTOR */
00083 #ifndef STLSOFT_INCL_H_STLSOFT_ITERATOR
00084 # include "stlsoft_iterator.h"              // stlsoft::iterator, stlsoft::reverse_iterator
00085 #endif /* STLSOFT_INCL_H_STLSOFT_ITERATOR */
00086 
00087 /* 
00088  * Namespace
00089  */
00090 
00091 #ifndef _WINSTL_NO_NAMESPACE
00092 # if defined(_STLSOFT_NO_NAMESPACE) || \
00093      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00094 /* There is no stlsoft namespace, so must define ::winstl */
00095 namespace winstl
00096 {
00097 # else
00098 /* Define stlsoft::winstl_project */
00099 
00100 namespace stlsoft
00101 {
00102 
00103 namespace winstl_project
00104 {
00105 
00106 # endif /* _STLSOFT_NO_NAMESPACE */
00107 #endif /* !_WINSTL_NO_NAMESPACE */
00108 
00109 /* 
00110 
00113 
00114 /* 
00115  * Forward declarations
00116  */
00117 
00118 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00119 
00120 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00121 class basic_reg_key_sequence_const_iterator;
00122 
00123 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00124 
00125 /* 
00126  * Classes
00127  */
00128 
00129 // class basic_reg_key_sequence
00135 template<   ss_typename_param_k C
00136 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00137         ,   ss_typename_param_k T = reg_traits<C>
00138         ,   ss_typename_param_k A = processheap_allocator<C>
00139 #else
00140         ,   ss_typename_param_k T /* = reg_traits<C> */
00141         ,   ss_typename_param_k A /* = processheap_allocator<C> */
00142 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00143         >
00144 class basic_reg_key_sequence
00145 {
00146 public:
00148     typedef C                                                                       char_type;
00150     typedef T                                                                       traits_type;
00152     typedef A                                                                       allocator_type;
00154     typedef basic_reg_key_sequence<C, T, A>                                         class_type;
00156     typedef basic_reg_key<C, T, A>                                                  key_type;
00158     typedef const key_type                                                          value_type;
00160     typedef ss_typename_type_k traits_type::size_type                               size_type;
00162     typedef basic_reg_key<C, T, A>                                                  reg_key_type;
00164     typedef basic_reg_key_sequence_const_iterator<C, T, value_type, A>              const_iterator;
00166     typedef key_type                                                                &reference;
00168     typedef key_type const                                                          &const_reference;
00170     typedef ss_typename_type_k traits_type::hkey_type                               hkey_type;
00172     typedef ws_ptrdiff_t                                                            difference_type;
00174 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00175     typedef stlsoft_ns_qual(const_reverse_bidirectional_iterator_base)< const_iterator,
00176                                                                         value_type,
00177                                                                         value_type, // Return by value!
00178                                                                         void*,
00179                                                                         difference_type>    const_reverse_iterator;
00180 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00181 
00182 // Construction
00183 public:
00185     basic_reg_key_sequence(hkey_type hkey, char_type const *sub_key_name)
00186         : m_hkey(NULL)
00187     {
00188         if(0 != traits_type::reg_open_key(hkey, sub_key_name, &m_hkey))
00189         {
00190             m_hkey = NULL;
00191         }
00192     } // Implementation is within class, otherwise VC5 will not link
00193 
00195     basic_reg_key_sequence(reg_key_type const &key);
00197     ~basic_reg_key_sequence() winstl_throw_0();
00198 
00199 // Iteration
00200 public:
00204     const_iterator          begin() const;
00208     const_iterator          end() const;
00209 
00210 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00214     const_reverse_iterator  rbegin() const;
00218     const_reverse_iterator  rend() const;
00219 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00220 
00221 // State
00222 public:
00224     size_type               size() const;
00226     ws_bool_t               empty() const;
00228     static size_type        max_size();
00229 
00230 // Members
00231 private:
00232     ss_typename_type_k traits_type::hkey_type   m_hkey;
00233 
00234 // Not to be implemented
00235 private:
00236     basic_reg_key_sequence(class_type const &);
00237     basic_reg_key_sequence const &operator =(class_type const &);
00238 };
00239 
00240 /* Typedefs to commonly encountered types. */
00242 typedef basic_reg_key_sequence<ws_char_a_t, reg_traits<ws_char_a_t>, processheap_allocator<ws_char_a_t> > reg_key_sequence_a;
00244 typedef basic_reg_key_sequence<ws_char_w_t, reg_traits<ws_char_w_t>, processheap_allocator<ws_char_w_t> > reg_key_sequence_w;
00245 
00246 // class basic_reg_key_sequence_const_iterator
00253 template<   ss_typename_param_k C
00254         ,   ss_typename_param_k T
00255         ,   ss_typename_param_k V
00256         ,   ss_typename_param_k A
00257         >
00258 class basic_reg_key_sequence_const_iterator
00259     : public stlsoft_ns_qual(iterator_base)<winstl_ns_qual_std(bidirectional_iterator_tag), V, ws_ptrdiff_t, void *, V>
00260 {
00261 public:
00263     typedef C                                                   char_type;
00265     typedef T                                                   traits_type;
00267     typedef V                                                   value_type;
00269     typedef A                                                   allocator_type;
00271     typedef basic_reg_key_sequence_const_iterator<C, T, V, A>   class_type;
00273     typedef ss_typename_type_k traits_type::size_type           size_type;
00275     typedef ss_typename_type_k traits_type::difference_type     difference_type;
00277     typedef ss_typename_type_k traits_type::string_type         string_type;
00279     typedef ws_sint32_t                                         index_type;
00281     typedef ss_typename_type_k traits_type::hkey_type           hkey_type;
00282 
00283 // Construction
00284 private:
00285     basic_reg_key_sequence_const_iterator(hkey_type hkey, index_type index, string_type const &sub_key_name, size_type maxKnown)
00286         : m_hkey(hkey)
00287         , m_index(index)
00288         , m_name(sub_key_name)
00289         , m_maxKnown(maxKnown)
00290     {}
00292     basic_reg_key_sequence_const_iterator(hkey_type hkey, index_type index, char_type const *sub_key_name, size_type maxKnown)
00293         : m_hkey(hkey)
00294         , m_index(index)
00295         , m_name(sub_key_name)
00296         , m_maxKnown(maxKnown)
00297     {}
00298     basic_reg_key_sequence_const_iterator(hkey_type hkey)
00299         : m_hkey(hkey)
00300         , m_index(sentinel_())
00301         , m_maxKnown(0)
00302     {}
00303 public:
00305     basic_reg_key_sequence_const_iterator();
00307     basic_reg_key_sequence_const_iterator(class_type const &rhs);
00309     ~basic_reg_key_sequence_const_iterator() winstl_throw_0();
00310 
00312     basic_reg_key_sequence_const_iterator &operator =(class_type const &rhs);
00313 
00314 // Operators
00315 public:
00317     class_type &operator ++();
00319     class_type &operator --();
00321     const class_type operator ++(int);
00323     const class_type operator --(int);
00325     const value_type operator *() const;
00327     ws_bool_t operator ==(class_type const &rhs) const;
00329     ws_bool_t operator !=(class_type const &rhs) const;
00330 
00331 // Implementation
00332 private:
00333     static index_type sentinel_();
00334 
00335 // Members
00336 private:
00337     friend class basic_reg_key_sequence<C, T, A>;
00338 
00339     hkey_type   m_hkey;     // Parent container's key. This is not dup'ed
00340     index_type  m_index;    // Current iteration index
00341     string_type m_name;     // The value name
00342     size_type   m_maxKnown; // The last known size of the maximum sub-key name length. Includes space for terminating null.
00343 };
00344 
00346 // Unit-testing
00347 
00348 #ifdef STLSOFT_UNITTEST
00349 
00350 namespace unittest
00351 {
00352     ss_bool_t test_winstl_reg_key_sequence(unittest_reporter *r)
00353     {
00354         using stlsoft::unittest::unittest_initialiser;
00355 
00356         ss_bool_t               bSuccess    =   true;
00357 
00358         unittest_initialiser    init(r, "WinSTL", "reg_key_sequence", __FILE__);
00359 
00360 #if 0
00361         if(<<TODO>>)
00362         {
00363             r->report("<<TODO>> failed ", __LINE__);
00364             bSuccess = false;
00365         }
00366 #endif /* 0 */
00367 
00368         return bSuccess;
00369     }
00370 
00371     unittest_registrar    unittest_winstl_reg_key_sequence(test_winstl_reg_key_sequence);
00372 
00373 } // namespace unittest
00374 
00375 #endif /* STLSOFT_UNITTEST */
00376 
00378 // Implementation
00379 
00380 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00381 
00382 // basic_reg_key_sequence
00383 
00384 #if 0
00385 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00386 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence(basic_reg_key_sequence<C, T, A>::hkey_type hkey, basic_reg_key_sequence<C, T, A>::char_type const *sub_key_name)
00387     : m_hkey(NULL)
00388 {
00389     if(0 != traits_type::reg_open_key(hkey, sub_key_name, &m_hkey))
00390     {
00391         m_hkey = NULL;
00392     }
00393 }
00394 #endif /* 0 */
00395 
00396 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00397 inline basic_reg_key_sequence<C, T, A>::basic_reg_key_sequence(ss_typename_type_k basic_reg_key_sequence<C, T, A>::reg_key_type const &key)
00398     : m_hkey(traits_type::key_dup(key.m_hkey))
00399 {}
00400 
00401 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00402 inline basic_reg_key_sequence<C, T, A>::~basic_reg_key_sequence() winstl_throw_0()
00403 {
00404     if(m_hkey != NULL)
00405     {
00406         ::RegCloseKey(m_hkey);
00407     }
00408 }
00409 
00410 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00411 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_iterator basic_reg_key_sequence<C, T, A>::begin() const
00412 {
00413     typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER>    buffer_t;
00414 
00415     // Grab enough for the first item
00416     size_type   cch_key_name    =   0;
00417     size_type   c_sub_keys      =   0;
00418     ws_long_t   res             =   traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, &cch_key_name, NULL, NULL, NULL, NULL, NULL, NULL);
00419 
00420     if( 0 == res &&
00421         0 < c_sub_keys)
00422     {
00423         size_type const maxKnown    =   ++cch_key_name;
00424         buffer_t        buffer(maxKnown);
00425 
00426         res = traits_type::reg_enum_key(m_hkey, 0, buffer, &cch_key_name, NULL, NULL, NULL);
00427 
00428         if(res == 0)
00429         {
00430             buffer[cch_key_name] = 0;
00431 
00432             return const_iterator(m_hkey, 0, buffer.data(), maxKnown);
00433         }
00434     }
00435 
00436     return end();
00437 }
00438 
00439 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00440 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_iterator basic_reg_key_sequence<C, T, A>::end() const
00441 {
00442     return const_iterator(m_hkey);
00443 }
00444 
00445 #if defined(__STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT)
00446 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00447 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_reverse_iterator basic_reg_key_sequence<C, T, A>::rbegin() const
00448 {
00449     return const_reverse_iterator(end());
00450 }
00451 
00452 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00453 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::const_reverse_iterator basic_reg_key_sequence<C, T, A>::rend() const
00454 {
00455     return const_reverse_iterator(begin());
00456 }
00457 #endif /* __STLSOFT_CF_BIDIRECTIONAL_ITERATOR_SUPPORT */
00458 
00459 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00460 inline ss_typename_type_k basic_reg_key_sequence<C, T, A>::size_type basic_reg_key_sequence<C, T, A>::size() const
00461 {
00462     ws_uint_t   c_sub_keys;
00463     ws_long_t   res = traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
00464 
00465     if(res != 0)
00466     {
00467         c_sub_keys = 0;
00468     }
00469 
00470     return static_cast<size_type>(c_sub_keys);
00471 }
00472 
00473 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00474 inline ws_bool_t basic_reg_key_sequence<C, T, A>::empty() const
00475 {
00476     return size() == 0;
00477 }
00478 
00479 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00480 inline /* static */ ss_typename_type_k basic_reg_key_sequence<C, T, A>::size_type basic_reg_key_sequence<C, T, A>::max_size()
00481 {
00482     return static_cast<size_type>(-1);
00483 }
00484 
00485 // basic_reg_key_sequence_const_iterator
00486 
00487 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00488 inline /* static */ ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::index_type basic_reg_key_sequence_const_iterator<C, T, V, A>::sentinel_()
00489 {
00490     return 0x7fffffff;
00491 }
00492 
00493 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00494 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator()
00495     : m_hkey(NULL)
00496     , m_index(sentinel_())
00497     , m_maxKnown(0)
00498 {}
00499 
00500 #if 0 /* This method is inline, as VC5 will not link otherwise. (Both 4.2 & 6 will!) */
00501 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00502 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator(ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::hkey_type hkey, ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::index_type basic_reg_key_sequence_const_iterator<C, T, V, A>::index, ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::string_type const &sub_key_name)
00503     : m_hkey(hkey)
00504     , m_index(index)
00505     , m_name(sub_key_name)
00506     , m_maxKnown(0)
00507 {}
00508 #endif /* 0 */
00509 
00510 #if 0 /* This method is inline, as VC5 will not link otherwise. (Both 4.2 & 6 will!) */
00511 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00512 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator(ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::hkey_type hkey)
00513     : m_hkey(hkey)
00514     , m_index(sentinel_())
00515     , m_maxKnown(0)
00516 {}
00517 #endif /* 0 */
00518 
00519 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00520 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::basic_reg_key_sequence_const_iterator(class_type const &rhs)
00521     : m_hkey(rhs.m_hkey)
00522     , m_index(rhs.m_index) // This is valid, since the index is transferrable between iterators
00523     , m_name(rhs.m_name)
00524     , m_maxKnown(rhs.m_maxKnown)
00525 {}
00526 
00527 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00528 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type &basic_reg_key_sequence_const_iterator<C, T, V, A>::operator =(ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type const &rhs)
00529 {
00530     // For efficiency, we don't do self-assignment test, and assume (reasonably)
00531     // that m_name will be self-protecting
00532 
00533     m_hkey  =   rhs.m_hkey;
00534     m_index =   rhs.m_index;
00535     m_name  =   rhs.m_name;
00536 
00537     return *this;
00538 }
00539 
00540 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00541 inline basic_reg_key_sequence_const_iterator<C, T, V, A>::~basic_reg_key_sequence_const_iterator() winstl_throw_0()
00542 {}
00543 
00544 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00545 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type &basic_reg_key_sequence_const_iterator<C, T, V, A>::operator ++()
00546 {
00547     stlsoft_message_assert("Attempting to increment an invalid iterator!", sentinel_() != m_index);
00548 
00549     typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER>    buffer_t;
00550 
00551     // Grab enough for the first item
00552     size_type   cch_key_name    =   m_maxKnown;
00553     buffer_t    buffer(cch_key_name);
00554     ws_long_t   res             =   (0 == m_maxKnown) ? ERROR_MORE_DATA : traits_type::reg_enum_key(m_hkey, 1 + m_index, buffer, &cch_key_name, NULL, NULL, NULL);
00555 
00556     // The registry may have changed during the life of the iterator - albeit that's unlikely and undesirable - we
00557     // make sure we have enough size for a given item. More reasonably, m_maxKnown starts out life as 0
00558     if(ERROR_MORE_DATA == res)
00559     {
00560         if(0 != traits_type::reg_query_info(m_hkey, NULL, NULL, NULL, &cch_key_name, NULL, NULL, NULL, NULL, NULL, NULL))
00561         {
00562             m_index = sentinel_();
00563         }
00564         else
00565         {
00566             m_maxKnown = 1 + cch_key_name;
00567 
00568             if(buffer.resize(cch_key_name))
00569             {
00570                 res = traits_type::reg_enum_key(m_hkey, 1 + m_index, buffer, &cch_key_name, NULL, NULL, NULL);
00571             }
00572         }
00573     }
00574 
00575     if(res == 0)
00576     {
00577         buffer[cch_key_name] = 0;
00578 
00579         m_name = buffer.data();
00580 
00581         ++m_index;
00582     }
00583     else
00584     {
00585         m_index = sentinel_();
00586     }
00587 
00588     return *this;
00589 }
00590 
00591 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00592 inline ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type &basic_reg_key_sequence_const_iterator<C, T, V, A>::operator --()
00593 {
00594     typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, CCH_REG_API_AUTO_BUFFER>    buffer_t;
00595 
00596     // Grab enough for the first item
00597     size_type   cch_key_name    =   0;
00598     ws_uint_t   c_sub_keys;
00599     ws_long_t   res             =   traits_type::reg_query_info(m_hkey, NULL, NULL, &c_sub_keys, &cch_key_name, NULL, NULL, NULL, NULL, NULL, NULL);
00600 
00601     if(res == 0)
00602     {
00603         buffer_t    buffer(++cch_key_name);
00604 
00605         // If the iterator is currently at the "end()", ...
00606         if(m_index == sentinel_())
00607         {
00608             // ... then set the index to be one past the end
00609             m_index = c_sub_keys;
00610         }
00611 
00612         // Move back one position, and get the key name
00613         res = traits_type::reg_enum_key(m_hkey, --m_index, buffer, &cch_key_name, NULL, NULL, NULL);
00614 
00615         if(res == 0)
00616         {
00617             buffer[cch_key_name] = 0;
00618 
00619             m_name = buffer.data();
00620         }
00621         else
00622         {
00623             m_index = sentinel_();
00624         }
00625     }
00626     else
00627     {
00628         m_index = sentinel_();
00629     }
00630 
00631     return *this;
00632 }
00633 
00634 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00635 inline const ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type basic_reg_key_sequence_const_iterator<C, T, V, A>::operator ++(int)
00636 {
00637     class_type  ret(*this);
00638 
00639     operator ++();
00640 
00641     return ret;
00642 }
00643 
00644 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00645 inline const ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::class_type basic_reg_key_sequence_const_iterator<C, T, V, A>::operator --(int)
00646 {
00647     class_type  ret(*this);
00648 
00649     operator --();
00650 
00651     return ret;
00652 }
00653 
00654 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00655 inline const ss_typename_type_k basic_reg_key_sequence_const_iterator<C, T, V, A>::value_type basic_reg_key_sequence_const_iterator<C, T, V, A>::operator *() const
00656 {
00657     return value_type(m_hkey, m_name);
00658 }
00659 
00660 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00661 inline ws_bool_t basic_reg_key_sequence_const_iterator<C, T, V, A>::operator ==(class_type const &rhs) const
00662 {
00663     winstl_message_assert("Comparing reg_key_sequence iterators from different sequences!", m_hkey == rhs.m_hkey);
00664 
00665     return m_index == rhs.m_index;
00666 }
00667 
00668 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k V, ss_typename_param_k A>
00669 inline ws_bool_t basic_reg_key_sequence_const_iterator<C, T, V, A>::operator !=(class_type const &rhs) const
00670 {
00671     return ! operator ==(rhs);
00672 }
00673 
00674 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00675 
00676 /* 
00677 
00679 
00680 /* 
00681 
00682 #ifndef _WINSTL_NO_NAMESPACE
00683 # if defined(_STLSOFT_NO_NAMESPACE) || \
00684      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00685 } // namespace winstl
00686 # else
00687 } // namespace winstl_project
00688 } // namespace stlsoft
00689 # endif /* _STLSOFT_NO_NAMESPACE */
00690 #endif /* !_WINSTL_NO_NAMESPACE */
00691 
00692 /* 
00693 
00694 #endif /* WINSTL_INCL_H_WINSTL_REG_KEY_SEQUENCE */
00695 
00696 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004