// 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_LIB_MAP_INTERNAL_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_INTERNAL_H_

#include <map>

#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"

namespace mojo {
namespace internal {

template <typename Key, typename Value, bool kValueIsMoveOnlyType>
struct MapTraits {};

// Defines traits of a map for which Value is not a move-only type.
template <typename Key, typename Value>
struct MapTraits<Key, Value, false> {
  // Map keys can't be move only types.
  static_assert(!internal::IsMoveOnlyType<Key>::value,
                "Map keys cannot be move only types.");

  typedef Key KeyStorageType;
  typedef Key& KeyRefType;
  typedef const Key& KeyConstRefType;
  typedef KeyConstRefType KeyForwardType;

  typedef Value ValueStorageType;
  typedef Value& ValueRefType;
  typedef const Value& ValueConstRefType;
  typedef ValueConstRefType ValueForwardType;

  static inline void InitializeFrom(
      std::map<KeyStorageType, ValueStorageType>* m,
      mojo::Array<Key> keys,
      mojo::Array<Value> values) {
    for (size_t i = 0; i < keys.size(); ++i)
      Insert(m, keys[i], values[i]);
  }
  static inline void Finalize(std::map<KeyStorageType, ValueStorageType>* m) {}
  static inline ValueRefType at(std::map<KeyStorageType, ValueStorageType>* m,
                                KeyForwardType key) {
    // We don't have C++11 library support yet, so we have to emulate the crash
    // on a non-existent key.
    auto it = m->find(key);
    MOJO_CHECK(it != m->end());
    return it->second;
  }
  static inline ValueConstRefType at(
      const std::map<KeyStorageType, ValueStorageType>* m,
      KeyForwardType key) {
    // We don't have C++11 library support yet, so we have to emulate the crash
    // on a non-existent key.
    auto it = m->find(key);
    MOJO_CHECK(it != m->end());
    return it->second;
  }
  static inline ValueRefType GetOrInsert(
      std::map<KeyStorageType, ValueStorageType>* m,
      KeyForwardType key) {
    // This is the backing for the index operator (operator[]).
    return (*m)[key];
  }
  static inline void Insert(std::map<KeyStorageType, ValueStorageType>* m,
                            KeyForwardType key,
                            ValueForwardType value) {
    m->insert(std::make_pair(key, value));
  }
  static inline KeyConstRefType GetKey(
      const typename std::map<KeyStorageType, ValueStorageType>::const_iterator&
          it) {
    return it->first;
  }
  static inline ValueConstRefType GetValue(
      const typename std::map<KeyStorageType, ValueStorageType>::const_iterator&
          it) {
    return it->second;
  }
  static inline ValueRefType GetValue(
      const typename std::map<KeyStorageType, ValueStorageType>::iterator& it) {
    return it->second;
  }
  static inline void Clone(
      const std::map<KeyStorageType, ValueStorageType>& src,
      std::map<KeyStorageType, ValueStorageType>* dst) {
    dst->clear();
    for (auto it = src.begin(); it != src.end(); ++it)
      dst->insert(*it);
  }
};

// Defines traits of a map for which Value is a move-only type.
template <typename Key, typename Value>
struct MapTraits<Key, Value, true> {
  // Map keys can't be move only types.
  static_assert(!internal::IsMoveOnlyType<Key>::value,
                "Map keys cannot be move only types.");

  typedef Key KeyStorageType;
  typedef Key& KeyRefType;
  typedef const Key& KeyConstRefType;
  typedef KeyConstRefType KeyForwardType;

  struct ValueStorageType {
    // Make 8-byte aligned.
    char buf[sizeof(Value) + (8 - (sizeof(Value) % 8)) % 8];
  };
  typedef Value& ValueRefType;
  typedef const Value& ValueConstRefType;
  typedef Value ValueForwardType;

  static inline void InitializeFrom(
      std::map<KeyStorageType, ValueStorageType>* m,
      mojo::Array<Key> keys,
      mojo::Array<Value> values) {
    for (size_t i = 0; i < keys.size(); ++i)
      Insert(m, keys[i], values[i]);
  }
  static inline void Finalize(std::map<KeyStorageType, ValueStorageType>* m) {
    for (auto& pair : *m)
      reinterpret_cast<Value*>(pair.second.buf)->~Value();
  }
  static inline ValueRefType at(std::map<KeyStorageType, ValueStorageType>* m,
                                KeyForwardType key) {
    // We don't have C++11 library support yet, so we have to emulate the crash
    // on a non-existent key.
    auto it = m->find(key);
    MOJO_CHECK(it != m->end());
    return GetValue(it);
  }
  static inline ValueConstRefType at(
      const std::map<KeyStorageType, ValueStorageType>* m,
      KeyForwardType key) {
    // We don't have C++11 library support yet, so we have to emulate the crash
    // on a non-existent key.
    auto it = m->find(key);
    MOJO_CHECK(it != m->end());
    return GetValue(it);
  }
  static inline ValueRefType GetOrInsert(
      std::map<KeyStorageType, ValueStorageType>* m,
      KeyForwardType key) {
    // This is the backing for the index operator (operator[]).
    auto it = m->find(key);
    if (it == m->end()) {
      it = m->insert(std::make_pair(key, ValueStorageType())).first;
      new (it->second.buf) Value();
    }

    return GetValue(it);
  }
  static inline void Insert(std::map<KeyStorageType, ValueStorageType>* m,
                            KeyForwardType key,
                            ValueRefType value) {
    // STL insert() doesn't insert |value| if |key| is already part of |m|. We
    // have to use operator[] to initialize into the storage buffer, but we
    // have to do a manual check so that we don't overwrite an existing object.
    auto it = m->find(key);
    if (it == m->end())
      new ((*m)[key].buf) Value(value.Pass());
  }
  static inline KeyConstRefType GetKey(
      const typename std::map<KeyStorageType, ValueStorageType>::const_iterator&
          it) {
    return it->first;
  }
  static inline ValueConstRefType GetValue(
      const typename std::map<KeyStorageType, ValueStorageType>::const_iterator&
          it) {
    return *reinterpret_cast<const Value*>(it->second.buf);
  }
  static inline ValueRefType GetValue(
      const typename std::map<KeyStorageType, ValueStorageType>::iterator& it) {
    return *reinterpret_cast<Value*>(it->second.buf);
  }
  static inline void Clone(
      const std::map<KeyStorageType, ValueStorageType>& src,
      std::map<KeyStorageType, ValueStorageType>* dst) {
    Finalize(dst);
    dst->clear();
    for (auto it = src.begin(); it != src.end(); ++it)
      new ((*dst)[it->first].buf) Value(GetValue(it).Clone());
  }
};

}  // namespace internal
}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_INTERNAL_H_
