ART: Clean up obj_ptr.h and obj_ptr-inl.h .

Move ObjPtr<> member function definitions that depend on
other functions in obj_ptr-inl.h also to the obj_ptr-inl.h.
Use C++14 std::enable_if_t<> and C++17 std::is_base_of_v<>.
Improve kObjPtrPoisoningValidateOnCopy code readability
(avoid ternary operator). Move relational opeators to
namespace scope and reimplement != as negation of ==.

Also move PtrCompression<>::Compress(ObjPtr<>) to the
object_reference-inl.h which includes obj_ptr-inl.h.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I5116c0e322775c19a88687f30742ef654a8be873
diff --git a/runtime/mirror/object_reference-inl.h b/runtime/mirror/object_reference-inl.h
index 780d662..183a5af 100644
--- a/runtime/mirror/object_reference-inl.h
+++ b/runtime/mirror/object_reference-inl.h
@@ -24,6 +24,11 @@
 namespace art {
 namespace mirror {
 
+template<bool kPoisonReferences, class MirrorType>
+inline uint32_t PtrCompression<kPoisonReferences, MirrorType>::Compress(ObjPtr<MirrorType> ptr) {
+  return Compress(ptr.Ptr());
+}
+
 template <bool kPoisonReferences, class MirrorType>
 ALWAYS_INLINE
 void ObjectReference<kPoisonReferences, MirrorType>::Assign(ObjPtr<MirrorType> ptr) {
diff --git a/runtime/mirror/object_reference.h b/runtime/mirror/object_reference.h
index e19e165..f01bcbd 100644
--- a/runtime/mirror/object_reference.h
+++ b/runtime/mirror/object_reference.h
@@ -48,9 +48,7 @@
   }
 
   // Convert an ObjPtr to a compressed reference.
-  static uint32_t Compress(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_) {
-    return Compress(ptr.Ptr());
-  }
+  static uint32_t Compress(ObjPtr<MirrorType> ptr) REQUIRES_SHARED(Locks::mutator_lock_);
 };
 
 // Value type representing a reference to a mirror::Object of type MirrorType.
diff --git a/runtime/obj_ptr-inl.h b/runtime/obj_ptr-inl.h
index f096445..3eb5b15 100644
--- a/runtime/obj_ptr-inl.h
+++ b/runtime/obj_ptr-inl.h
@@ -64,6 +64,121 @@
 }
 
 template<class MirrorType>
