// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___DEBUG
#define _LIBCPP___DEBUG

#include <__assert>
#include <__config>
#include <__type_traits/is_constant_evaluated.h>
#include <cstddef>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY)
# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY
#endif

#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING)
# define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING
#endif

#ifdef _LIBCPP_ENABLE_DEBUG_MODE
#   define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m)
#else
#   define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
#endif

#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)

_LIBCPP_BEGIN_NAMESPACE_STD

struct _LIBCPP_TYPE_VIS __c_node;

struct _LIBCPP_TYPE_VIS __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_TYPE_VIS __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
    explicit __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
{
    explicit _C_node(void* __c, __c_node* __n)
        : __c_node(__c, __n) {}

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

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

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

template <class _Cont>
inline 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* _Cp = static_cast<_Cont*>(__c_);
    return _Cp->__addable(__j, __n);
}

template <class _Cont>
inline 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* _Cp = static_cast<_Cont*>(__c_);
    return _Cp->__subscriptable(__j, __n);
}

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

    explicit __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;

    typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*);

    template <class _Cont>
    _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) {
        return ::new (__mem) _C_node<_Cont>(__c, __next);
    }

    template <class _Cont>
    _LIBCPP_INLINE_VISIBILITY
    void __insert_c(_Cont* __c)
    {
        __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>);
    }

    void __insert_i(void* __i);
    void __insert_c(void* __c, _InsertConstruct* __fn);
    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 __less_than_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_FUNC_VIS __libcpp_db* __get_db();
};

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

_LIBCPP_END_NAMESPACE_STD

#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY)

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) {
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
    if (!__libcpp_is_constant_evaluated())
        __get_db()->__insert_c(__c);
#else
    (void)(__c);
#endif
}

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) {
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
    if (!__libcpp_is_constant_evaluated())
        __get_db()->__insert_i(__i);
#else
    (void)(__i);
#endif
}

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) {
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
    if (!__libcpp_is_constant_evaluated())
        __get_db()->__erase_c(__c);
#else
    (void)(__c);
#endif
}

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) {
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
    if (!__libcpp_is_constant_evaluated())
        __get_db()->swap(__lhs, __rhs);
#else
    (void)(__lhs);
    (void)(__rhs);
#endif
}

template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) {
#ifdef _LIBCPP_ENABLE_DEBUG_MODE
    if (!__libcpp_is_constant_evaluated())
        __get_db()->__invalidate_all(__c);
#else
    (void)(__c);
#endif
}

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___DEBUG
