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

// This file extends stlport's <memory> implementation to provide support for:
//  - std::shared_ptr (C++11)
//  - std::unique_ptr (C++11)

// Cloned from master branch vendor/google/native/cmds/sysproxy/shared_ptr.h
// Upstream commit ff64c352c35c46a14f15503778781889a816eea4
// Upstream Change-Id: I481ec53b08beecde2bf6dc38e5933342235da3d9

#include <stlport/memory>

namespace std {

template <typename T>
class shared_ptr {
 public:
  shared_ptr();
  explicit shared_ptr(T *value);
  shared_ptr(const shared_ptr &rhs);
  shared_ptr &operator=(const shared_ptr &rhs);
  template <typename U>
  shared_ptr(const shared_ptr<U> &rhs);
  template <typename U>
  shared_ptr &operator=(const shared_ptr<U> &rhs);
  ~shared_ptr();

  T *get() const;
  T *operator->() const;
  T &operator*() const;

  template <typename U>
  bool operator==(const shared_ptr<U> &rhs) const;
  template <typename U>
  bool operator!=(const shared_ptr<U> &rhs) const;
  template <typename U>
  bool operator<(const shared_ptr<U> &rhs) const;
  template <typename U>
  bool operator<=(const shared_ptr<U> &rhs) const;
  template <typename U>
  bool operator>(const shared_ptr<U> &rhs) const;
  template <typename U>
  bool operator>=(const shared_ptr<U> &rhs) const;

  void reset(T *value = NULL);

  // TODO(haining) Work with Deleter

 private:
  template <typename U>
  friend class shared_ptr;

  struct Node {
    T *value;
    int *count;
  };
  // Thread safe decrement, deletes node_ if holding last remaining reference.
  // Any use of node_ after calling this function is unsafe unless node_ is
  // reassigned.
  void DecNode();

  // Thread safe increment.
  void IncNode();

  // Creates a Node referring to NULL.
  static Node NewNullNode();

  // Creates a Node referring to value.
  static Node NewNodeFor(T *value);

  Node node_;
};

template <typename T>
typename shared_ptr<T>::Node shared_ptr<T>::NewNodeFor(T *value) {
  Node n = {value, new int(1)};
  return n;
}

template <typename T>
typename shared_ptr<T>::Node shared_ptr<T>::NewNullNode() {
  return NewNodeFor(NULL);
}

template <typename T>
void shared_ptr<T>::reset(T *value) {
  DecNode();
  node_ = NewNodeFor(value);
}

template <typename T>
shared_ptr<T>::shared_ptr() : node_(NewNullNode()) {}

template <typename T>
void shared_ptr<T>::DecNode() {
  bool should_delete = __atomic_fetch_sub(node_.count, 1, __ATOMIC_SEQ_CST) == 0;
  // The only accesses to node_ that should be made after this line is the
  // deletion conditional on should_delete. Anything else is unsafe since
  // because another thread could have deleted node_
  if (should_delete) {
    delete node_.value;
    delete node_.count;
    node_.value = NULL;
    node_.count = NULL;
  }
}

template <typename T>
void shared_ptr<T>::IncNode() {
  __atomic_fetch_add(node_.count, 1, __ATOMIC_SEQ_CST);
}

template <typename T>
shared_ptr<T>::shared_ptr(T *value) {
  node_ = NewNodeFor(value);
}

template <typename T>
shared_ptr<T>::shared_ptr(const shared_ptr &rhs) : node_(rhs.node_) {
  IncNode();
}

template <typename T>
template <typename U>
shared_ptr<T>::shared_ptr(const shared_ptr<U> &rhs) {
  node_.value = rhs.node_.value;
  node_.count = rhs.node_.count;
  node_.m = rhs.node_.m;
  IncNode();
}

template <typename T>
shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr &rhs) {
  if (node_.value == rhs.node_.value) {
    return *this;
  }

  DecNode();
  node_ = rhs.node_;
  IncNode();
  return *this;
}

template <typename T>
template <typename U>
shared_ptr<T> &shared_ptr<T>::operator=(const shared_ptr<U> &rhs) {
  if (node_.value == rhs.node_.value) {
    return *this;
  }

  DecNode();
  node_.value = rhs.node_.value;
  node_.count = rhs.node_.count;
  node_.m = rhs.node_.m;
  IncNode();
  return *this;
}

template <typename T>
shared_ptr<T>::~shared_ptr() {
  DecNode();
}

template <typename T>
T *shared_ptr<T>::get() const {
  return node_.value;
}

template <typename T>
T *shared_ptr<T>::operator->() const {
  return get();
}

template <typename T>
T &shared_ptr<T>::operator*() const {
  return *node_.value;
}

template <typename T>
template <typename U>
bool shared_ptr<T>::operator==(const shared_ptr<U> &rhs) const {
  return node_.value == rhs.node_.value;
}

