/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_LIBARTBASE_BASE_INTRUSIVE_FORWARD_LIST_H_
#define ART_LIBARTBASE_BASE_INTRUSIVE_FORWARD_LIST_H_

#include <stdint.h>
#include <functional>
#include <iterator>
#include <memory>
#include <type_traits>

#include <android-base/logging.h>

#include "base/casts.h"
#include "base/macros.h"

namespace art {

struct IntrusiveForwardListHook {
  IntrusiveForwardListHook() : next_hook(nullptr) { }
  explicit IntrusiveForwardListHook(const IntrusiveForwardListHook* hook) : next_hook(hook) { }

  // Allow copyable values but do not copy the hook, it is not part of the value.
  IntrusiveForwardListHook(const IntrusiveForwardListHook& other ATTRIBUTE_UNUSED)
      : next_hook(nullptr) { }
  IntrusiveForwardListHook& operator=(const IntrusiveForwardListHook& src ATTRIBUTE_UNUSED) {
    return *this;
  }

  mutable const IntrusiveForwardListHook* next_hook;
};

template <typename Derived, typename Tag = void>
struct IntrusiveForwardListNode : public IntrusiveForwardListHook {
};

template <typename T, IntrusiveForwardListHook T::* NextPtr = &T::hook>
class IntrusiveForwardListMemberHookTraits;

template <typename T, typename Tag = void>
class IntrusiveForwardListBaseHookTraits;

template <typename T,
          typename HookTraits = IntrusiveForwardListBaseHookTraits<std::remove_const_t<T>>>
class IntrusiveForwardList;

template <typename T, typename HookTraits>
class IntrusiveForwardListIterator : public std::iterator<std::forward_iterator_tag, T> {
 public:
  // Construct/copy/destroy (except the private constructor used by IntrusiveForwardList<>).
  IntrusiveForwardListIterator() : hook_(nullptr) { }
  IntrusiveForwardListIterator(const IntrusiveForwardListIterator& src) = default;
  IntrusiveForwardListIterator& operator=(const IntrusiveForwardListIterator& src) = default;

  // Conversion from iterator to const_iterator.
  template <typename OtherT,
            typename = std::enable_if_t<std::is_same_v<T, const OtherT>>>
  IntrusiveForwardListIterator(const IntrusiveForwardListIterator<OtherT, HookTraits>& src)  // NOLINT, implicit
      : hook_(src.hook_) { }

  // Iteration.
  IntrusiveForwardListIterator& operator++() {
    DCHECK(hook_ != nullptr);
    hook_ = hook_->next_hook;
    return *this;
  }
  IntrusiveForwardListIterator operator++(int) {
    IntrusiveForwardListIterator tmp(*this);
    ++*this;
    return tmp;
  }

  // Dereference
  T& operator*() const {
    DCHECK(hook_ != nullptr);
    return *HookTraits::GetValue(hook_);
  }
  T* operator->() const {
    return &**this;
  }

 private:
  explicit IntrusiveForwardListIterator(const IntrusiveForwardListHook* hook) : hook_(hook) { }

  const IntrusiveForwardListHook* hook_;

  template <typename OtherT, typename OtherTraits>
  friend class IntrusiveForwardListIterator;

  template <typename OtherT, typename OtherTraits>
  friend class IntrusiveForwardList;

