// 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_; }

 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_