template <typename T>
template <typename U>
bool shared_ptr<T>::operator!=(const shared_ptr<U> &rhs) const {
  return node_.value != rhs.node_.value;
}

template <typename T>
template <typename U>
bool shared_ptr<T>::operator<(const shared_ptr<U> &rhs) const {
  return node_.value < rhs.node_.value;
}

template <typename T>
template <typename U>
bool shared_ptr<T>::operator<=(const shared_ptr<U> &rhs) const {
  return node_.value <= rhs.node_.value;
}

template <typename T>
template <typename U>
bool shared_ptr<T>::operator>(const shared_ptr<U> &rhs) const {
  return node_.value > rhs.node_.value;
}

template <typename T>
template <typename U>
bool shared_ptr<T>::operator>=(const shared_ptr<U> &rhs) const {
  return node_.value >= rhs.node_.value;
}

#if !defined(DISALLOW_COPY_AND_ASSIGN)
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&);               \
  void operator=(const TypeName&);
#endif

#include <cstddef>

// Default deleter for pointer types.
template <typename T>
struct DefaultDelete {
  void operator()(T* p) const { delete p; }
};

// Default deleter for array types.
template <typename T>
struct DefaultDelete<T[]> {
  void operator()(T* p) const { delete[] p; }
};

// A smart pointer that deletes the given pointer on destruction.
// Equivalent to C++11's std::unique_ptr
// Named to be in keeping with Android style but also to avoid
// collision with any other implementation, until we can switch over
// to unique_ptr.
// Use thus:
//   unique_ptr<C> c(new C);

namespace workaround_internal {
template <typename T, typename Deleter>
class UniquePtrBase {
 public:
  // Construct a new UniquePtrBase, taking ownership of the given raw pointer.
  explicit UniquePtrBase(T* ptr = 0) : mPtr(ptr), mDeleter() {}
  explicit UniquePtrBase(T* ptr, Deleter d) : mPtr(ptr), mDeleter(d) {}

  ~UniquePtrBase() { reset(); }

  // Accessors.
  T* get() const { return mPtr; }

  // Returns the raw pointer and hands over ownership to the caller.
  // The pointer will not be deleted by UniquePtrBase.
  T* release() {
    T* result = mPtr;
    mPtr = 0;
    return result;
  }

  // Takes ownership of the given raw pointer.
  // If this smart pointer previously owned a different raw pointer, that
  // raw pointer will be freed.
  void reset(T* ptr = 0) {
    T* old_ptr = mPtr;
    mPtr = ptr;
    if (old_ptr != NULL && mPtr != old_ptr) {
      get_deleter()(old_ptr);
    }
  }

  Deleter& get_deleter() { return mDeleter; }
  const Deleter& get_deleter() const { return mDeleter; }

 private:
  // This is so users can compare against null. Callers should be able
  // to invoke operator== and operator!= above with NULL pointers but not
  // with any other pointer.
  struct RawDummy {};

 public:
  bool operator==(const RawDummy*) const { return get() == NULL; }
  friend bool operator==(const RawDummy*, const UniquePtrBase& self) {
    return self == NULL;
  }

  bool operator!=(const RawDummy*) const { return !(*this == NULL); }
  friend bool operator!=(const RawDummy*, const UniquePtrBase& self) {
    return self != NULL;
  }

 private:
  // The raw pointer.
  T* mPtr;
  Deleter mDeleter;

  DISALLOW_COPY_AND_ASSIGN(UniquePtrBase);
};
}  // namespace workaround_internal

template <typename T, typename Deleter = DefaultDelete<T> >
class unique_ptr : public workaround_internal::UniquePtrBase<T, Deleter> {
  typedef workaround_internal::UniquePtrBase<T, Deleter> Base;
 public:
  // Construct a new unique_ptr, taking ownership of the given raw pointer.
  explicit unique_ptr(T* ptr = 0) : Base(ptr) { }
  explicit unique_ptr(T* ptr, Deleter d) : Base(ptr, d) { }

  T& operator*() const { return *this->get(); }
  T* operator->() const { return this->get(); }
};

// Partial specialization for array types. Like std::unique_ptr, this removes
// operator* and operator-> but adds operator[].
template <typename T, typename Deleter>
class unique_ptr<T[], Deleter> : public workaround_internal::UniquePtrBase<T, Deleter> {
  typedef workaround_internal::UniquePtrBase<T, Deleter> Base;
 public:
  explicit unique_ptr(T* ptr = 0) : Base(ptr) { }
  explicit unique_ptr(T* ptr, Deleter d) : Base(ptr, d) { }

  T& operator[](std::ptrdiff_t i) const { return this->get()[i]; }
};

template <typename T>
shared_ptr<T> make_shared() {
  return shared_ptr<T>(new T);
}

}  // namespace std

#endif  // _STLPORT_CPP11_EXTENSION_MEMORY_