  template <typename OtherT1, typename OtherT2, typename OtherTraits>
  friend std::enable_if_t<std::is_same_v<const OtherT1, const OtherT2>, bool>
  operator==(const IntrusiveForwardListIterator<OtherT1, OtherTraits>& lhs,
             const IntrusiveForwardListIterator<OtherT2, OtherTraits>& rhs);
};

template <typename T, typename OtherT, typename HookTraits>
std::enable_if_t<std::is_same_v<const T, const OtherT>, bool> operator==(
    const IntrusiveForwardListIterator<T, HookTraits>& lhs,
    const IntrusiveForwardListIterator<OtherT, HookTraits>& rhs) {
  return lhs.hook_ == rhs.hook_;
}

template <typename T, typename OtherT, typename HookTraits>
std::enable_if_t<std::is_same_v<const T, const OtherT>, bool> operator!=(
    const IntrusiveForwardListIterator<T, HookTraits>& lhs,
    const IntrusiveForwardListIterator<OtherT, HookTraits>& rhs) {
  return !(lhs == rhs);
}

// Intrusive version of std::forward_list<>. See also slist<> in Boost.Intrusive.
//
// This class template provides the same interface as std::forward_list<> as long
// as the functions are meaningful for an intrusive container; this excludes emplace
// functions and functions taking an std::initializer_list<> as the container does
// not construct elements.
template <typename T, typename HookTraits>
class IntrusiveForwardList {
 public:
  using hook_traits     = HookTraits;
  using value_type      = T;
  using reference       = T&;
  using const_reference = const T&;
  using pointer         = T*;
  using const_pointer   = const T*;
  using iterator        = IntrusiveForwardListIterator<T, hook_traits>;
  using const_iterator  = IntrusiveForwardListIterator<const T, hook_traits>;

  // Construct/copy/destroy.
  IntrusiveForwardList() = default;
  template <typename InputIterator>
  IntrusiveForwardList(InputIterator first, InputIterator last) : IntrusiveForwardList() {
    insert_after(before_begin(), first, last);
  }
  IntrusiveForwardList(IntrusiveForwardList&& src) noexcept : first_(src.first_.next_hook) {
    src.first_.next_hook = nullptr;
  }
  IntrusiveForwardList& operator=(const IntrusiveForwardList& src) = delete;
  IntrusiveForwardList& operator=(IntrusiveForwardList&& src) noexcept {
    IntrusiveForwardList tmp(std::move(src));
    tmp.swap(*this);
    return *this;
  }
  ~IntrusiveForwardList() = default;

  // Iterators.
  iterator before_begin() { return iterator(&first_); }
  const_iterator before_begin() const { return const_iterator(&first_); }
  iterator begin() { return iterator(first_.next_hook); }
  const_iterator begin() const { return const_iterator(first_.next_hook); }
  iterator end() { return iterator(nullptr); }
  const_iterator end() const { return const_iterator(nullptr); }
  const_iterator cbefore_begin() const { return const_iterator(&first_); }
  const_iterator cbegin() const { return const_iterator(first_.next_hook); }
  const_iterator cend() const { return const_iterator(nullptr); }

  // Capacity.
  bool empty() const { return begin() == end(); }
  size_t max_size() { return static_cast<size_t>(-1); }

  // Element access.
  reference front() { return *begin(); }
  const_reference front() const { return *begin(); }

  // Modifiers.
  template <typename InputIterator>
  void assign(InputIterator first, InputIterator last) {
    IntrusiveForwardList tmp(first, last);
    tmp.swap(*this);
  }
  void push_front(value_type& value) {
    insert_after(before_begin(), value);
  }
  void pop_front() {
    DCHECK(!empty());
    erase_after(before_begin());
  }
  iterator insert_after(const_iterator position, value_type& value) {
    const IntrusiveForwardListHook* new_hook = hook_traits::GetHook(&value);
    new_hook->next_hook = position.hook_->next_hook;
    position.hook_->next_hook = new_hook;
    return iterator(new_hook);
  }
  template <typename InputIterator>
  iterator insert_after(const_iterator position, InputIterator first, InputIterator last) {
    while (first != last) {
      position = insert_after(position, *first++);
    }
    return iterator(position.hook_);
  }
  iterator erase_after(const_iterator position) {
    const_iterator last = position;
    std::advance(last, 2);
    return erase_after(position, last);
  }
  iterator erase_after(const_iterator position, const_iterator last) {
    DCHECK(position != last);
    position.hook_->next_hook = last.hook_;
    return iterator(last.hook_);
  }
  void swap(IntrusiveForwardList& other) {
    std::swap(first_.next_hook, other.first_.next_hook);
  }
  void clear() {
    first_.next_hook = nullptr;
  }

