Listing 3 reg_key_sequence


// Extract from winstl_reg_key_sequence.h


template< ws_typename_param_k C
        , ws_typename_param_k T = reg_traits<C>
        , ws_typename_param_k A = processheap_allocator<C>
        >
class basic_reg_key_sequence
{
public:
  typedef C                                         char_type;
  typedef T                                         traits_type;
  typedef A                                         allocator_type;
  typedef basic_reg_key_sequence<C, T, A>           class_type;
  typedef basic_reg_key<C, T, A>                    key_type;
  typedef const key_type                            value_type;
  typedef ws_typename_type_k traits_type::size_type size_type;
  typedef basic_reg_key<C, T, A>                    reg_key_type;
  typedef basic_reg_key_sequence_const_iterator<C, T, value_type, A>
                                                    const_iterator;
  typedef key_type                                  &reference;
  typedef key_type const                            &const_reference;
  typedef ws_ptrdiff_t                              difference_type;

  typedef stlsoft::const_reverse_bidirectional_iterator_base< 
                    const_iterator, value_type, 
                    value_type, void*, 
                    difference_type>          const_reverse_iterator;

// Construction
public:
  basic_reg_key_sequence(HKEY hkey, char_type const *sub_key_name);
  basic_reg_key_sequence(reg_key_type const &key);
  ~basic_reg_key_sequence() winstl_throw_0();

// Iteration
public:
  const_iterator          begin() const;
  const_iterator          end() const;

  const_reverse_iterator  rbegin() const;
  const_reverse_iterator  rend() const;

// State
public:
  size_type         size() const;
  ws_bool_t         empty() const;
  static size_type  max_size();

// Members
private:
  HKEY  m_hkey;

// Not to be implemented
private:
  basic_reg_key_sequence(class_type const &);
  basic_reg_key_sequence const &operator =(class_type const &);
};


template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline basic_reg_key_sequence<C, T, A>::
    basic_reg_key_sequence(HKEY hkey, char_type const *sub_key_name)
  : m_hkey(NULL)
{
  if(0 != traits_type::reg_open_key(hkey, sub_key_name, &m_hkey))
  {
    m_hkey = NULL;
  }
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline basic_reg_key_sequence<C, T, A>::
    basic_reg_key_sequence(reg_key_type const &key)
  : m_hkey(traits_type::key_dup(key.m_hkey))
{
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline basic_reg_key_sequence<C, T, A>::
    ~basic_reg_key_sequence() winstl_throw_0()
{
  if(m_hkey != NULL)
  {
    ::RegCloseKey(m_hkey);
  }
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline ws_typename_type_k const_iterator 
    basic_reg_key_sequence<C, T, A>::begin() const
{
  // Grab enough for the first item
  size_type cch_key_name  = 0;
  ws_long_t res     = traits_type::reg_query_info(m_hkey, 
                        NULL, NULL, NULL, &cch_key_name,
                        NULL, NULL, NULL, NULL, NULL, NULL);

  if(res == 0)
  {
    auto_buffer<char_type, allocator_type>  buffer(++cch_key_name);

    res = traits_type::reg_enum_key(m_hkey, 0, buffer, 
                          &cch_key_name, NULL, NULL, NULL);

    if(res == 0)
    {
      return const_iterator(m_hkey, 0, buffer);
    }
  }

  return end();
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline ws_typename_type_k const_iterator 
    basic_reg_key_sequence<C, T, A>::end() const
{
  return const_iterator(m_hkey);
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline ws_typename_type_k const_reverse_iterator 
    basic_reg_key_sequence<C, T, A>::rbegin() const
{
  return const_reverse_iterator(end());
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline ws_typename_type_k const_reverse_iterator 
    basic_reg_key_sequence<C, T, A>::rend() const
{
  return const_reverse_iterator(begin());
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline ws_typename_type_k size_type 
    basic_reg_key_sequence<C, T, A>::size() const
{
  ws_uint_t c_sub_keys;
  ws_long_t res = traits_type::reg_query_info(m_hkey, NULL, NULL, 
                                  &c_sub_keys, NULL, NULL, NULL,
                                  NULL, NULL, NULL, NULL);

  if(res != 0)
  {
    c_sub_keys = 0;
  }

  return static_cast<size_type>(c_sub_keys);
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline ws_bool_t basic_reg_key_sequence<C, T, A>::empty() const
{
  return size() == 0;
}

template< ws_typename_param_k C
        , ws_typename_param_k T
        , ws_typename_param_k A
        >
inline size_type 
  basic_reg_key_sequence<C, T, A>::max_size()
{
  return static_cast<size_type>(-1);
}