+template <typename Type,
+          typename /* = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>> */>
+inline ObjPtr<MirrorType>::ObjPtr(Type* ptr)
+    : reference_(Encode(static_cast<MirrorType*>(ptr))) {
+}
+
+template<class MirrorType>
+template <typename Type,
+          typename /* = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>> */>
+inline ObjPtr<MirrorType>::ObjPtr(const ObjPtr<Type>& other)
+    : reference_(other.reference_) {
+  if (kObjPtrPoisoningValidateOnCopy) {
+    AssertValid();
+  }
+}
+
+template<class MirrorType>
+template <typename Type,
+          typename /* = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>> */>
+inline ObjPtr<MirrorType>& ObjPtr<MirrorType>::operator=(const ObjPtr<Type>& other) {
+  reference_ = other.reference_;
+  if (kObjPtrPoisoningValidateOnCopy) {
+    AssertValid();
+  }
+  return *this;
+}
+
+template<class MirrorType>
+OBJPTR_INLINE ObjPtr<MirrorType>& ObjPtr<MirrorType>::operator=(MirrorType* ptr) {
+  Assign(ptr);
+  return *this;
+}
+
+template<class MirrorType>
+inline void ObjPtr<MirrorType>::Assign(MirrorType* ptr) {
+  reference_ = Encode(ptr);
+}
+
+template<class MirrorType>
+inline MirrorType* ObjPtr<MirrorType>::operator->() const {
+  return Ptr();
+}
+
+template<class MirrorType>
+inline MirrorType* ObjPtr<MirrorType>::Ptr() const {
+  AssertValid();
+  return PtrUnchecked();
+}
+
+template<class MirrorType>
+template <typename SourceType>
+inline ObjPtr<MirrorType> ObjPtr<MirrorType>::DownCast(ObjPtr<SourceType> ptr) {
+  static_assert(std::is_base_of_v<SourceType, MirrorType>,
+                "Target type must be a subtype of source type");
+  return static_cast<MirrorType*>(ptr.Ptr());
+}
+
+template<class MirrorType>
+size_t HashObjPtr::operator()(const ObjPtr<MirrorType>& ptr) const {
+  return std::hash<MirrorType*>()(ptr.Ptr());
+}
+
+template<class MirrorType1, class MirrorType2>
+inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                        std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator==(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) {
+  return lhs.Ptr() == rhs.Ptr();
+}
+
+template<class MirrorType1, class MirrorType2>
+inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                        std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator==(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) {
+  return lhs == rhs.Ptr();
+}
+
+template<class MirrorType1, class MirrorType2>
+inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                        std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator==(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs) REQUIRES_SHARED(Locks::mutator_lock_) {
+  return lhs.Ptr() == rhs;
+}
+
+template<class MirrorType1, class MirrorType2>
+inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                        std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator!=(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) {
+  return !(lhs == rhs);
+}
+
+template<class MirrorType1, class MirrorType2>
+inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                        std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator!=(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs) REQUIRES_SHARED(Locks::mutator_lock_) {
+  return !(lhs == rhs);
+}
+
+template<class MirrorType1, class MirrorType2>
+inline std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                        std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator!=(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs) REQUIRES_SHARED(Locks::mutator_lock_) {
+  return !(lhs == rhs);
+}
+
+template<class MirrorType>
+static inline ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr) {
+  return ObjPtr<MirrorType>(ptr);
+}
+
+template<class MirrorType>
+static inline ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr) {
+  return ObjPtr<MirrorType>(ptr);
+}
+
+template<class MirrorType>
 inline std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType> ptr) {
   // May be used for dumping bad pointers, do not use the checked version.
   return os << ptr.PtrUnchecked();
diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h
index b0f24da..1f79d37 100644
--- a/runtime/obj_ptr.h
+++ b/runtime/obj_ptr.h
@@ -59,86 +59,34 @@
       : reference_(0u) {}
 
   template <typename Type,
-            typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
-  OBJPTR_INLINE ObjPtr(Type* ptr)
-      REQUIRES_SHARED(Locks::mutator_lock_)
-      : reference_(Encode(static_cast<MirrorType*>(ptr))) {
-  }
+            typename = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>>>
+  OBJPTR_INLINE ObjPtr(Type* ptr) REQUIRES_SHARED(Locks::mutator_lock_);
 
   template <typename Type,
-            typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
-  OBJPTR_INLINE ObjPtr(const ObjPtr<Type>& other)
-      REQUIRES_SHARED(Locks::mutator_lock_)
-      : reference_(kObjPtrPoisoningValidateOnCopy
-                       ? Encode(static_cast<MirrorType*>(other.Ptr()))
-                       : other.reference_) {
-  }
+            typename = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>>>
+  OBJPTR_INLINE ObjPtr(const ObjPtr<Type>& other) REQUIRES_SHARED(Locks::mutator_lock_);
 
   template <typename Type,
-            typename = typename std::enable_if<std::is_base_of<MirrorType, Type>::value>::type>
-  OBJPTR_INLINE ObjPtr& operator=(const ObjPtr<Type>& other)
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    reference_ = kObjPtrPoisoningValidateOnCopy
-                     ? Encode(static_cast<MirrorType*>(other.Ptr()))
-                     : other.reference_;
-    return *this;
-  }
+            typename = typename std::enable_if_t<std::is_base_of_v<MirrorType, Type>>>
+  OBJPTR_INLINE ObjPtr& operator=(const ObjPtr<Type>& other) REQUIRES_SHARED(Locks::mutator_lock_);
 
-  OBJPTR_INLINE ObjPtr& operator=(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_) {
-    Assign(ptr);
-    return *this;
-  }
+  OBJPTR_INLINE ObjPtr& operator=(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_);
 
-  OBJPTR_INLINE void Assign(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_) {
-    reference_ = Encode(ptr);
-  }
+  OBJPTR_INLINE void Assign(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_);
 
-  OBJPTR_INLINE MirrorType* operator->() const REQUIRES_SHARED(Locks::mutator_lock_) {
-    return Ptr();
-  }
+  OBJPTR_INLINE MirrorType* operator->() const REQUIRES_SHARED(Locks::mutator_lock_);
 
   OBJPTR_INLINE bool IsNull() const {
     return reference_ == 0;
   }
 
   // Ptr makes sure that the object pointer is valid.
-  OBJPTR_INLINE MirrorType* Ptr() const REQUIRES_SHARED(Locks::mutator_lock_) {
-    AssertValid();
-    return PtrUnchecked();
-  }
+  OBJPTR_INLINE MirrorType* Ptr() const REQUIRES_SHARED(Locks::mutator_lock_);
 
   OBJPTR_INLINE bool IsValid() const REQUIRES_SHARED(Locks::mutator_lock_);
 
   OBJPTR_INLINE void AssertValid() const REQUIRES_SHARED(Locks::mutator_lock_);
 