  // Operations.
  void splice_after(const_iterator position, IntrusiveForwardList& src) {
    DCHECK(position != end());
    splice_after(position, src, src.before_begin(), src.end());
  }
  void splice_after(const_iterator position, IntrusiveForwardList&& src) {
    splice_after(position, src);  // Use l-value overload.
  }
  // Splice the element after `i`.
  void splice_after(const_iterator position, IntrusiveForwardList& src, const_iterator i) {
    // The standard specifies that this version does nothing if `position == i`
    // or `position == ++i`. We must handle the latter here because the overload
    // `splice_after(position, src, first, last)` does not allow `position` inside
    // the range `(first, last)`.
    if (++const_iterator(i) == position) {
      return;
    }
    const_iterator last = i;
    std::advance(last, 2);
    splice_after(position, src, i, last);
  }
  // Splice the element after `i`.
  void splice_after(const_iterator position, IntrusiveForwardList&& src, const_iterator i) {
    splice_after(position, src, i);  // Use l-value overload.
  }
  // Splice elements between `first` and `last`, i.e. open range `(first, last)`.
  void splice_after(const_iterator position,
                    IntrusiveForwardList& src,
                    const_iterator first,
                    const_iterator last) {
    DCHECK(position != end());
    DCHECK(first != last);
    if (++const_iterator(first) == last) {
      // Nothing to do.
      return;
    }
    // If position is just before end() and last is src.end(), we can finish this quickly.
    if (++const_iterator(position) == end() && last == src.end()) {
      position.hook_->next_hook = first.hook_->next_hook;
      first.hook_->next_hook = nullptr;
      return;
    }
    // Otherwise we need to find the position before last to fix up the hook.
    const_iterator before_last = first;
    while (++const_iterator(before_last) != last) {
      ++before_last;
    }
    // Detach (first, last).
    const IntrusiveForwardListHook* first_taken = first.hook_->next_hook;
    first.hook_->next_hook = last.hook_;
    // Attach the sequence to the new position.
    before_last.hook_->next_hook = position.hook_->next_hook;
    position.hook_->next_hook = first_taken;
  }
  // Splice elements between `first` and `last`, i.e. open range `(first, last)`.
  void splice_after(const_iterator position,
                    IntrusiveForwardList&& src,
                    const_iterator first,
                    const_iterator last) {
    splice_after(position, src, first, last);  // Use l-value overload.
  }
  void remove(const value_type& value) {
    remove_if([value](const value_type& v) { return value == v; });
  }
  template <typename Predicate>
  void remove_if(Predicate pred) {
    iterator prev = before_begin();
    for (iterator current = begin(); current != end(); ++current) {
      if (pred(*current)) {
        erase_after(prev);
        current = prev;
      } else {
        prev = current;
      }
    }
  }
  void unique() {
    unique(std::equal_to<value_type>());
  }
  template <typename BinaryPredicate>
  void unique(BinaryPredicate pred) {
    if (!empty()) {
      iterator prev = begin();
      iterator current = prev;
      ++current;
      for (; current != end(); ++current) {
        if (pred(*prev, *current)) {
          erase_after(prev);
          current = prev;
        } else {
          prev = current;
        }
      }
    }
  }
  void merge(IntrusiveForwardList& other) {
    merge(other, std::less<value_type>());
  }
  void merge(IntrusiveForwardList&& other) {
    merge(other);  // Use l-value overload.
  }
  template <typename Compare>
  void merge(IntrusiveForwardList& other, Compare cmp) {
    iterator prev = before_begin();
    iterator current = begin();
    iterator other_prev = other.before_begin();
    iterator other_current = other.begin();
    while (current != end() && other_current != other.end()) {
      if (cmp(*other_current, *current)) {
        ++other_current;
        splice_after(prev, other, other_prev);
        ++prev;
      } else {
        prev = current;
        ++current;
      }
      DCHECK(++const_iterator(prev) == current);
      DCHECK(++const_iterator(other_prev) == other_current);
    }
    splice_after(prev, other);
  }
  template <typename Compare>
  void merge(IntrusiveForwardList&& other, Compare cmp) {
    merge(other, cmp);  // Use l-value overload.
  }
  void sort() {
    sort(std::less<value_type>());
  }
  template <typename Compare>
  void sort(Compare cmp) {
    size_t n = std::distance(begin(), end());
    if (n >= 2u) {
      const_iterator middle = before_begin();
      std::advance(middle, n / 2u);
      IntrusiveForwardList second_half;
      second_half.splice_after(second_half.before_begin(), *this, middle, end());
      sort(cmp);
      second_half.sort(cmp);
      merge(second_half, cmp);
    }
  }
  void reverse() {
    IntrusiveForwardList reversed;
    while (!empty()) {
      value_type& value = front();
      erase_after(before_begin());
      reversed.insert_after(reversed.before_begin(), value);
    }
    reversed.swap(*this);
  }

