//===----------------------------------------------------------------------===//
//
// 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___ITERATOR_ALIASING_ITERATOR_H
#define _LIBCPP___ITERATOR_ALIASING_ITERATOR_H

#include <__config>
#include <__cstddef/ptrdiff_t.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/is_trivially_constructible.h>
#include <__type_traits/is_trivially_copyable.h>

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

// This iterator wrapper is used to type-pun an iterator to return a different type. This is done without UB by not
// actually punning the type, but instead inspecting the object representation of the base type and copying that into
// an instance of the alias type. For that reason the alias type has to be trivial. The alias is returned as a prvalue
// when derferencing the iterator, since it is temporary storage. This wrapper is used to vectorize some algorithms.

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _BaseIter, class _Alias>
struct __aliasing_iterator_wrapper {
  class __iterator {
    _BaseIter __base_ = nullptr;

    using __iter_traits _LIBCPP_NODEBUG     = iterator_traits<_BaseIter>;
    using __base_value_type _LIBCPP_NODEBUG = typename __iter_traits::value_type;

    static_assert(__has_random_access_iterator_category<_BaseIter>::value,
                  "The base iterator has to be a random access iterator!");

  public:
    using iterator_category = random_access_iterator_tag;
    using value_type        = _Alias;
    using difference_type   = ptrdiff_t;
    using reference         = value_type&;
    using pointer           = value_type*;

    static_assert(is_trivially_default_constructible<value_type>::value);
    static_assert(is_trivially_copyable<value_type>::value);
    static_assert(sizeof(__base_value_type) == sizeof(value_type));

    _LIBCPP_HIDE_FROM_ABI __iterator() = default;
    _LIBCPP_HIDE_FROM_ABI __iterator(_BaseIter __base) _NOEXCEPT : __base_(__base) {}

    _LIBCPP_HIDE_FROM_ABI __iterator& operator++() _NOEXCEPT {
      ++__base_;
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI __iterator operator++(int) _NOEXCEPT {
      __iterator __tmp(*this);
      ++__base_;
      return __tmp;
    }

    _LIBCPP_HIDE_FROM_ABI __iterator& operator--() _NOEXCEPT {
      --__base_;
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI __iterator operator--(int) _NOEXCEPT {
      __iterator __tmp(*this);
      --__base_;
      return __tmp;
    }

    _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(__iterator __iter, difference_type __n) _NOEXCEPT {
      return __iterator(__iter.__base_ + __n);
    }

    _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(difference_type __n, __iterator __iter) _NOEXCEPT {
      return __iterator(__n + __iter.__base_);
    }

    _LIBCPP_HIDE_FROM_ABI __iterator& operator+=(difference_type __n) _NOEXCEPT {
      __base_ += __n;
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI friend __iterator operator-(__iterator __iter, difference_type __n) _NOEXCEPT {
      return __iterator(__iter.__base_ - __n);
    }

    _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(__iterator __lhs, __iterator __rhs) _NOEXCEPT {
      return __lhs.__base_ - __rhs.__base_;
    }

    _LIBCPP_HIDE_FROM_ABI __iterator& operator-=(difference_type __n) _NOEXCEPT {
      __base_ -= __n;
      return *this;
    }

    _LIBCPP_HIDE_FROM_ABI _BaseIter __base() const _NOEXCEPT { return __base_; }

    _LIBCPP_HIDE_FROM_ABI _Alias operator*() const _NOEXCEPT {
      _Alias __val;
      __builtin_memcpy(std::addressof(__val), std::__to_address(__base_), sizeof(value_type));
      return __val;
    }

    _LIBCPP_HIDE_FROM_ABI value_type operator[](difference_type __n) const _NOEXCEPT { return *(*this + __n); }

    _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT {
      return __lhs.__base_ == __rhs.__base_;
    }

    _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT {
      return __lhs.__base_ != __rhs.__base_;
    }
  };
};

// This is required to avoid ADL instantiations on _BaseT
template <class _BaseT, class _Alias>
using __aliasing_iterator _LIBCPP_NODEBUG = typename __aliasing_iterator_wrapper<_BaseT, _Alias>::__iterator;

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___ITERATOR_ALIASING_ITERATOR_H
