// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_
#define MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_

#include <cstddef>
#include <iosfwd>
#include <memory>
#include <new>

#include "mojo/public/cpp/bindings/type_converter.h"
#include "mojo/public/cpp/environment/logging.h"
#include "mojo/public/cpp/system/macros.h"

namespace mojo {
namespace internal {

template <typename Struct>
class StructHelper {
 public:
  template <typename Ptr>
  static void Initialize(Ptr* ptr) {
    ptr->Initialize();
  }
};

}  // namespace internal

// Smart pointer wrapping a mojom structure or union, with move-only semantics.
template <typename Struct>
class StructPtr {
 public:
  StructPtr() {}
  StructPtr(std::nullptr_t) {}

  ~StructPtr() {}

  StructPtr& operator=(std::nullptr_t) {
    reset();
    return *this;
  }

  StructPtr(StructPtr&& other) { Take(&other); }
  StructPtr& operator=(StructPtr&& other) {
    Take(&other);
    return *this;
  }

  template <typename U>
  U To() const {
    return TypeConverter<U, StructPtr>::Convert(*this);
  }

  void reset() { ptr_.reset(); }

  // Tests as true if non-null, false if null.
  explicit operator bool() const { return !!ptr_; }

  bool is_null() const { return !ptr_; }

  Struct& operator*() const {
    MOJO_DCHECK(ptr_);
    return *ptr_;
  }
  Struct* operator->() const {
    MOJO_DCHECK(ptr_);
    return ptr_.get();
  }
  Struct* get() const { return ptr_.get(); }

  void Swap(StructPtr* other) { std::swap(ptr_, other->ptr_); }

  // Please note that calling this method will fail compilation if the value
  // type |Struct| doesn't have a Clone() method defined (which usually means
  // that it contains Mojo handles).
  StructPtr Clone() const { return is_null() ? StructPtr() : ptr_->Clone(); }

  bool Equals(const StructPtr& other) const {
    if (is_null() || other.is_null())
      return is_null() && other.is_null();
    return ptr_->Equals(*other.ptr_);
  }

 private:
  friend class internal::StructHelper<Struct>;
  void Initialize() {
    MOJO_DCHECK(!ptr_);
    ptr_.reset(new Struct());
  }

  void Take(StructPtr* other) {
    reset();
    Swap(other);
  }

  std::unique_ptr<Struct> ptr_;

  MOJO_MOVE_ONLY_TYPE(StructPtr);
};

// Designed to be used when Struct is small and copyable. Unions are always
// InlinedStructPtr in practice.
template <typename Struct>
class InlinedStructPtr {
 public:
  InlinedStructPtr() : is_null_(true) {}
  InlinedStructPtr(decltype(nullptr)) : is_null_(true) {}

  ~InlinedStructPtr() {}

  InlinedStructPtr& operator=(decltype(nullptr)) {
    reset();
    return *this;
  }

  InlinedStructPtr(InlinedStructPtr&& other) : is_null_(true) { Take(&other); }
  InlinedStructPtr& operator=(InlinedStructPtr&& other) {
    Take(&other);
    return *this;
  }

  template <typename U>
  U To() const {
    return TypeConverter<U, InlinedStructPtr>::Convert(*this);
  }

  void reset() {
    is_null_ = true;
    value_.~Struct();
    new (&value_) Struct();
  }

  // Tests as true if non-null, false if null.
  explicit operator bool() const { return !is_null_; }

  bool is_null() const { return is_null_; }

  Struct& operator*() const {
    MOJO_DCHECK(!is_null_);
    return value_;
  }
  Struct* operator->() const {
    MOJO_DCHECK(!is_null_);
    return &value_;
  }
  Struct* get() const { return is_null() ? nullptr : &value_; }

  void Swap(InlinedStructPtr* other) {
    std::swap(value_, other->value_);
    std::swap(is_null_, other->is_null_);
  }

  InlinedStructPtr Clone() const {
    return is_null() ? InlinedStructPtr() : value_.Clone();
  }
  bool Equals(const InlinedStructPtr& other) const {
    if (is_null() || other.is_null())
      return is_null() && other.is_null();
    return value_.Equals(other.value_);
  }

 private:
  friend class internal::StructHelper<Struct>;
  void Initialize() { is_null_ = false; }

  void Take(InlinedStructPtr* other) {
    reset();
    Swap(other);
  }

  mutable Struct value_;
  bool is_null_;

  MOJO_MOVE_ONLY_TYPE(InlinedStructPtr);
};

// Prints the pointee of a Mojo structure pointer to an output stream
// for debugging purposes, assuming there exists an operator<< overload
// that accepts a const reference to the object.
template <typename T, typename = typename T::Data_>
auto operator<<(std::ostream& os, const T* value) -> decltype(os << *value) {
  return value ? os << *value : os << "null";
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const StructPtr<T>& value) {
  return os << value.get();
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const InlinedStructPtr<T>& value) {
  return os << value.get();
}

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_STRUCT_PTR_H_
