Figure 2: Definition of classes automation_vector_base and automation_vector

template <class> class automation_vector;

class automation_vector_base
{
    friend void trace(CComVariant &v);
    typedef automation_vector_base self;
protected:
    ...
    void attach(VARIANT &v) throw(); 
    void detach(VARIANT &v) throw();
public:
    ...
    static void com_enforce(HRESULT hr) throw(std::runtime_error);
    // The size of the vector
    size_t size() const throw()
    {
        _ASSERT(valid());
        return m_Value.vt == VT_EMPTY ? 0 : bounds().cElements;
    }
    size_t capacity() const throw()
    {
        return size();
    }
    // checks whether the vector is empty
    bool empty() const throw()
    {
        return size() == 0;
    }
    ~automation_vector_base() throw();
    // Creation mode
    enum TCreateMode { MOVE, COPY };
protected:
    // Constructors/destructors are protected to prevent 
    // direct instantiation
    self(unsigned Elements, VARENUM VarType) 
        throw(std::invalid_argument, std::runtime_error);
    ...    
    void resize(size_type NewSize, VARENUM Type);
    void clear()
    {
        _ASSERT(!V_ISBYREF(&m_Value));
        _ASSERT(empty() || array().cLocks == 0);
        com_enforce(m_Value.Clear());
    }
    ...
private:
    ...

    // The actual holder of the array
    CComVariant m_Value;
};

inline void from_automation(SAFEARRAY &, void *)
{
}

inline void to_automation(SAFEARRAY &, void *)
{
}

template <class T>
void 
from_automation(SAFEARRAY &Array, automation_vector<T> *pDummy);

template <class T>
void 
to_automation(SAFEARRAY &Array, automation_vector<T> *pDummy);

template <class T> class automation_vector : 
    public automation_vector_base
{
    typedef automation_vector_base base;
    typedef automation_vector self;
    ...
public:
    ...
    // *** Static VARIANT type mapped from the C++ type
    static VARENUM myVARENUM()
    {
        // If you have an error on the line below, 
        // you've instantiated automation_vector with the 
        // wrong type
        static_checker<sizeof(T) == sizeof(
            Configure::deduceVARENUM(T()).size_checker)>();
        return static_cast<VARENUM>
            (Configure::deduceVARENUM(T()).vt);
    }
    automation_vector(VARIANT &vSource, TCreateMode Mode) 
        throw(std::invalid_argument, std::runtime_error)
        : base(0, myVARENUM())
    {
        if (Mode == COPY)
        {
            // Make a copy and attach to it
            CComVariant v(vSource);
            attach(v);
        }
        else
            // Attach directly to the source
            attach(vSource);
    }
    ...
    void attach(VARIANT &vSource) 
        throw(std::invalid_argument, std::runtime_error);
    void detach(VARIANT &Var)
    {
        _ASSERT(_CrtIsValidPointer(&Var, sizeof(VARIANT), true));
        com_enforce(::VariantClear(&Var));
        unlock();
        base::detach(Var);
    }
    CComVariant detach()
    {
        CComVariant v;
        detach(v);
        return v;
    }
    ...
protected:
    void lock();
    void unlock();
};