  // Extensions.
  bool HasExactlyOneElement() const {
    return !empty() && ++begin() == end();
  }
  size_t SizeSlow() const {
    return std::distance(begin(), end());
  }
  bool ContainsNode(const_reference node) const {
    for (auto&& n : *this) {
      if (std::addressof(n) == std::addressof(node)) {
        return true;
      }
    }
    return false;
  }

 private:
  static IntrusiveForwardListHook* ModifiableHook(const IntrusiveForwardListHook* hook) {
    return const_cast<IntrusiveForwardListHook*>(hook);
  }

  IntrusiveForwardListHook first_;
};

template <typename T, typename HookTraits>
void swap(IntrusiveForwardList<T, HookTraits>& lhs, IntrusiveForwardList<T, HookTraits>& rhs) {
  lhs.swap(rhs);
}

template <typename T, typename HookTraits>
bool operator==(const IntrusiveForwardList<T, HookTraits>& lhs,
                const IntrusiveForwardList<T, HookTraits>& rhs) {
  auto lit = lhs.begin();
  auto rit = rhs.begin();
  for (; lit != lhs.end() && rit != rhs.end(); ++lit, ++rit) {
    if (*lit != *rit) {
      return false;
    }
  }
  return lit == lhs.end() && rit == rhs.end();
}

template <typename T, typename HookTraits>
bool operator!=(const IntrusiveForwardList<T, HookTraits>& lhs,
                const IntrusiveForwardList<T, HookTraits>& rhs) {
  return !(lhs == rhs);
}

template <typename T, typename HookTraits>
bool operator<(const IntrusiveForwardList<T, HookTraits>& lhs,
               const IntrusiveForwardList<T, HookTraits>& rhs) {
  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

template <typename T, typename HookTraits>
bool operator>(const IntrusiveForwardList<T, HookTraits>& lhs,
               const IntrusiveForwardList<T, HookTraits>& rhs) {
  return rhs < lhs;
}

template <typename T, typename HookTraits>
bool operator<=(const IntrusiveForwardList<T, HookTraits>& lhs,
                const IntrusiveForwardList<T, HookTraits>& rhs) {
  return !(rhs < lhs);
}

template <typename T, typename HookTraits>
bool operator>=(const IntrusiveForwardList<T, HookTraits>& lhs,
                const IntrusiveForwardList<T, HookTraits>& rhs) {
  return !(lhs < rhs);
}

template <typename T, IntrusiveForwardListHook T::* NextPtr>
class IntrusiveForwardListMemberHookTraits {
 public:
  static const IntrusiveForwardListHook* GetHook(const T* value) {
    return &(value->*NextPtr);
  }

  static T* GetValue(const IntrusiveForwardListHook* hook) {
    return reinterpret_cast<T*>(
        reinterpret_cast<uintptr_t>(hook) - OFFSETOF_MEMBERPTR(T, NextPtr));
  }
};

template <typename T, typename Tag>
class IntrusiveForwardListBaseHookTraits {
 public:
  static const IntrusiveForwardListHook* GetHook(const T* value) {
    // Explicit conversion to the "node" followed by implicit conversion to the "hook".
    return static_cast<const IntrusiveForwardListNode<T, Tag>*>(value);
  }

  static T* GetValue(const IntrusiveForwardListHook* hook) {
    return down_cast<T*>(down_cast<IntrusiveForwardListNode<T, Tag>*>(
        const_cast<IntrusiveForwardListHook*>(hook)));
  }
};

}  // namespace art

#endif  // ART_LIBARTBASE_BASE_INTRUSIVE_FORWARD_LIST_H_
