Listing 1: Definition of Slot<> and Index<> classes
// Listing 1: Definition of Slot<> and Index<> classes

template <typename C, size_t CCH>
struct Slot
{
  Slot(Slot *next)
    : next(next)
  {}
  ~Slot()
  {
    delete next;
  }

  // Use the process heap because:
  // 
  // 1. Don't want to worry about thread-specificity, since 
  //   deallocation will occur in a different thread to allocation
  // 2. Don't want to worry about linkage to any specific CRT or
    //      other library
  // 3. Doesn't matter how fast it is
  // 4. Want it to be *highly* unlikely that allocation will fail, 
  //    which is indeed pretty unheard of when using the Win32 
    //    process heap.
  // 5. Want a C++-exception free solution, so use the Win32-system
    //    out-of-memory exception, and not have to worry about any 
    //    linkage pains.
  void *operator new(size_t cb)
  {
    return ::HeapAlloc(::GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, cb);
  }
  void operator delete(void *pv)
  {
    ::HeapFree(::GetProcessHeap(), 0, pv);
  }

  C     buff[CCH];
  Slot  *next;
};

template <typename C, size_t CCH>
struct Index
{
  typedef Slot<C, CCH>  Slot;

  Index()
    : m_index(::TlsAlloc())
  {
    // Use Win32 exception because:
    //
    // 1. Process cannot recover from this error in any 
    // meaningful way
    // 2. Do not want to couple to C++ exception-handling
    // and there is no graceful way to allow this to be
    // parameterisable. (May allow a pp-discriminated
    // mechanism in next version.)
    if(TLS_OUT_OF_INDEXES == m_index)
    {
      ::RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, 0);
    }
  }

  ~Index()
  {
    // Walk the slot list and free. This can be as slow as 
    // you like, since performance is not important here
    delete m_top;

    // Now release the index
    ::TlsFree(m_index);
  }

  Slot *GetSlot()
  {
    // NOTE: This does not need to be thread-safe
    return reinterpret_cast<Slot*>(::TlsGetValue(m_index));
  }

  Slot *AllocSlot()
  {
    Slot  *next;

    { // Protect linked-list manipulation
      lock_scope<thread_mutex>  lock(m_mx);

      m_top = next = new Slot(m_top);
    }

    ::TlsSetValue(m_index, next);

    return next;
  }

private:
  ws_dword_t const  m_index;
  Slot              *m_top;
  thread_mutex      m_mx;
};