// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 COBALT_BASE_TYPE_ID_H_
#define COBALT_BASE_TYPE_ID_H_

#include "base/hash_tables.h"

// This file introduces the template function GetTypeId<T>() as well as the
// class TypeId.  GetTypeId<T>() will return a TypeId object that is unique
// to the type T passed as the template parameter.  This can be used to
// implement run-time type identification on certain types without actually
// enabling RTTI on the compiler.

// Some of this code is copied from gtest-internal.h.

namespace base {

namespace internal {

template <typename T>
class TypeIdHelper {
 public:
  // dummy_ must not have a const type.  Otherwise an overly eager
  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
  // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
  static bool dummy_;
};

// The compiler is required to allocate a different
// TypeIdHelper<T>::dummy_ variable for each T used to instantiate
// the template.  Therefore, the address of dummy_ is guaranteed to
// be unique.
template <typename T>
bool TypeIdHelper<T>::dummy_ = false;

}  // namespace internal

class TypeId {
 public:
  bool operator==(const TypeId& other) const { return value_ == other.value_; }
  bool operator!=(const TypeId& other) const { return !(*this == other); }
  bool operator<(const TypeId& other) const { return value_ < other.value_; }
  bool operator<=(const TypeId& other) const { return value_ <= other.value_; }
  bool operator>(const TypeId& other) const { return value_ > other.value_; }
  bool operator>=(const TypeId& other) const { return value_ >= other.value_; }

 private:
  explicit TypeId(intptr_t value) : value_(value) {}
  intptr_t value_;
  template <typename T> friend TypeId GetTypeId();
#if defined(BASE_HASH_USE_HASH_STRUCT)
  friend struct BASE_HASH_NAMESPACE::hash<TypeId>;
#else
  template <typename T, typename Predicate>
  friend class BASE_HASH_NAMESPACE::hash_compare;
#endif
};

// GetTypeId<T>() returns the ID of type T.  Different values will be
// returned for different types.  Calling the function twice with the
// same type argument is guaranteed to return the same ID.
template <typename T>
TypeId GetTypeId() {
  return
      TypeId(reinterpret_cast<intptr_t>(&(internal::TypeIdHelper<T>::dummy_)));
}

}  // namespace base

// Make TypeId usable as key in base::hash_map.

namespace BASE_HASH_NAMESPACE {

//
// GCC-flavored hash functor.
//
#if defined(BASE_HASH_USE_HASH_STRUCT)

// Forward declaration in case <hash_fun.h> is not #include'd.
template <typename Key>
struct hash;

template <>
struct hash<base::TypeId> {
  size_t operator()(const base::TypeId& key) const {
    return base_hash(key.value_);
  }

  hash<intptr_t> base_hash;
};

//
// Dinkumware-flavored hash functor.
//
#else

// Forward declaration in case <xhash> is not #include'd.
template <typename Key, typename Predicate>
class hash_compare;

template <typename Predicate>
class hash_compare<base::TypeId, Predicate> {
 public:
  typedef hash_compare<intptr_t> BaseHashCompare;

  enum {
    bucket_size = BaseHashCompare::bucket_size,
#if !defined(COMPILER_MSVC)
    min_buckets = BaseHashCompare::min_buckets,
#endif
  };

  hash_compare() {}

  size_t operator()(const base::TypeId& key) const {
    return base_hash_compare_(key.value_);
  }

  bool operator()(const base::TypeId& lhs,
                  const base::TypeId& rhs) const {
    return base_hash_compare_(lhs.value_, rhs.value_);
  }

 private:
  BaseHashCompare base_hash_compare_;
};

#endif
}  // namespace BASE_HASH_NAMESPACE

#endif  // COBALT_BASE_TYPE_ID_H_
