// -*- C++ -*-
//===--------------------------- __debug ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_DEBUG_H
#define _LIBCPP_DEBUG_H

#if _LIBCPP_DEBUG_LEVEL >= 1

#   include <cstdlib>
#   include <cstdio>
#   include <cstddef>
#   define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::printf("%s\n", m), _VSTD::abort()))

#endif

#if _LIBCPP_DEBUG_LEVEL >= 2

_LIBCPP_BEGIN_NAMESPACE_STD

struct _LIBCPP_VISIBLE __c_node;

struct _LIBCPP_VISIBLE __i_node
{
    void* __i_;
    __i_node* __next_;
    __c_node* __c_;

    __i_node(const __i_node&) = delete;
    __i_node& operator=(const __i_node&) = delete;
    _LIBCPP_INLINE_VISIBILITY
    __i_node(void* __i, __i_node* __next, __c_node* __c)
        : __i_(__i), __next_(__next), __c_(__c) {}
    ~__i_node();
};

struct _LIBCPP_VISIBLE __c_node
{
    void* __c_;
    __c_node* __next_;
    __i_node** beg_;
    __i_node** end_;
    __i_node** cap_;

    __c_node(const __c_node&) = delete;
    __c_node& operator=(const __c_node&) = delete;
    _LIBCPP_INLINE_VISIBILITY
    __c_node(void* __c, __c_node* __next)
        : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
    virtual ~__c_node();

    virtual bool __dereferenceable(const void*) const = 0;
    virtual bool __decrementable(const void*) const = 0;
    virtual bool __addable(const void*, ptrdiff_t) const = 0;
    virtual bool __subscriptable(const void*, ptrdiff_t) const = 0;

    void __add(__i_node* __i);
    _LIBCPP_HIDDEN void __remove(__i_node* __i);
};

template <class _Cont>
struct _C_node
    : public __c_node
{
    _C_node(void* __c, __c_node* __n)
        : __c_node(__c, __n) {}

    virtual bool __dereferenceable(const void*) const;
    virtual bool __decrementable(const void*) const;
    virtual bool __addable(const void*, ptrdiff_t) const;
    virtual bool __subscriptable(const void*, ptrdiff_t) const;
};

template <class _Cont>
bool
_C_node<_Cont>::__dereferenceable(const void* __i) const
{
    typedef typename _Cont::const_iterator iterator;
    const iterator* __j = static_cast<const iterator*>(__i);
    _Cont* _C = static_cast<_Cont*>(__c_);
    return _C->__dereferenceable(__j);
}

template <class _Cont>
bool
_C_node<_Cont>::__decrementable(const void* __i) const
{
    typedef typename _Cont::const_iterator iterator;
    const iterator* __j = static_cast<const iterator*>(__i);
    _Cont* _C = static_cast<_Cont*>(__c_);
    return _C->__decrementable(__j);
}

template <class _Cont>
bool
_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const
{
    typedef typename _Cont::const_iterator iterator;
    const iterator* __j = static_cast<const iterator*>(__i);
    _Cont* _C = static_cast<_Cont*>(__c_);
    return _C->__addable(__j, __n);
}

template <class _Cont>
bool
_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const
{
    typedef typename _Cont::const_iterator iterator;
    const iterator* __j = static_cast<const iterator*>(__i);
    _Cont* _C = static_cast<_Cont*>(__c_);
    return _C->__subscriptable(__j, __n);
}

class _LIBCPP_VISIBLE __libcpp_db
{
    __c_node** __cbeg_;
    __c_node** __cend_;
    size_t   __csz_;
    __i_node** __ibeg_;
    __i_node** __iend_;
    size_t   __isz_;

    __libcpp_db();
public:
    __libcpp_db(const __libcpp_db&) = delete;
    __libcpp_db& operator=(const __libcpp_db&) = delete;
    ~__libcpp_db();

    class __db_c_iterator;
    class __db_c_const_iterator;
    class __db_i_iterator;
    class __db_i_const_iterator;

    __db_c_const_iterator __c_end() const;
    __db_i_const_iterator __i_end() const;

    template <class _Cont>
    _LIBCPP_INLINE_VISIBILITY
    void __insert_c(_Cont* __c)
    {
        __c_node* __n = __insert_c(static_cast<void*>(__c));
        ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_);
    }

    void __insert_i(void* __i);
    __c_node* __insert_c(void* __c);
    void __erase_c(void* __c);

    void __insert_ic(void* __i, const void* __c);
    void __iterator_copy(void* __i, const void* __i0);
    void __erase_i(void* __i);

    void* __find_c_from_i(void* __i) const;
    void __invalidate_all(void* __c);
    __c_node* __find_c_and_lock(void* __c) const;
    __c_node* __find_c(void* __c) const;
    void unlock() const;

    void swap(void* __c1, void* __c2);


    bool __dereferenceable(const void* __i) const;
    bool __decrementable(const void* __i) const;
    bool __addable(const void* __i, ptrdiff_t __n) const;
    bool __subscriptable(const void* __i, ptrdiff_t __n) const;
    bool __comparable(const void* __i, const void* __j) const;
private:
    _LIBCPP_HIDDEN
    __i_node* __insert_iterator(void* __i);
    _LIBCPP_HIDDEN
    __i_node* __find_iterator(const void* __i) const;

    friend _LIBCPP_VISIBLE __libcpp_db* __get_db();
};

_LIBCPP_VISIBLE __libcpp_db* __get_db();
_LIBCPP_VISIBLE const __libcpp_db* __get_const_db();


_LIBCPP_END_NAMESPACE_STD

#endif

#endif  // _LIBCPP_DEBUG_H

