//===-- ValueObjectList.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/ValueObjectList.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ValueObjectChild.h"
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"

using namespace lldb;
using namespace lldb_private;

ValueObjectList::ValueObjectList () :
    m_value_objects()
{
}

ValueObjectList::ValueObjectList (const ValueObjectList &rhs) :
    m_value_objects(rhs.m_value_objects)
{
}


ValueObjectList::~ValueObjectList ()
{
}

const ValueObjectList &
ValueObjectList::operator = (const ValueObjectList &rhs)
{
    if (this != &rhs)
        m_value_objects = rhs.m_value_objects;
    return *this;
}

void
ValueObjectList::Append (const ValueObjectSP &val_obj_sp)
{
    m_value_objects.push_back(val_obj_sp);
}

void
ValueObjectList::Append (const ValueObjectList &valobj_list)
{
    std::copy(valobj_list.m_value_objects.begin(),  // source begin
              valobj_list.m_value_objects.end(),    // source end
              back_inserter(m_value_objects));      // destination
    
}


size_t
ValueObjectList::GetSize() const
{
    return m_value_objects.size();
}

void
ValueObjectList::Resize (size_t size)
{
    m_value_objects.resize (size);
}

lldb::ValueObjectSP
ValueObjectList::GetValueObjectAtIndex (size_t idx)
{
    lldb::ValueObjectSP valobj_sp;
    if (idx < m_value_objects.size())
        valobj_sp = m_value_objects[idx];
    return valobj_sp;
}

lldb::ValueObjectSP
ValueObjectList::RemoveValueObjectAtIndex (size_t idx)
{
    lldb::ValueObjectSP valobj_sp;
    if (idx < m_value_objects.size())
    {
        valobj_sp = m_value_objects[idx];
        m_value_objects.erase (m_value_objects.begin() + idx);
    }
    return valobj_sp;
}

void
ValueObjectList::SetValueObjectAtIndex (size_t idx, const ValueObjectSP &valobj_sp)
{
    if (idx >= m_value_objects.size())
        m_value_objects.resize (idx + 1);
    m_value_objects[idx] = valobj_sp;
}

ValueObjectSP
ValueObjectList::FindValueObjectByValueName (const char *name)
{
    ConstString name_const_str(name);
    ValueObjectSP val_obj_sp;
    collection::iterator pos, end = m_value_objects.end();
    for (pos = m_value_objects.begin(); pos != end; ++pos)
    {
        ValueObject *valobj = (*pos).get();
        if (valobj && valobj->GetName() == name_const_str)
        {
            val_obj_sp = *pos;
            break;
        }
    }
    return val_obj_sp;
}

ValueObjectSP
ValueObjectList::FindValueObjectByUID (lldb::user_id_t uid)
{
    ValueObjectSP valobj_sp;
    collection::iterator pos, end = m_value_objects.end();

    for (pos = m_value_objects.begin(); pos != end; ++pos)
    {
        // Watch out for NULL objects in our list as the list
        // might get resized to a specific size and lazily filled in
        ValueObject *valobj = (*pos).get();
        if (valobj && valobj->GetID() == uid)
        {
            valobj_sp = *pos;
            break;
        }
    }
    return valobj_sp;
}


ValueObjectSP
ValueObjectList::FindValueObjectByPointer (ValueObject *find_valobj)
{
    ValueObjectSP valobj_sp;
    collection::iterator pos, end = m_value_objects.end();

    for (pos = m_value_objects.begin(); pos != end; ++pos)
    {
        ValueObject *valobj = (*pos).get();
        if (valobj && valobj == find_valobj)
        {
            valobj_sp = *pos;
            break;
        }
    }
    return valobj_sp;
}

void
ValueObjectList::Swap (ValueObjectList &value_object_list)
{
    m_value_objects.swap (value_object_list.m_value_objects);
}