-  OBJPTR_INLINE bool operator==(const ObjPtr& ptr) const REQUIRES_SHARED(Locks::mutator_lock_) {
-    return Ptr() == ptr.Ptr();
-  }
-
-  template <typename PointerType>
-  OBJPTR_INLINE bool operator==(const PointerType* ptr) const
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    return Ptr() == ptr;
-  }
-
-  OBJPTR_INLINE bool operator==(std::nullptr_t) const {
-    return IsNull();
-  }
-
-  OBJPTR_INLINE bool operator!=(const ObjPtr& ptr) const REQUIRES_SHARED(Locks::mutator_lock_) {
-    return Ptr() != ptr.Ptr();
-  }
-
-  template <typename PointerType>
-  OBJPTR_INLINE bool operator!=(const PointerType* ptr) const
-      REQUIRES_SHARED(Locks::mutator_lock_) {
-    return Ptr() != ptr;
-  }
-
-  OBJPTR_INLINE bool operator!=(std::nullptr_t) const {
-    return !IsNull();
-  }
-
   // Ptr unchecked does not check that object pointer is valid. Do not use if you can avoid it.
   OBJPTR_INLINE MirrorType* PtrUnchecked() const {
     if (kObjPtrPoisoning) {
@@ -151,11 +99,7 @@
 
   // Static function to be friendly with null pointers.
   template <typename SourceType>
-  static ObjPtr<MirrorType> DownCast(ObjPtr<SourceType> ptr) REQUIRES_SHARED(Locks::mutator_lock_) {
-    static_assert(std::is_base_of<SourceType, MirrorType>::value,
-                  "Target type must be a subtype of source type");
-    return static_cast<MirrorType*>(ptr.Ptr());
-  }
+  static ObjPtr<MirrorType> DownCast(ObjPtr<SourceType> ptr) REQUIRES_SHARED(Locks::mutator_lock_);
 
  private:
   // Trim off high bits of thread local cookie.
@@ -179,42 +123,70 @@
 class HashObjPtr {
  public:
   template<class MirrorType>
-  size_t operator()(const ObjPtr<MirrorType>& ptr) const NO_THREAD_SAFETY_ANALYSIS {
-    return std::hash<MirrorType*>()(ptr.Ptr());
-  }
+  size_t operator()(const ObjPtr<MirrorType>& ptr) const NO_THREAD_SAFETY_ANALYSIS;
 };
 
-template<class MirrorType, typename PointerType>
-OBJPTR_INLINE bool operator==(const PointerType* a, const ObjPtr<MirrorType>& b)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return b == a;
+template<class MirrorType1, class MirrorType2>
+OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                               std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator==(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs)
+    REQUIRES_SHARED(Locks::mutator_lock_);
+
+template<class MirrorType1, class MirrorType2>
+OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                               std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator==(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs)
+    REQUIRES_SHARED(Locks::mutator_lock_);
+
+template<class MirrorType1, class MirrorType2>
+OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                               std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator==(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs)
+    REQUIRES_SHARED(Locks::mutator_lock_);
+
+template<class MirrorType>
+OBJPTR_INLINE bool operator==(ObjPtr<MirrorType> ptr, std::nullptr_t) {
+  return ptr.IsNull();
 }
 
 template<class MirrorType>
-OBJPTR_INLINE bool operator==(std::nullptr_t, const ObjPtr<MirrorType>& b) {
-  return b == nullptr;
+OBJPTR_INLINE bool operator==(std::nullptr_t, ObjPtr<MirrorType> ptr) {
+  return ptr.IsNull();
 }
 
-template<typename MirrorType, typename PointerType>
-OBJPTR_INLINE bool operator!=(const PointerType* a, const ObjPtr<MirrorType>& b)
-    REQUIRES_SHARED(Locks::mutator_lock_) {
-  return b != a;
+template<class MirrorType1, class MirrorType2>
+OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                               std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator!=(ObjPtr<MirrorType1> lhs, ObjPtr<MirrorType2> rhs)
+    REQUIRES_SHARED(Locks::mutator_lock_);
+
+template<class MirrorType1, class MirrorType2>
+OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                               std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator!=(const MirrorType1* lhs, ObjPtr<MirrorType2> rhs)
+    REQUIRES_SHARED(Locks::mutator_lock_);
+
+template<class MirrorType1, class MirrorType2>
+OBJPTR_INLINE std::enable_if_t<std::is_base_of_v<MirrorType1, MirrorType2> ||
+                               std::is_base_of_v<MirrorType2, MirrorType1>, bool>
+operator!=(ObjPtr<MirrorType1> lhs, const MirrorType2* rhs)
+    REQUIRES_SHARED(Locks::mutator_lock_);
+
+template<class MirrorType>
+OBJPTR_INLINE bool operator!=(ObjPtr<MirrorType> ptr, std::nullptr_t) {
+  return !(ptr == nullptr);
 }
 
 template<class MirrorType>
-OBJPTR_INLINE bool operator!=(std::nullptr_t, const ObjPtr<MirrorType>& b) {
-  return b != nullptr;
+OBJPTR_INLINE bool operator!=(std::nullptr_t, ObjPtr<MirrorType> ptr) {
+  return !(nullptr == ptr);
 }
 
 template<class MirrorType>
-static inline ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr) {
-  return ObjPtr<MirrorType>(ptr);
-}
+static OBJPTR_INLINE ObjPtr<MirrorType> MakeObjPtr(MirrorType* ptr);
 
 template<class MirrorType>
-static inline ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr) {
-  return ObjPtr<MirrorType>(ptr);
-}
+static OBJPTR_INLINE ObjPtr<MirrorType> MakeObjPtr(ObjPtr<MirrorType> ptr);
 
 template<class MirrorType>
 OBJPTR_INLINE std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType> ptr);