bool STObject::setType (const SOTemplate& type)
{
    boost::ptr_vector<SerializedType> newData (type.peek ().size ());
    bool valid = true;

    mType = &type;

    BOOST_FOREACH (const SOElement * elem, type.peek ())
    {
        bool match = false;

        for (boost::ptr_vector<SerializedType>::iterator it = mData.begin (); it != mData.end (); ++it)
            if (it->getFName () == elem->e_field)
            {
                // matching entry, move to new vector
                match = true;

                if ((elem->flags == SOE_DEFAULT) && it->isDefault ())
                {
                    WriteLog (lsWARNING, STObject) << "setType( " << getFName ().getName () << ") invalid default "
                                                   << elem->e_field.fieldName;
                    valid = false;
                }

                newData.push_back (mData.release (it).release ()); // CAUTION: This renders 'it' invalid
                break;
            }

        if (!match)
        {
            // no match found
            if (elem->flags == SOE_REQUIRED)
            {
                WriteLog (lsWARNING, STObject) << "setType( " << getFName ().getName () << ") invalid missing "
                                               << elem->e_field.fieldName;
                valid = false;
            }

            newData.push_back (makeNonPresentObject (elem->e_field).release ());
        }
    }

    BOOST_FOREACH (const SerializedType & t, mData)
    {
        // Anything left over must be discardable
        if (!t.getFName ().isDiscardable ())
        {
            WriteLog (lsWARNING, STObject) << "setType( " << getFName ().getName () << ") invalid leftover "
                                           << t.getFName ().getName ();
            valid = false;
        }
    }

    mData.swap (newData);
    return valid;
}
void STObject::set (const SOTemplate& type)
{
    mData.clear ();
    mType = &type;

    BOOST_FOREACH (const SOElement * elem, type.peek ())
    {
        if (elem->flags != SOE_REQUIRED)
            giveObject (makeNonPresentObject (elem->e_field));
        else
            giveObject (makeDefaultObject (elem->e_field));
    }
}
void STObject::set (const SOTemplate& type)
{
    mData.clear ();
    mType = &type;

    for (SOTemplate::value_type const& elem : type.peek ())
    {
        if (elem->flags != SOE_REQUIRED)
            giveObject (makeNonPresentObject (elem->e_field));
        else
            giveObject (makeDefaultObject (elem->e_field));
    }
}
void STObject::set(const std::vector<SOElement::ref>& type)
{
	mData.clear();
	mType.clear();

	BOOST_FOREACH(SOElement::ref elem, type)
	{
		mType.push_back(elem);
		if (elem->flags != SOE_REQUIRED)
			giveObject(makeNonPresentObject(elem->e_field));
		else
			giveObject(makeDefaultObject(elem->e_field));
	}
void STObject::makeFieldAbsent (SField::ref field)
{
    int index = getFieldIndex (field);

    if (index == -1)
        throw std::runtime_error ("Field not found");

    const SerializedType& f = peekAtIndex (index);

    if (f.getSType () == STI_NOTPRESENT)
        return;

    mData.replace (index, makeNonPresentObject (f.getFName ()).release ());
}
SerializedType* STObject::makeFieldPresent (SField::ref field)
{
    int index = getFieldIndex (field);

    if (index == -1)
    {
        if (!isFree ())
            throw std::runtime_error ("Field not found");

        return getPIndex (giveObject (makeNonPresentObject (field)));
    }

    SerializedType* f = getPIndex (index);

    if (f->getSType () != STI_NOTPRESENT)
        return f;

    mData.replace (index, makeDefaultObject (f->getFName ()).release ());
    return getPIndex (index);
}