// -*- 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___RANGES_ACCESS_H
#define _LIBCPP___RANGES_ACCESS_H

#include <__concepts/class_or_enum.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/readable_traits.h>
#include <__ranges/enable_borrowed_range.h>
#include <__utility/auto_cast.h>
#include <type_traits>

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

_LIBCPP_BEGIN_NAMESPACE_STD

#if _LIBCPP_STD_VER > 17

namespace ranges {
  template <class _Tp>
  concept __can_borrow =
    is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;
} // namespace ranges

// [range.access.begin]

namespace ranges {
namespace __begin {
  template <class _Tp>
  concept __member_begin =
    __can_borrow<_Tp> &&
    __workaround_52970<_Tp> &&
    requires(_Tp&& __t) {
      { _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;
    };

  void begin(auto&) = delete;
  void begin(const auto&) = delete;

  template <class _Tp>
  concept __unqualified_begin =
    !__member_begin<_Tp> &&
    __can_borrow<_Tp> &&
    __class_or_enum<remove_cvref_t<_Tp>> &&
    requires(_Tp && __t) {
      { _LIBCPP_AUTO_CAST(begin(__t)) } -> input_or_output_iterator;
    };

  struct __fn {
    template <class _Tp>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept
      requires (sizeof(_Tp) >= 0)  // Disallow incomplete element types.
    {
      return __t + 0;
    }

    template <class _Tp, size_t _Np>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
      requires (sizeof(_Tp) >= 0)  // Disallow incomplete element types.
    {
      return __t + 0;
    }

    template <class _Tp>
      requires __member_begin<_Tp>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin())))
    {
      return _LIBCPP_AUTO_CAST(__t.begin());
    }

    template <class _Tp>
      requires __unqualified_begin<_Tp>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t))))
    {
      return _LIBCPP_AUTO_CAST(begin(__t));
    }

    void operator()(auto&&) const = delete;
  };
} // namespace __begin

inline namespace __cpo {
  inline constexpr auto begin = __begin::__fn{};
} // namespace __cpo
} // namespace ranges

// [range.range]

namespace ranges {
  template <class _Tp>
  using iterator_t = decltype(ranges::begin(declval<_Tp&>()));
} // namespace ranges

// [range.access.end]

namespace ranges {
namespace __end {
  template <class _Tp>
  concept __member_end =
    __can_borrow<_Tp> &&
    __workaround_52970<_Tp> &&
    requires(_Tp&& __t) {
      typename iterator_t<_Tp>;
      { _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;
    };

  void end(auto&) = delete;
  void end(const auto&) = delete;

  template <class _Tp>
  concept __unqualified_end =
    !__member_end<_Tp> &&
    __can_borrow<_Tp> &&
    __class_or_enum<remove_cvref_t<_Tp>> &&
    requires(_Tp && __t) {
      typename iterator_t<_Tp>;
      { _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp>>;
    };

  struct __fn {
    template <class _Tp, size_t _Np>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
      requires (sizeof(_Tp) >= 0)  // Disallow incomplete element types.
    {
      return __t + _Np;
    }

    template <class _Tp>
      requires __member_end<_Tp>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end())))
    {
      return _LIBCPP_AUTO_CAST(__t.end());
    }

    template <class _Tp>
      requires __unqualified_end<_Tp>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t))))
    {
      return _LIBCPP_AUTO_CAST(end(__t));
    }

    void operator()(auto&&) const = delete;
  };
} // namespace __end

inline namespace __cpo {
  inline constexpr auto end = __end::__fn{};
} // namespace __cpo
} // namespace ranges

// [range.access.cbegin]

namespace ranges {
namespace __cbegin {
  struct __fn {
    template <class _Tp>
      requires is_lvalue_reference_v<_Tp&&>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
    constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))))
      -> decltype(      ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)))
      { return          ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)); }

    template <class _Tp>
      requires is_rvalue_reference_v<_Tp&&>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
    constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t))))
      -> decltype(      ranges::begin(static_cast<const _Tp&&>(__t)))
      { return          ranges::begin(static_cast<const _Tp&&>(__t)); }
  };
} // namespace __cbegin

inline namespace __cpo {
  inline constexpr auto cbegin = __cbegin::__fn{};
} // namespace __cpo
} // namespace ranges

// [range.access.cend]

namespace ranges {
namespace __cend {
  struct __fn {
    template <class _Tp>
      requires is_lvalue_reference_v<_Tp&&>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
    constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))))
      -> decltype(      ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)))
      { return          ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)); }

    template <class _Tp>
      requires is_rvalue_reference_v<_Tp&&>
    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
    constexpr auto operator()(_Tp&& __t) const
      noexcept(noexcept(ranges::end(static_cast<const _Tp&&>(__t))))
      -> decltype(      ranges::end(static_cast<const _Tp&&>(__t)))
      { return          ranges::end(static_cast<const _Tp&&>(__t)); }
  };
} // namespace __cend

inline namespace __cpo {
  inline constexpr auto cend = __cend::__fn{};
} // namespace __cpo
} // namespace ranges

#endif // _LIBCPP_STD_VER > 17

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___RANGES_ACCESS_H
