<commit_before>// Copyright (c) 2011 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.

#include "ppapi/cpp/var.h"

#include <stdio.h>
#include <string.h>

#include <algorithm>

#include "ppapi/c/pp_var.h"
#ifndef PPAPI_VAR_REMOVE_SCRIPTING
#  include "ppapi/c/dev/ppb_var_deprecated.h"
#endif
#include "ppapi/c/ppb_var.h"
#include "ppapi/cpp/common.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/dev/scriptable_object_deprecated.h"

// Define equivalent to snprintf on Windows.
#if defined(_MSC_VER)
#  define snprintf sprintf_s
#endif

namespace pp {

namespace {

template <> const char* interface_name<PPB_Var>() {
  return PPB_VAR_INTERFACE;
}

#ifdef PPAPI_VAR_REMOVE_SCRIPTING
typedef PPB_Var PPB_Var_Interface_Type;
#else
typedef PPB_Var_Deprecated PPB_Var_Interface_Type;

template <> const char* interface_name<PPB_Var_Deprecated>() {
  return PPB_VAR_DEPRECATED_INTERFACE;
}
#endif

// Technically you can call AddRef and Release on any Var, but it may involve
// cross-process calls depending on the plugin. This is an optimization so we
// only do refcounting on the necessary objects.
inline bool NeedsRefcounting(const PP_Var& var) {
  return var.type > PP_VARTYPE_DOUBLE;
}

}  // namespace

using namespace deprecated;

Var::Var() {
  var_.type = PP_VARTYPE_UNDEFINED;
  var_.padding = 0;
  needs_release_ = false;
}

Var::Var(Null) {
  var_.type = PP_VARTYPE_NULL;
  var_.padding = 0;
  needs_release_ = false;
}

Var::Var(bool b) {
  var_.type = PP_VARTYPE_BOOL;
  var_.padding = 0;
  var_.value.as_bool = BoolToPPBool(b);
  needs_release_ = false;
}

Var::Var(int32_t i) {
  var_.type = PP_VARTYPE_INT32;
  var_.padding = 0;
  var_.value.as_int = i;
  needs_release_ = false;
}

Var::Var(double d) {
  var_.type = PP_VARTYPE_DOUBLE;
  var_.padding = 0;
  var_.value.as_double = d;
  needs_release_ = false;
}

Var::Var(const char* utf8_str) {
  if (has_interface<PPB_Var_Interface_Type>()) {
    uint32_t len = utf8_str ? static_cast<uint32_t>(strlen(utf8_str)) : 0;
    var_ = get_interface<PPB_Var_Interface_Type>()->VarFromUtf8(
        Module::Get()->pp_module(), utf8_str, len);
  } else {
    var_.type = PP_VARTYPE_NULL;
    var_.padding = 0;
  }
  needs_release_ = (var_.type == PP_VARTYPE_STRING);
}

Var::Var(const std::string& utf8_str) {
  if (has_interface<PPB_Var_Interface_Type>()) {
    var_ = get_interface<PPB_Var_Interface_Type>()->VarFromUtf8(
        Module::Get()->pp_module(),
        utf8_str.c_str(),
        static_cast<uint32_t>(utf8_str.size()));
  } else {
    var_.type = PP_VARTYPE_NULL;
    var_.padding = 0;
  }
  needs_release_ = (var_.type == PP_VARTYPE_STRING);
}

Var::Var(const Var& other) {
  var_ = other.var_;
  if (NeedsRefcounting(var_)) {
    if (has_interface<PPB_Var_Interface_Type>()) {
      needs_release_ = true;
      get_interface<PPB_Var_Interface_Type>()->AddRef(var_);
    } else {
      var_.type = PP_VARTYPE_NULL;
      needs_release_ = false;
    }
  } else {
    needs_release_ = false;
  }
}

Var::~Var() {
  if (needs_release_ && has_interface<PPB_Var_Interface_Type>())
    get_interface<PPB_Var_Interface_Type>()->Release(var_);
}

Var& Var::operator=(const Var& other) {
  if (needs_release_ && has_interface<PPB_Var_Interface_Type>())
    get_interface<PPB_Var_Interface_Type>()->Release(var_);
  var_ = other.var_;
  if (NeedsRefcounting(var_)) {
    if (has_interface<PPB_Var_Interface_Type>()) {
      needs_release_ = true;
      get_interface<PPB_Var_Interface_Type>()->AddRef(var_);
    } else {
      var_.type = PP_VARTYPE_NULL;
      needs_release_ = false;
    }
  } else {
    needs_release_ = false;
  }
  return *this;
}

bool Var::operator==(const Var& other) const {
  if (var_.type != other.var_.type)
    return false;
  switch (var_.type) {
    case PP_VARTYPE_UNDEFINED:
    case PP_VARTYPE_NULL:
      return true;
    case PP_VARTYPE_BOOL:
      return AsBool() == other.AsBool();
    case PP_VARTYPE_INT32:
      return AsInt() == other.AsInt();
    case PP_VARTYPE_DOUBLE:
      return AsDouble() == other.AsDouble();
    case PP_VARTYPE_STRING:
      if (var_.value.as_id == other.var_.value.as_id)
        return true;
      return AsString() == other.AsString();
    default:  // Objects, arrays, dictionaries.
      return var_.value.as_id == other.var_.value.as_id;
  }
}

bool Var::AsBool() const {
  if (!is_bool()) {
    PP_NOTREACHED();
    return false;
  }
  return PPBoolToBool(var_.value.as_bool);
}

int32_t Var::AsInt() const {
  if (is_int())
    return var_.value.as_int;
  if (is_double())
    return static_cast<int>(var_.value.as_double);
  PP_NOTREACHED();
  return 0;
}

double Var::AsDouble() const {
  if (is_double())
    return var_.value.as_double;
  if (is_int())
    return static_cast<double>(var_.value.as_int);
  PP_NOTREACHED();
  return 0.0;
}

std::string Var::AsString() const {
  if (!is_string()) {
    PP_NOTREACHED();
    return std::string();
  }

  if (!has_interface<PPB_Var_Interface_Type>())
    return std::string();
  uint32_t len;
  const char* str =
      get_interface<PPB_Var_Interface_Type>()->VarToUtf8(var_, &len);
  return std::string(str, len);
}

#ifndef PPAPI_VAR_REMOVE_SCRIPTING
Var::Var(Instance* instance, ScriptableObject* object) {
  if (has_interface<PPB_Var_Deprecated>()) {
    var_ = get_interface<PPB_Var_Deprecated>()->CreateObject(
        instance->pp_instance(), object->GetClass(), object);
    needs_release_ = true;
  } else {
    var_.type = PP_VARTYPE_NULL;
    var_.padding = 0;
    needs_release_ = false;
  }
}

ScriptableObject* Var::AsScriptableObject() const {
  if (!is_object()) {
    PP_NOTREACHED();
  } else if (has_interface<PPB_Var_Deprecated>()) {
    void* object = NULL;
    if (get_interface<PPB_Var_Deprecated>()->IsInstanceOf(
        var_, ScriptableObject::GetClass(), &object)) {
      return reinterpret_cast<ScriptableObject*>(object);
    }
  }
  return NULL;
}

bool Var::HasProperty(const Var& name, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return false;
  return get_interface<PPB_Var_Deprecated>()->HasProperty(
      var_, name.var_, OutException(exception).get());
}

bool Var::HasMethod(const Var& name, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return false;
  return get_interface<PPB_Var_Deprecated>()->HasMethod(
      var_, name.var_, OutException(exception).get());
}

Var Var::GetProperty(const Var& name, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->GetProperty(
      var_, name.var_, OutException(exception).get()));
}

void Var::GetAllPropertyNames(std::vector<Var>* properties,
                              Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return;
  PP_Var* props = NULL;
  uint32_t prop_count = 0;
  get_interface<PPB_Var_Deprecated>()->GetAllPropertyNames(
      var_, &prop_count, &props, OutException(exception).get());
  if (!prop_count)
    return;
  properties->resize(prop_count);
  for (uint32_t i = 0; i < prop_count; ++i) {
    Var temp(PassRef(), props[i]);
    (*properties)[i] = temp;
  }
  Module::Get()->core()->MemFree(props);
}

void Var::SetProperty(const Var& name, const Var& value, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return;
  get_interface<PPB_Var_Deprecated>()->SetProperty(
      var_, name.var_, value.var_, OutException(exception).get());
}

void Var::RemoveProperty(const Var& name, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return;
  get_interface<PPB_Var_Deprecated>()->RemoveProperty(
      var_, name.var_, OutException(exception).get());
}

Var Var::Call(const Var& method_name, uint32_t argc, Var* argv,
              Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  if (argc > 0) {
    std::vector<PP_Var> args;
    args.reserve(argc);
    for (size_t i = 0; i < argc; i++)
      args.push_back(argv[i].var_);
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
        var_, method_name.var_, argc, &args[0], OutException(exception).get()));
  } else {
    // Don't try to get the address of a vector if it's empty.
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
        var_, method_name.var_, 0, NULL, OutException(exception).get()));
  }
}

Var Var::Construct(uint32_t argc, Var* argv, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  if (argc > 0) {
    std::vector<PP_Var> args;
    args.reserve(argc);
    for (size_t i = 0; i < argc; i++)
      args.push_back(argv[i].var_);
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
        var_, argc, &args[0], OutException(exception).get()));
  } else {
    // Don't try to get the address of a vector if it's empty.
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
        var_, 0, NULL, OutException(exception).get()));
  }
}

Var Var::Call(const Var& method_name, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 0, NULL, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[1] = {arg1.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 1, args, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
              Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[2] = {arg1.var_, arg2.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 2, args, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
              const Var& arg3, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[3] = {arg1.var_, arg2.var_, arg3.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 3, args, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
              const Var& arg3, const Var& arg4, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[4] = {arg1.var_, arg2.var_, arg3.var_, arg4.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 4, args, OutException(exception).get()));
}
#endif

std::string Var::DebugString() const {
  char buf[256];
  if (is_undefined()) {
    snprintf(buf, sizeof(buf), "Var<UNDEFINED>");
  } else if (is_null()) {
    snprintf(buf, sizeof(buf), "Var<NULL>");
  } else if (is_bool()) {
    snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>");
  } else if (is_int()) {
    // Note that the following static_cast is necessary because
    // NativeClient's int32_t is actually "long".
    // TODO(sehr,polina): remove this after newlib is changed.
    snprintf(buf, sizeof(buf), "Var<%d>", static_cast<int>(AsInt()));
  } else if (is_double()) {
    snprintf(buf, sizeof(buf), "Var<%f>", AsDouble());
  } else if (is_string()) {
    char format[] = "Var<'%s'>";
    size_t decoration = sizeof(format) - 2;  // The %s is removed.
    size_t available = sizeof(buf) - decoration;
    std::string str = AsString();
    if (str.length() > available) {
      str.resize(available - 3);  // Reserve space for ellipsis.
      str.append("...");
    }
    snprintf(buf, sizeof(buf), format, str.c_str());
  } else if (is_object()) {
    snprintf(buf, sizeof(buf), "Var<OBJECT>");
  }
  return buf;
}

}  // namespace pp
<commit_msg>This guarantees that the underlying PP_Var is all initialized.  There was a red test bot in NaCl (lucid-newlib-64-dbg); the problem was caused by garbage values (non-0) in pp:Var being usedto index into the proxy var cache.<commit_after>// Copyright (c) 2011 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.

#include "ppapi/cpp/var.h"

#include <stdio.h>
#include <string.h>

#include <algorithm>

#include "ppapi/c/pp_var.h"
#ifndef PPAPI_VAR_REMOVE_SCRIPTING
#  include "ppapi/c/dev/ppb_var_deprecated.h"
#endif
#include "ppapi/c/ppb_var.h"
#include "ppapi/cpp/common.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/logging.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/module_impl.h"
#include "ppapi/cpp/dev/scriptable_object_deprecated.h"

// Define equivalent to snprintf on Windows.
#if defined(_MSC_VER)
#  define snprintf sprintf_s
#endif

namespace pp {

namespace {

template <> const char* interface_name<PPB_Var>() {
  return PPB_VAR_INTERFACE;
}

#ifdef PPAPI_VAR_REMOVE_SCRIPTING
typedef PPB_Var PPB_Var_Interface_Type;
#else
typedef PPB_Var_Deprecated PPB_Var_Interface_Type;

template <> const char* interface_name<PPB_Var_Deprecated>() {
  return PPB_VAR_DEPRECATED_INTERFACE;
}
#endif

// Technically you can call AddRef and Release on any Var, but it may involve
// cross-process calls depending on the plugin. This is an optimization so we
// only do refcounting on the necessary objects.
inline bool NeedsRefcounting(const PP_Var& var) {
  return var.type > PP_VARTYPE_DOUBLE;
}

}  // namespace

using namespace deprecated;

Var::Var() {
  memset(&var_, 0, sizeof(var_));
  var_.type = PP_VARTYPE_UNDEFINED;
  needs_release_ = false;
}

Var::Var(Null) {
  memset(&var_, 0, sizeof(var_));
  var_.type = PP_VARTYPE_NULL;
  needs_release_ = false;
}

Var::Var(bool b) {
  var_.type = PP_VARTYPE_BOOL;
  var_.padding = 0;
  var_.value.as_bool = BoolToPPBool(b);
  needs_release_ = false;
}

Var::Var(int32_t i) {
  var_.type = PP_VARTYPE_INT32;
  var_.padding = 0;
  var_.value.as_int = i;
  needs_release_ = false;
}

Var::Var(double d) {
  var_.type = PP_VARTYPE_DOUBLE;
  var_.padding = 0;
  var_.value.as_double = d;
  needs_release_ = false;
}

Var::Var(const char* utf8_str) {
  if (has_interface<PPB_Var_Interface_Type>()) {
    uint32_t len = utf8_str ? static_cast<uint32_t>(strlen(utf8_str)) : 0;
    var_ = get_interface<PPB_Var_Interface_Type>()->VarFromUtf8(
        Module::Get()->pp_module(), utf8_str, len);
  } else {
    var_.type = PP_VARTYPE_NULL;
    var_.padding = 0;
  }
  needs_release_ = (var_.type == PP_VARTYPE_STRING);
}

Var::Var(const std::string& utf8_str) {
  if (has_interface<PPB_Var_Interface_Type>()) {
    var_ = get_interface<PPB_Var_Interface_Type>()->VarFromUtf8(
        Module::Get()->pp_module(),
        utf8_str.c_str(),
        static_cast<uint32_t>(utf8_str.size()));
  } else {
    var_.type = PP_VARTYPE_NULL;
    var_.padding = 0;
  }
  needs_release_ = (var_.type == PP_VARTYPE_STRING);
}

Var::Var(const Var& other) {
  var_ = other.var_;
  if (NeedsRefcounting(var_)) {
    if (has_interface<PPB_Var_Interface_Type>()) {
      needs_release_ = true;
      get_interface<PPB_Var_Interface_Type>()->AddRef(var_);
    } else {
      var_.type = PP_VARTYPE_NULL;
      needs_release_ = false;
    }
  } else {
    needs_release_ = false;
  }
}

Var::~Var() {
  if (needs_release_ && has_interface<PPB_Var_Interface_Type>())
    get_interface<PPB_Var_Interface_Type>()->Release(var_);
}

Var& Var::operator=(const Var& other) {
  if (needs_release_ && has_interface<PPB_Var_Interface_Type>())
    get_interface<PPB_Var_Interface_Type>()->Release(var_);
  var_ = other.var_;
  if (NeedsRefcounting(var_)) {
    if (has_interface<PPB_Var_Interface_Type>()) {
      needs_release_ = true;
      get_interface<PPB_Var_Interface_Type>()->AddRef(var_);
    } else {
      var_.type = PP_VARTYPE_NULL;
      needs_release_ = false;
    }
  } else {
    needs_release_ = false;
  }
  return *this;
}

bool Var::operator==(const Var& other) const {
  if (var_.type != other.var_.type)
    return false;
  switch (var_.type) {
    case PP_VARTYPE_UNDEFINED:
    case PP_VARTYPE_NULL:
      return true;
    case PP_VARTYPE_BOOL:
      return AsBool() == other.AsBool();
    case PP_VARTYPE_INT32:
      return AsInt() == other.AsInt();
    case PP_VARTYPE_DOUBLE:
      return AsDouble() == other.AsDouble();
    case PP_VARTYPE_STRING:
      if (var_.value.as_id == other.var_.value.as_id)
        return true;
      return AsString() == other.AsString();
    default:  // Objects, arrays, dictionaries.
      return var_.value.as_id == other.var_.value.as_id;
  }
}

bool Var::AsBool() const {
  if (!is_bool()) {
    PP_NOTREACHED();
    return false;
  }
  return PPBoolToBool(var_.value.as_bool);
}

int32_t Var::AsInt() const {
  if (is_int())
    return var_.value.as_int;
  if (is_double())
    return static_cast<int>(var_.value.as_double);
  PP_NOTREACHED();
  return 0;
}

double Var::AsDouble() const {
  if (is_double())
    return var_.value.as_double;
  if (is_int())
    return static_cast<double>(var_.value.as_int);
  PP_NOTREACHED();
  return 0.0;
}

std::string Var::AsString() const {
  if (!is_string()) {
    PP_NOTREACHED();
    return std::string();
  }

  if (!has_interface<PPB_Var_Interface_Type>())
    return std::string();
  uint32_t len;
  const char* str =
      get_interface<PPB_Var_Interface_Type>()->VarToUtf8(var_, &len);
  return std::string(str, len);
}

#ifndef PPAPI_VAR_REMOVE_SCRIPTING
Var::Var(Instance* instance, ScriptableObject* object) {
  if (has_interface<PPB_Var_Deprecated>()) {
    var_ = get_interface<PPB_Var_Deprecated>()->CreateObject(
        instance->pp_instance(), object->GetClass(), object);
    needs_release_ = true;
  } else {
    var_.type = PP_VARTYPE_NULL;
    var_.padding = 0;
    needs_release_ = false;
  }
}

ScriptableObject* Var::AsScriptableObject() const {
  if (!is_object()) {
    PP_NOTREACHED();
  } else if (has_interface<PPB_Var_Deprecated>()) {
    void* object = NULL;
    if (get_interface<PPB_Var_Deprecated>()->IsInstanceOf(
        var_, ScriptableObject::GetClass(), &object)) {
      return reinterpret_cast<ScriptableObject*>(object);
    }
  }
  return NULL;
}

bool Var::HasProperty(const Var& name, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return false;
  return get_interface<PPB_Var_Deprecated>()->HasProperty(
      var_, name.var_, OutException(exception).get());
}

bool Var::HasMethod(const Var& name, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return false;
  return get_interface<PPB_Var_Deprecated>()->HasMethod(
      var_, name.var_, OutException(exception).get());
}

Var Var::GetProperty(const Var& name, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->GetProperty(
      var_, name.var_, OutException(exception).get()));
}

void Var::GetAllPropertyNames(std::vector<Var>* properties,
                              Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return;
  PP_Var* props = NULL;
  uint32_t prop_count = 0;
  get_interface<PPB_Var_Deprecated>()->GetAllPropertyNames(
      var_, &prop_count, &props, OutException(exception).get());
  if (!prop_count)
    return;
  properties->resize(prop_count);
  for (uint32_t i = 0; i < prop_count; ++i) {
    Var temp(PassRef(), props[i]);
    (*properties)[i] = temp;
  }
  Module::Get()->core()->MemFree(props);
}

void Var::SetProperty(const Var& name, const Var& value, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return;
  get_interface<PPB_Var_Deprecated>()->SetProperty(
      var_, name.var_, value.var_, OutException(exception).get());
}

void Var::RemoveProperty(const Var& name, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return;
  get_interface<PPB_Var_Deprecated>()->RemoveProperty(
      var_, name.var_, OutException(exception).get());
}

Var Var::Call(const Var& method_name, uint32_t argc, Var* argv,
              Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  if (argc > 0) {
    std::vector<PP_Var> args;
    args.reserve(argc);
    for (size_t i = 0; i < argc; i++)
      args.push_back(argv[i].var_);
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
        var_, method_name.var_, argc, &args[0], OutException(exception).get()));
  } else {
    // Don't try to get the address of a vector if it's empty.
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
        var_, method_name.var_, 0, NULL, OutException(exception).get()));
  }
}

Var Var::Construct(uint32_t argc, Var* argv, Var* exception) const {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  if (argc > 0) {
    std::vector<PP_Var> args;
    args.reserve(argc);
    for (size_t i = 0; i < argc; i++)
      args.push_back(argv[i].var_);
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
        var_, argc, &args[0], OutException(exception).get()));
  } else {
    // Don't try to get the address of a vector if it's empty.
    return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct(
        var_, 0, NULL, OutException(exception).get()));
  }
}

Var Var::Call(const Var& method_name, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 0, NULL, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[1] = {arg1.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 1, args, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
              Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[2] = {arg1.var_, arg2.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 2, args, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
              const Var& arg3, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[3] = {arg1.var_, arg2.var_, arg3.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 3, args, OutException(exception).get()));
}

Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
              const Var& arg3, const Var& arg4, Var* exception) {
  if (!has_interface<PPB_Var_Deprecated>())
    return Var();
  PP_Var args[4] = {arg1.var_, arg2.var_, arg3.var_, arg4.var_};
  return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call(
      var_, method_name.var_, 4, args, OutException(exception).get()));
}
#endif

std::string Var::DebugString() const {
  char buf[256];
  if (is_undefined()) {
    snprintf(buf, sizeof(buf), "Var<UNDEFINED>");
  } else if (is_null()) {
    snprintf(buf, sizeof(buf), "Var<NULL>");
  } else if (is_bool()) {
    snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>");
  } else if (is_int()) {
    // Note that the following static_cast is necessary because
    // NativeClient's int32_t is actually "long".
    // TODO(sehr,polina): remove this after newlib is changed.
    snprintf(buf, sizeof(buf), "Var<%d>", static_cast<int>(AsInt()));
  } else if (is_double()) {
    snprintf(buf, sizeof(buf), "Var<%f>", AsDouble());
  } else if (is_string()) {
    char format[] = "Var<'%s'>";
    size_t decoration = sizeof(format) - 2;  // The %s is removed.
    size_t available = sizeof(buf) - decoration;
    std::string str = AsString();
    if (str.length() > available) {
      str.resize(available - 3);  // Reserve space for ellipsis.
      str.append("...");
    }
    snprintf(buf, sizeof(buf), format, str.c_str());
  } else if (is_object()) {
    snprintf(buf, sizeof(buf), "Var<OBJECT>");
  }
  return buf;
}

}  // namespace pp
<|endoftext|>


<commit_before>#ifndef LTL_FUTURE_HPP
#define LTL_FUTURE_HPP

#include <type_traits>
#include <mutex>
#include <memory>

#include "ltl/detail/future_state.hpp"
#include "ltl/detail/result_of.hpp"
#include "ltl/detail/private.hpp"
#include "ltl/traits.hpp"

namespace ltl {

template <typename T>
class future
{
public:
    typedef detail::future_state<T> state;
    typedef T value_type;

    future()
    : state_()
    {
    }

    future(future&& other)
    : state_(std::move(other.state_))
    {
    }

    future(future const& other) = delete;

    future& operator=(future&& other)
    {
        future f(other);
        state_.swap(f.state_);
        return *this;
    }

    future& operator=(future const& other) = delete;

    bool valid() const
    {
        return state_ != nullptr;
    }

    template <typename Function>
    future<typename result_of<Function, T>::type> then(Function&& func)
    {
        typedef future<typename result_of<Function, T>::type> result_future;
        return valid() ? state_->template then<result_future>(std::forward<Function>(func)) : result_future();
    }

    void swap(future& other)
    {
        state_swap(other.state_);
    }

    bool ready()
    {
        return state_ ? state_->poll() != nullptr : false;
    }

    void wait()
    {
        if (!valid())
            return;

        return state_->wait();
    }

    T get()
    {
        wait();
        return *state_->poll();
    }

    typename std::conditional<is_future<T>::value, T, future<T>>::type unwrap();

private:
    std::shared_ptr<state> state_;

public:
    std::shared_ptr<state> const& get_state(detail::private_interface) const
    {
        return state_;
    }

    explicit future(detail::private_interface, detail::promised)
    : state_(std::make_shared<state>())
    {
    }

    explicit future(detail::private_interface, std::shared_ptr<detail::task_queue_impl> const& tq)
    : state_(std::make_shared<state>(tq))
    {
    }

    explicit future(detail::private_interface, std::shared_ptr<state> const& s)
    : state_(s)
    {
    }
};

template <typename T>
void swap(future<T>& x, future<T>& y)
{
    x.swap(y);
}

namespace detail {

struct unwrap
{
    template <typename T>
    future<T> operator()(future<T>&& other) const
    {
        return std::move(other);
    }

    template <typename T>
    future<T> operator()(future<future<T>>&& other) const
    {
        if (!other.valid())
            return future<T>();

        future<T> f(detail::use_private_interface, other.get_state(detail::use_private_interface)->await_queue);
        auto s = f.get_state(detail::use_private_interface);

        other.get_state(detail::use_private_interface)->continue_with([=](future<T> const& x){
            x.get_state(detail::use_private_interface)->continue_with([=](T const& x) {
                s->set_value(x);
            });
        });
        return std::move(f);
    }

    inline future<void> operator()(future<future<void>>&& other) const
    {
        if (!other.valid())
            return future<void>();

        future<void> f(detail::use_private_interface, other.get_state(detail::use_private_interface)->await_queue);
        auto s = f.get_state(detail::use_private_interface);
        other.get_state(detail::use_private_interface)->continue_with([=](future<void> const& x){
            x.get_state(detail::use_private_interface)->continue_with([=]() {
                s->set_value();
            });
        });
        return std::move(f);
    }
};

} // namespace detail

template <typename T>
inline typename std::conditional<is_future<T>::value, T, future<T>>::type future<T>::unwrap()
{
    return detail::unwrap()(future<T>(detail::use_private_interface, state_));
}

} // namespace ltl

#endif // LTL_FUTURE_HPP
<commit_msg>Removed explicit qualifiers<commit_after>#ifndef LTL_FUTURE_HPP
#define LTL_FUTURE_HPP

#include <type_traits>
#include <mutex>
#include <memory>

#include "ltl/detail/future_state.hpp"
#include "ltl/detail/result_of.hpp"
#include "ltl/detail/private.hpp"
#include "ltl/traits.hpp"

namespace ltl {

template <typename T>
class future
{
public:
    typedef detail::future_state<T> state;
    typedef T value_type;

    future()
    : state_()
    {
    }

    future(future&& other)
    : state_(std::move(other.state_))
    {
    }

    future(future const& other) = delete;

    future& operator=(future&& other)
    {
        future f(other);
        state_.swap(f.state_);
        return *this;
    }

    future& operator=(future const& other) = delete;

    bool valid() const
    {
        return state_ != nullptr;
    }

    template <typename Function>
    future<typename result_of<Function, T>::type> then(Function&& func)
    {
        typedef future<typename result_of<Function, T>::type> result_future;
        return valid() ? state_->template then<result_future>(std::forward<Function>(func)) : result_future();
    }

    void swap(future& other)
    {
        state_swap(other.state_);
    }

    bool ready()
    {
        return state_ ? state_->poll() != nullptr : false;
    }

    void wait()
    {
        if (!valid())
            return;

        return state_->wait();
    }

    T get()
    {
        wait();
        return *state_->poll();
    }

    typename std::conditional<is_future<T>::value, T, future<T>>::type unwrap();

private:
    std::shared_ptr<state> state_;

public:
    std::shared_ptr<state> const& get_state(detail::private_interface) const
    {
        return state_;
    }

    future(detail::private_interface, detail::promised)
    : state_(std::make_shared<state>())
    {
    }

    future(detail::private_interface, std::shared_ptr<detail::task_queue_impl> const& tq)
    : state_(std::make_shared<state>(tq))
    {
    }

    future(detail::private_interface, std::shared_ptr<state> const& s)
    : state_(s)
    {
    }
};

template <typename T>
void swap(future<T>& x, future<T>& y)
{
    x.swap(y);
}

namespace detail {

struct unwrap
{
    template <typename T>
    future<T> operator()(future<T>&& other) const
    {
        return std::move(other);
    }

    template <typename T>
    future<T> operator()(future<future<T>>&& other) const
    {
        if (!other.valid())
            return future<T>();

        future<T> f(detail::use_private_interface, other.get_state(detail::use_private_interface)->await_queue);
        auto s = f.get_state(detail::use_private_interface);

        other.get_state(detail::use_private_interface)->continue_with([=](future<T> const& x){
            x.get_state(detail::use_private_interface)->continue_with([=](T const& x) {
                s->set_value(x);
            });
        });
        return std::move(f);
    }

    inline future<void> operator()(future<future<void>>&& other) const
    {
        if (!other.valid())
            return future<void>();

        future<void> f(detail::use_private_interface, other.get_state(detail::use_private_interface)->await_queue);
        auto s = f.get_state(detail::use_private_interface);
        other.get_state(detail::use_private_interface)->continue_with([=](future<void> const& x){
            x.get_state(detail::use_private_interface)->continue_with([=]() {
                s->set_value();
            });
        });
        return std::move(f);
    }
};

} // namespace detail

template <typename T>
inline typename std::conditional<is_future<T>::value, T, future<T>>::type future<T>::unwrap()
{
    return detail::unwrap()(future<T>(detail::use_private_interface, state_));
}

} // namespace ltl

#endif // LTL_FUTURE_HPP
<|endoftext|>


<commit_before><commit_msg>Fix a bug in pp:Var (var.cc) where DebugString could throw an exception on Windows; replace _snprintf_s, which doesn't have the same signature as snprintf, with sprintf_s, which has the same function signature. Check length of string vars and truncate values (adding ellipsis at end) if the won't fit in our fixed size buffer. TEST=manual BUG=none (found during testing in Chrome) Review URL: http://codereview.chromium.org/5559009<commit_after><|endoftext|>


<commit_before>
#ifndef DUNE_STUFF_GRID_BOUNDARYINFO_HH
#define DUNE_STUFF_GRID_BOUNDARYINFO_HH

// system
#include <map>
#include <set>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune {

namespace Stuff {

namespace Grid {

namespace BoundaryInfo {

class AllDirichlet
{
public:
  template< class IntersectionType >
  bool dirichlet(const IntersectionType& intersection) const
  {
    return true;
  }
}; // class AllDirichlet

class IdBased
{
public:
  typedef int IdType;

  typedef std::set< IdType > IdSetType;

  typedef std::map< std::string, IdSetType > IdSetMapType;

  IdBased(const Dune::shared_ptr< const IdSetMapType > boundaryInfoMap)
    : boundaryInfoMap_(boundaryInfoMap)
    , hasDirichlet_(boundaryInfoMap_->find("dirichlet") != boundaryInfoMap_->end())
  {}

  template< class IntersectionType >
  bool dirichlet(const IntersectionType& intersection) const
  {
    if (hasDirichlet_ && intersection.boundary()) {
      // get boundary id
      const IdType boundaryId = intersection.boundaryId();
      // get set of dirichlet ids (has to be found, otherwise hasDirichlet_ would be false)
      const typename IdSetMapType::const_iterator result = boundaryInfoMap_->find("dirichlet");
      assert(result != boundaryInfoMap_->end());
      const IdSetType& idSet = result->second;
      return (idSet.count(boundaryId) > 0);
    } else
      return false;
  } // bool dirichlet(const IntersectionType& intersection) const

private:
  const Dune::shared_ptr< const IdSetMapType > boundaryInfoMap_;
  const bool hasDirichlet_;
}; // class IdBased

} // namespace BoundaryInfo

} // namespace Grid

} // namespace Stuff

} // namespace Dune

#endif // DUNE_STUFF_GRID_BOUNDARYINFO_HH
<commit_msg>[grid.boundaryinfo.alldirichlet] major fix<commit_after>
#ifndef DUNE_STUFF_GRID_BOUNDARYINFO_HH
#define DUNE_STUFF_GRID_BOUNDARYINFO_HH

// system
#include <map>
#include <set>

// dune-common
#include <dune/common/shared_ptr.hh>

namespace Dune {

namespace Stuff {

namespace Grid {

namespace BoundaryInfo {

class AllDirichlet
{
public:
  template< class IntersectionType >
  bool dirichlet(const IntersectionType& intersection) const
  {
    if (intersection.boundary())
      return true;
    else
      return false;
  }

  template< class IntersectionType >
  bool neumann(const IntersectionType& intersection) const
  {
    return false;
  }
}; // class AllDirichlet

class IdBased
{
public:
  typedef int IdType;

  typedef std::set< IdType > IdSetType;

  typedef std::map< std::string, IdSetType > IdSetMapType;

  IdBased(const Dune::shared_ptr< const IdSetMapType > boundaryInfoMap)
    : boundaryInfoMap_(boundaryInfoMap)
    , hasDirichlet_(boundaryInfoMap_->find("dirichlet") != boundaryInfoMap_->end())
  {}

  template< class IntersectionType >
  bool dirichlet(const IntersectionType& intersection) const
  {
    if (hasDirichlet_ && intersection.boundary()) {
      // get boundary id
      const IdType boundaryId = intersection.boundaryId();
      // get set of dirichlet ids (has to be found, otherwise hasDirichlet_ would be false)
      const typename IdSetMapType::const_iterator result = boundaryInfoMap_->find("dirichlet");
      assert(result != boundaryInfoMap_->end());
      const IdSetType& idSet = result->second;
      return (idSet.count(boundaryId) > 0);
    } else
      return false;
  } // bool dirichlet(const IntersectionType& intersection) const

private:
  const Dune::shared_ptr< const IdSetMapType > boundaryInfoMap_;
  const bool hasDirichlet_;
}; // class IdBased

} // namespace BoundaryInfo

} // namespace Grid

} // namespace Stuff

} // namespace Dune

#endif // DUNE_STUFF_GRID_BOUNDARYINFO_HH
<|endoftext|>


<commit_before>// Copyright (c) 2012 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.

#include "chrome/browser/chromeos/extensions/file_browser_notifications.h"

#include <gtest/gtest.h>
#include <string>

#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"

namespace chromeos {

class FileBrowserNotificationsTest : public InProcessBrowserTest {
 public:
  FileBrowserNotificationsTest() {}

  virtual void CleanUpOnMainThread() OVERRIDE {
    notifications_.reset();
  }

 protected:
  // This must be initialized late in test startup.
  void InitNotifications() {
    Profile* profile = browser()->profile();
    notifications_.reset(new FileBrowserNotifications(profile));
  }

  bool FindNotification(const std::string& id) {
    return notifications_->HasNotificationForTest(id);
  }

  scoped_ptr<FileBrowserNotifications> notifications_;
};

IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, TestBasic) {
  InitNotifications();
  // Showing a notification adds a new notification.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // Updating the same notification maintains the same count.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // A new notification increases the count.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_TRUE(FindNotification("Dpath"));

  // Hiding a notification removes it from our data.
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_FALSE(FindNotification("DFpath"));
  EXPECT_TRUE(FindNotification("Dpath"));
};

// Note: Delayed tests use a delay time of 0 so that tasks wille execute
// when RunAllPendingInMessageLoop() is called.
IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, ShowDelayedTest) {
  InitNotifications();
  // Adding a delayed notification does not create a notification.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());
  EXPECT_FALSE(FindNotification("Dpath"));

  // Running the message loop should create the notification.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // Showing a notification both immediately and delayed results in one
  // additional notification.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("DFpath"));

  // When the delayed notification is processed, it's an update, so we still
  // only have two notifications.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("DFpath"));

  // If we schedule a show for later, then hide before it becomes visible,
  // the notification should not be added.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::FORMAT_FAIL,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  notifications_->HideNotification(FileBrowserNotifications::FORMAT_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_FALSE(FindNotification("Fpath"));

  // Even after processing messages, no new notification should be added.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_FALSE(FindNotification("Fpath"));
}

IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, HideDelayedTest) {
  InitNotifications();
  // Showing now, and scheduling a hide for later, results in one notification.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // Running pending messges should remove the notification.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());

  // Immediate show then hide results in no notification.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());

  // Delayed hide for a notification that doesn't exist does nothing.
  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());
}

}  // namespace chromeos.
<commit_msg>Disable FileBrowserNotificationsTest.TestBasic<commit_after>// Copyright (c) 2012 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.

#include "chrome/browser/chromeos/extensions/file_browser_notifications.h"

#include <gtest/gtest.h>
#include <string>

#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"

namespace chromeos {

class FileBrowserNotificationsTest : public InProcessBrowserTest {
 public:
  FileBrowserNotificationsTest() {}

  virtual void CleanUpOnMainThread() OVERRIDE {
    notifications_.reset();
  }

 protected:
  // This must be initialized late in test startup.
  void InitNotifications() {
    Profile* profile = browser()->profile();
    notifications_.reset(new FileBrowserNotifications(profile));
  }

  bool FindNotification(const std::string& id) {
    return notifications_->HasNotificationForTest(id);
  }

  scoped_ptr<FileBrowserNotifications> notifications_;
};

// http://crbug.com/163175
IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, DISABLED_TestBasic) {
  InitNotifications();
  // Showing a notification adds a new notification.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // Updating the same notification maintains the same count.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // A new notification increases the count.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_TRUE(FindNotification("Dpath"));

  // Hiding a notification removes it from our data.
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_FALSE(FindNotification("DFpath"));
  EXPECT_TRUE(FindNotification("Dpath"));
};

// Note: Delayed tests use a delay time of 0 so that tasks wille execute
// when RunAllPendingInMessageLoop() is called.
IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, ShowDelayedTest) {
  InitNotifications();
  // Adding a delayed notification does not create a notification.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());
  EXPECT_FALSE(FindNotification("Dpath"));

  // Running the message loop should create the notification.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // Showing a notification both immediately and delayed results in one
  // additional notification.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("DFpath"));

  // When the delayed notification is processed, it's an update, so we still
  // only have two notifications.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("DFpath"));

  // If we schedule a show for later, then hide before it becomes visible,
  // the notification should not be added.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::FORMAT_FAIL,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  notifications_->HideNotification(FileBrowserNotifications::FORMAT_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_FALSE(FindNotification("Fpath"));

  // Even after processing messages, no new notification should be added.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(2u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_FALSE(FindNotification("Fpath"));
}

IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, HideDelayedTest) {
  InitNotifications();
  // Showing now, and scheduling a hide for later, results in one notification.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  EXPECT_EQ(1u, notifications_->GetNotificationCountForTest());
  EXPECT_TRUE(FindNotification("Dpath"));

  // Running pending messges should remove the notification.
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());

  // Immediate show then hide results in no notification.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());

  // Delayed hide for a notification that doesn't exist does nothing.
  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path",
                                          base::TimeDelta::FromSeconds(0));
  content::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, notifications_->GetNotificationCountForTest());
}

}  // namespace chromeos.
<|endoftext|>


<commit_before>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2013, Ioan A. Sucan
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Ioan A. Sucan nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author: Ioan Sucan, Dave Coleman, Robert Haschke */

#include "moveit_fake_controllers.h"
#include <ros/ros.h>
#include <moveit/robot_state/robot_state.h>
#include <moveit/robot_model_loader/robot_model_loader.h>
#include <sensor_msgs/JointState.h>
#include <pluginlib/class_list_macros.hpp>
#include <ros/console.h>
#include <map>
#include <iterator>

namespace moveit_fake_controller_manager
{
static const std::string DEFAULT_TYPE = "interpolate";
static const std::string ROBOT_DESCRIPTION = "robot_description";

class MoveItFakeControllerManager : public moveit_controller_manager::MoveItControllerManager
{
public:
  MoveItFakeControllerManager() : node_handle_("~")
  {
    if (!node_handle_.hasParam("controller_list"))
    {
      ROS_ERROR_STREAM_NAMED("MoveItFakeControllerManager", "No controller_list specified.");
      return;
    }

    XmlRpc::XmlRpcValue controller_list;
    node_handle_.getParam("controller_list", controller_list);
    if (controller_list.getType() != XmlRpc::XmlRpcValue::TypeArray)
    {
      ROS_ERROR_NAMED("MoveItFakeControllerManager", "controller_list should be specified as an array");
      return;
    }

    pub_ = node_handle_.advertise<sensor_msgs::JointState>("fake_controller_joint_states", 100, false);

    /* publish initial pose */
    XmlRpc::XmlRpcValue initial;
    if (node_handle_.getParam("initial", initial))
    {
      sensor_msgs::JointState js = loadInitialJointValues(initial);
      js.header.stamp = ros::Time::now();
      pub_.publish(js);
    }

    /* actually create each controller */
    for (int i = 0; i < controller_list.size(); ++i)
    {
      if (!controller_list[i].hasMember("name") || !controller_list[i].hasMember("joints"))
      {
        ROS_ERROR_NAMED("MoveItFakeControllerManager", "Name and joints must be specified for each controller");
        continue;
      }

      try
      {
        std::string name = std::string(controller_list[i]["name"]);

        if (controller_list[i]["joints"].getType() != XmlRpc::XmlRpcValue::TypeArray)
        {
          ROS_ERROR_STREAM_NAMED("MoveItFakeControllerManager", "The list of joints for controller "
                                                                    << name << " is not specified as an array");
          continue;
        }
        std::vector<std::string> joints;
        for (int j = 0; j < controller_list[i]["joints"].size(); ++j)
          joints.push_back(std::string(controller_list[i]["joints"][j]));

        const std::string& type =
            controller_list[i].hasMember("type") ? std::string(controller_list[i]["type"]) : DEFAULT_TYPE;
        if (type == "last point")
          controllers_[name].reset(new LastPointController(name, joints, pub_));
        else if (type == "via points")
          controllers_[name].reset(new ViaPointController(name, joints, pub_));
        else if (type == "interpolate")
          controllers_[name].reset(new InterpolatingController(name, joints, pub_));
        else
          ROS_ERROR_STREAM("Unknown fake controller type: " << type);
      }
      catch (...)
      {
        ROS_ERROR_NAMED("MoveItFakeControllerManager", "Caught unknown exception while parsing controller information");
      }
    }
  }

  sensor_msgs::JointState loadInitialJointValues(XmlRpc::XmlRpcValue& param) const
  {
    sensor_msgs::JointState js;

    if (param.getType() != XmlRpc::XmlRpcValue::TypeArray || param.size() == 0)
    {
      ROS_ERROR_ONCE_NAMED("loadInitialJointValues", "Parameter 'initial' should be an array of (group, pose) "
                                                     "structs.");
      return js;
    }

    robot_model_loader::RobotModelLoader robot_model_loader(ROBOT_DESCRIPTION);
    robot_model::RobotModelPtr robot_model = robot_model_loader.getModel();
    typedef std::map<std::string, double> JointPoseMap;
    JointPoseMap joints;

    for (int i = 0, end = param.size(); i != end; ++i)
    {
      try
      {
        std::string group_name = std::string(param[i]["group"]);
        std::string pose_name = std::string(param[i]["pose"]);
        if (!robot_model->hasJointModelGroup(group_name))
        {
          ROS_WARN_STREAM_NAMED("loadInitialJointValues", "Unknown joint model group: " << group_name);
          continue;
        }
        moveit::core::JointModelGroup* jmg = robot_model->getJointModelGroup(group_name);
        moveit::core::RobotState robot_state(robot_model);
        const std::vector<std::string>& joint_names = jmg->getActiveJointModelNames();

        if (!robot_state.setToDefaultValues(jmg, pose_name))
        {
          ROS_WARN_NAMED("loadInitialJointValues", "Unknown pose '%s' for group '%s'.", pose_name.c_str(),
                         group_name.c_str());
          continue;
        }
        ROS_INFO_NAMED("loadInitialJointValues", "Set joints of group '%s' to pose '%s'.", group_name.c_str(),
                       pose_name.c_str());

        for (std::vector<std::string>::const_iterator jit = joint_names.begin(), end = joint_names.end(); jit != end;
             ++jit)
        {
          const moveit::core::JointModel* jm = robot_state.getJointModel(*jit);
          if (!jm)
          {
            ROS_WARN_STREAM_NAMED("loadInitialJointValues", "Unknown joint: " << *jit);
            continue;
          }
          if (jm->getVariableCount() != 1)
          {
            ROS_WARN_STREAM_NAMED("loadInitialJointValues", "Cannot handle multi-variable joint: " << *jit);
            continue;
          }

          joints[*jit] = robot_state.getJointPositions(jm)[0];
        }
      }
      catch (...)
      {
        ROS_ERROR_ONCE_NAMED("loadInitialJointValues", "Caught unknown exception while reading initial pose "
                                                       "information.");
      }
    }

    // fill the joint state
    for (JointPoseMap::const_iterator it = joints.begin(), end = joints.end(); it != end; ++it)
    {
      js.name.push_back(it->first);
      js.position.push_back(it->second);
    }
    return js;
  }

  virtual ~MoveItFakeControllerManager()
  {
  }

  /*
   * Get a controller, by controller name (which was specified in the controllers.yaml
   */
  virtual moveit_controller_manager::MoveItControllerHandlePtr getControllerHandle(const std::string& name)
  {
    std::map<std::string, BaseFakeControllerPtr>::const_iterator it = controllers_.find(name);
    if (it != controllers_.end())
      return it->second;
    else
      ROS_FATAL_STREAM("No such controller: " << name);
    return moveit_controller_manager::MoveItControllerHandlePtr();
  }

  /*
   * Get the list of controller names.
   */
  virtual void getControllersList(std::vector<std::string>& names)
  {
    for (std::map<std::string, BaseFakeControllerPtr>::const_iterator it = controllers_.begin();
         it != controllers_.end(); ++it)
      names.push_back(it->first);
    ROS_INFO_STREAM("Returned " << names.size() << " controllers in list");
  }

  /*
   * Fake controllers are always active
   */
  virtual void getActiveControllers(std::vector<std::string>& names)
  {
    getControllersList(names);
  }

  /*
   * Fake controllers are always loaded
   */
  virtual void getLoadedControllers(std::vector<std::string>& names)
  {
    getControllersList(names);
  }

  /*
   * Get the list of joints that a controller can control.
   */
  virtual void getControllerJoints(const std::string& name, std::vector<std::string>& joints)
  {
    std::map<std::string, BaseFakeControllerPtr>::const_iterator it = controllers_.find(name);
    if (it != controllers_.end())
    {
      it->second->getJoints(joints);
    }
    else
    {
      ROS_WARN("The joints for controller '%s' are not known. Perhaps the controller configuration is not loaded on "
               "the param server?",
               name.c_str());
      joints.clear();
    }
  }

  /*
   * Controllers are all active and default.
   */
  virtual moveit_controller_manager::MoveItControllerManager::ControllerState
  getControllerState(const std::string& name)
  {
    moveit_controller_manager::MoveItControllerManager::ControllerState state;
    state.active_ = true;
    state.default_ = true;
    return state;
  }

  /* Cannot switch our controllers */
  virtual bool switchControllers(const std::vector<std::string>& activate, const std::vector<std::string>& deactivate)
  {
    return false;
  }

protected:
  ros::NodeHandle node_handle_;
  ros::Publisher pub_;
  std::map<std::string, BaseFakeControllerPtr> controllers_;
};

}  // end namespace moveit_fake_controller_manager

PLUGINLIB_EXPORT_CLASS(moveit_fake_controller_manager::MoveItFakeControllerManager,
                       moveit_controller_manager::MoveItControllerManager);
<commit_msg>latch initial pose published by fake_controller_manager (#1092)<commit_after>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2013, Ioan A. Sucan
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Ioan A. Sucan nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author: Ioan Sucan, Dave Coleman, Robert Haschke */

#include "moveit_fake_controllers.h"
#include <ros/ros.h>
#include <moveit/robot_state/robot_state.h>
#include <moveit/robot_model_loader/robot_model_loader.h>
#include <sensor_msgs/JointState.h>
#include <pluginlib/class_list_macros.hpp>
#include <ros/console.h>
#include <map>
#include <iterator>

namespace moveit_fake_controller_manager
{
static const std::string DEFAULT_TYPE = "interpolate";
static const std::string ROBOT_DESCRIPTION = "robot_description";

class MoveItFakeControllerManager : public moveit_controller_manager::MoveItControllerManager
{
public:
  MoveItFakeControllerManager() : node_handle_("~")
  {
    if (!node_handle_.hasParam("controller_list"))
    {
      ROS_ERROR_STREAM_NAMED("MoveItFakeControllerManager", "No controller_list specified.");
      return;
    }

    XmlRpc::XmlRpcValue controller_list;
    node_handle_.getParam("controller_list", controller_list);
    if (controller_list.getType() != XmlRpc::XmlRpcValue::TypeArray)
    {
      ROS_ERROR_NAMED("MoveItFakeControllerManager", "controller_list should be specified as an array");
      return;
    }

    /* by setting latch to true we preserve the initial joint state while other nodes launch */
    bool latch = true;
    pub_ = node_handle_.advertise<sensor_msgs::JointState>("fake_controller_joint_states", 100, latch);

    /* publish initial pose */
    XmlRpc::XmlRpcValue initial;
    if (node_handle_.getParam("initial", initial))
    {
      sensor_msgs::JointState js = loadInitialJointValues(initial);
      js.header.stamp = ros::Time::now();
      pub_.publish(js);
    }

    /* actually create each controller */
    for (int i = 0; i < controller_list.size(); ++i)
    {
      if (!controller_list[i].hasMember("name") || !controller_list[i].hasMember("joints"))
      {
        ROS_ERROR_NAMED("MoveItFakeControllerManager", "Name and joints must be specified for each controller");
        continue;
      }

      try
      {
        std::string name = std::string(controller_list[i]["name"]);

        if (controller_list[i]["joints"].getType() != XmlRpc::XmlRpcValue::TypeArray)
        {
          ROS_ERROR_STREAM_NAMED("MoveItFakeControllerManager", "The list of joints for controller "
                                                                    << name << " is not specified as an array");
          continue;
        }
        std::vector<std::string> joints;
        for (int j = 0; j < controller_list[i]["joints"].size(); ++j)
          joints.push_back(std::string(controller_list[i]["joints"][j]));

        const std::string& type =
            controller_list[i].hasMember("type") ? std::string(controller_list[i]["type"]) : DEFAULT_TYPE;
        if (type == "last point")
          controllers_[name].reset(new LastPointController(name, joints, pub_));
        else if (type == "via points")
          controllers_[name].reset(new ViaPointController(name, joints, pub_));
        else if (type == "interpolate")
          controllers_[name].reset(new InterpolatingController(name, joints, pub_));
        else
          ROS_ERROR_STREAM("Unknown fake controller type: " << type);
      }
      catch (...)
      {
        ROS_ERROR_NAMED("MoveItFakeControllerManager", "Caught unknown exception while parsing controller information");
      }
    }
  }

  sensor_msgs::JointState loadInitialJointValues(XmlRpc::XmlRpcValue& param) const
  {
    sensor_msgs::JointState js;

    if (param.getType() != XmlRpc::XmlRpcValue::TypeArray || param.size() == 0)
    {
      ROS_ERROR_ONCE_NAMED("loadInitialJointValues", "Parameter 'initial' should be an array of (group, pose) "
                                                     "structs.");
      return js;
    }

    robot_model_loader::RobotModelLoader robot_model_loader(ROBOT_DESCRIPTION);
    robot_model::RobotModelPtr robot_model = robot_model_loader.getModel();
    typedef std::map<std::string, double> JointPoseMap;
    JointPoseMap joints;

    for (int i = 0, end = param.size(); i != end; ++i)
    {
      try
      {
        std::string group_name = std::string(param[i]["group"]);
        std::string pose_name = std::string(param[i]["pose"]);
        if (!robot_model->hasJointModelGroup(group_name))
        {
          ROS_WARN_STREAM_NAMED("loadInitialJointValues", "Unknown joint model group: " << group_name);
          continue;
        }
        moveit::core::JointModelGroup* jmg = robot_model->getJointModelGroup(group_name);
        moveit::core::RobotState robot_state(robot_model);
        const std::vector<std::string>& joint_names = jmg->getActiveJointModelNames();

        if (!robot_state.setToDefaultValues(jmg, pose_name))
        {
          ROS_WARN_NAMED("loadInitialJointValues", "Unknown pose '%s' for group '%s'.", pose_name.c_str(),
                         group_name.c_str());
          continue;
        }
        ROS_INFO_NAMED("loadInitialJointValues", "Set joints of group '%s' to pose '%s'.", group_name.c_str(),
                       pose_name.c_str());

        for (std::vector<std::string>::const_iterator jit = joint_names.begin(), end = joint_names.end(); jit != end;
             ++jit)
        {
          const moveit::core::JointModel* jm = robot_state.getJointModel(*jit);
          if (!jm)
          {
            ROS_WARN_STREAM_NAMED("loadInitialJointValues", "Unknown joint: " << *jit);
            continue;
          }
          if (jm->getVariableCount() != 1)
          {
            ROS_WARN_STREAM_NAMED("loadInitialJointValues", "Cannot handle multi-variable joint: " << *jit);
            continue;
          }

          joints[*jit] = robot_state.getJointPositions(jm)[0];
        }
      }
      catch (...)
      {
        ROS_ERROR_ONCE_NAMED("loadInitialJointValues", "Caught unknown exception while reading initial pose "
                                                       "information.");
      }
    }

    // fill the joint state
    for (JointPoseMap::const_iterator it = joints.begin(), end = joints.end(); it != end; ++it)
    {
      js.name.push_back(it->first);
      js.position.push_back(it->second);
    }
    return js;
  }

  virtual ~MoveItFakeControllerManager()
  {
  }

  /*
   * Get a controller, by controller name (which was specified in the controllers.yaml
   */
  virtual moveit_controller_manager::MoveItControllerHandlePtr getControllerHandle(const std::string& name)
  {
    std::map<std::string, BaseFakeControllerPtr>::const_iterator it = controllers_.find(name);
    if (it != controllers_.end())
      return it->second;
    else
      ROS_FATAL_STREAM("No such controller: " << name);
    return moveit_controller_manager::MoveItControllerHandlePtr();
  }

  /*
   * Get the list of controller names.
   */
  virtual void getControllersList(std::vector<std::string>& names)
  {
    for (std::map<std::string, BaseFakeControllerPtr>::const_iterator it = controllers_.begin();
         it != controllers_.end(); ++it)
      names.push_back(it->first);
    ROS_INFO_STREAM("Returned " << names.size() << " controllers in list");
  }

  /*
   * Fake controllers are always active
   */
  virtual void getActiveControllers(std::vector<std::string>& names)
  {
    getControllersList(names);
  }

  /*
   * Fake controllers are always loaded
   */
  virtual void getLoadedControllers(std::vector<std::string>& names)
  {
    getControllersList(names);
  }

  /*
   * Get the list of joints that a controller can control.
   */
  virtual void getControllerJoints(const std::string& name, std::vector<std::string>& joints)
  {
    std::map<std::string, BaseFakeControllerPtr>::const_iterator it = controllers_.find(name);
    if (it != controllers_.end())
    {
      it->second->getJoints(joints);
    }
    else
    {
      ROS_WARN("The joints for controller '%s' are not known. Perhaps the controller configuration is not loaded on "
               "the param server?",
               name.c_str());
      joints.clear();
    }
  }

  /*
   * Controllers are all active and default.
   */
  virtual moveit_controller_manager::MoveItControllerManager::ControllerState
  getControllerState(const std::string& name)
  {
    moveit_controller_manager::MoveItControllerManager::ControllerState state;
    state.active_ = true;
    state.default_ = true;
    return state;
  }

  /* Cannot switch our controllers */
  virtual bool switchControllers(const std::vector<std::string>& activate, const std::vector<std::string>& deactivate)
  {
    return false;
  }

protected:
  ros::NodeHandle node_handle_;
  ros::Publisher pub_;
  std::map<std::string, BaseFakeControllerPtr> controllers_;
};

}  // end namespace moveit_fake_controller_manager

PLUGINLIB_EXPORT_CLASS(moveit_fake_controller_manager::MoveItFakeControllerManager,
                       moveit_controller_manager::MoveItControllerManager);
<|endoftext|>


<commit_before>// -*- mode: c++, coding: utf-8 -*-
/**
 * tbrpg – Text based roll playing game
 *
 * Copyright © 2012  Mattias Andrée (maandree@kth.se)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __GUARD_ACTIONSLOTCHART_HPP__
#define __GUARD_ACTIONSLOTCHART_HPP__

#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <unordered_map>

#include "Class.hpp"
#include "ActionSlot.hpp"

/**
 * Text based roll playing game
 *
 * DD2387 Program construction with C++
 * Laboration 3
 *
 * @author  Mattias Andrée <maandree@kth.se>
 */
namespace tbrpg
{
  /**
   * Prestige class–action slot cart
   */
  class ActionSlotChart
  {
  public:
    /**
     * Prestige class to OR:able index map
     */
    std::unordered_map<Class, long long> index_map;

    /**
     * Index combination to action slots map
     */
    std::unordered_map<long long, std::vector<ActionSlot>> slot_map;

    /**
     * Construction
     */
    ActionSlotChart();

    /**
     * Copy constructor
     *
     * @param  original  The object to clone
     */
    ActionSlotChart(const ActionSlotChart& original);

    /**
     * Copy constructor
     *
     * @param  original  The object to clone
     */
    ActionSlotChart(ActionSlotChart& original);

    /**
     * Move constructor
     *
     * @param  original  The object to clone
     */
    ActionSlotChart(ActionSlotChart&& original);

    /**
     * Destructor
     */
    virtual ~ActionSlotChart();

    /**
     * Assignment operator
     *
     * @param   original  The reference object
     * @return            The invoked object
     */
    virtual ActionSlotChart& operator =(const ActionSlotChart& original);

    /**
     * Assignment operator
     *
     * @param   original  The reference object
     * @return            The invoked object
     */
    virtual ActionSlotChart& operator =(ActionSlotChart& original);

    /**
     * Move operator
     *
     * @param   original  The moved object, its resourced will be moved
     * @return            The invoked object
     */
    virtual ActionSlotChart& operator =(ActionSlotChart&& original);

    /**
     * Equality evaluator
     *
     * @param   other  The other comparand
     * @return         Whether the instances are equal
     */
    virtual bool operator ==(const ActionSlotChart& other) const;

  protected:
    /**
     * Copy method
     *
     * @param  self      The object to modify
     * @param  original  The reference object
     */
    static void __copy__(ActionSlotChart& self, const ActionSlotChart& original);

  public:
    /**
     * Hash method
     *
     * @return  The object's hash code
     */
    size_t hash() const;

  };
}

namespace std
{
  template<>
  class hash<tbrpg::ActionSlotChart>
  {
  public:
    size_t operator()(const tbrpg::ActionSlotChart& elem) const
    {
       return elem.hash();
    }
  };
}

#endif//__GUARD_ACTIONSLOTCHART_HPP__
<commit_msg>forgot to stage<commit_after>// -*- mode: c++, coding: utf-8 -*-
/**
 * tbrpg – Text based roll playing game
 *
 * Copyright © 2012  Mattias Andrée (maandree@kth.se)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __GUARD_ACTIONSLOTCHART_HPP__
#define __GUARD_ACTIONSLOTCHART_HPP__

#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <unordered_map>

#include "Class.hpp"
#include "ActionSlot.hpp"
#include "Fighter.hpp"
#include "Ranger.hpp"
#include "Paladin.hpp"
#include "Thief.hpp"
#include "Bard.hpp"
#include "Cleric.hpp"
#include "Druid.hpp"
#include "Mage.hpp"
#include "Sorcerer.hpp"

/**
 * Text based roll playing game
 *
 * DD2387 Program construction with C++
 * Laboration 3
 *
 * @author  Mattias Andrée <maandree@kth.se>
 */
namespace tbrpg
{
  /**
   * Prestige class–action slot cart
   */
  class ActionSlotChart
  {
  public:
    /**
     * Prestige class to OR:able index map
     */
    std::unordered_map<Class, long long> index_map;

    /**
     * Index combination to action slots map
     */
    std::unordered_map<long long, std::vector<ActionSlot>> slot_map;

    /**
     * Construction
     */
    ActionSlotChart();

    /**
     * Copy constructor
     *
     * @param  original  The object to clone
     */
    ActionSlotChart(const ActionSlotChart& original);

    /**
     * Copy constructor
     *
     * @param  original  The object to clone
     */
    ActionSlotChart(ActionSlotChart& original);

    /**
     * Move constructor
     *
     * @param  original  The object to clone
     */
    ActionSlotChart(ActionSlotChart&& original);

    /**
     * Destructor
     */
    virtual ~ActionSlotChart();

    /**
     * Assignment operator
     *
     * @param   original  The reference object
     * @return            The invoked object
     */
    virtual ActionSlotChart& operator =(const ActionSlotChart& original);

    /**
     * Assignment operator
     *
     * @param   original  The reference object
     * @return            The invoked object
     */
    virtual ActionSlotChart& operator =(ActionSlotChart& original);

    /**
     * Move operator
     *
     * @param   original  The moved object, its resourced will be moved
     * @return            The invoked object
     */
    virtual ActionSlotChart& operator =(ActionSlotChart&& original);

    /**
     * Equality evaluator
     *
     * @param   other  The other comparand
     * @return         Whether the instances are equal
     */
    virtual bool operator ==(const ActionSlotChart& other) const;

  protected:
    /**
     * Copy method
     *
     * @param  self      The object to modify
     * @param  original  The reference object
     */
    static void __copy__(ActionSlotChart& self, const ActionSlotChart& original);

  public:
    /**
     * Hash method
     *
     * @return  The object's hash code
     */
    size_t hash() const;

  };
}

namespace std
{
  template<>
  class hash<tbrpg::ActionSlotChart>
  {
  public:
    size_t operator()(const tbrpg::ActionSlotChart& elem) const
    {
       return elem.hash();
    }
  };
}

#endif//__GUARD_ACTIONSLOTCHART_HPP__
<|endoftext|>


<commit_before>#include "kernel.h"
#include "geometries.h"
#include "ilwisdata.h"
#include "ellipsoid.h"
#include "geodeticdatum.h"
#include "projection.h"
#include "coordinatesystem.h"
#include "conventionalcoordinatesystem.h"
#include "proj4parameters.h"

using namespace Ilwis;

ConventionalCoordinateSystem::ConventionalCoordinateSystem() : _unit(sUNDEF)
{
}

ConventionalCoordinateSystem::ConventionalCoordinateSystem(const Resource &resource) : CoordinateSystem(resource),_unit(sUNDEF)
{
}

ConventionalCoordinateSystem::~ConventionalCoordinateSystem()
{
    _projection.set(0);
    _ellipsoid.set(0);
}

Coordinate ConventionalCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    //TODO isLatLon guard doesn't consider latlon cs other than WGS84!
    if (sourceCs->id() == id()) //  the 'real'isEqual test is too expensive here, as this method can be called 100000's of times (resample)
        return crdSource;
    LatLon ll = sourceCs->isLatLon() ? LatLon(crdSource.y,crdSource.x) : sourceCs->coord2latlon(crdSource);
    if ( ll.isValid()) {
        return isLatLon() ? ll : latlon2coord(ll);
    }
    return Coordinate();
}

LatLon ConventionalCoordinateSystem::coord2latlon(const Coordinate &crdSource) const
{
    LatLon pl = _projection->coord2latlon(crdSource);
    if (!pl.isValid())
        return llUNDEF;
    if (abs(pl.lon()) > 90)
        return llUNDEF;
    return pl;
}

Coordinate ConventionalCoordinateSystem::latlon2coord(const LatLon &ll) const
{
    Coordinate xy = _projection->latlon2coord(ll);
    if (xy == crdUNDEF)
        return crdUNDEF;
    return xy;

}

bool ConventionalCoordinateSystem::isEqual(const IlwisObject *obj) const
{
    if ( !obj || !hasType(obj->ilwisType(), itCONVENTIONALCOORDSYSTEM))
        return false;

    if(id() == obj->id())
        return true;

    const ConventionalCoordinateSystem *csy = static_cast<const ConventionalCoordinateSystem *>(obj);
    if ( !csy->isValid())
        return false;

    if ( ellipsoid().isValid() && ellipsoid()->isEqual(csy->ellipsoid())) {
        if ( csy->projection().isValid() && projection().isValid()){ //  special case; in general datums will be checked first
            if (csy->projection()->code() == "longlat" && projection()->code() == "longlat")
                return true;
        }
        if ( datum() && csy->datum()) {
            if  (datum()->code() == csy->datum()->code())
                    return true;
        } else {
            if ( csy->projection().isValid() && projection().isValid()) {
                return csy->projection()->isEqual(projection().ptr());
            }
        }
    }

    return false;
}

QString ConventionalCoordinateSystem::toWKT(quint32 spaces) const
{
    QString wkt = "PROJCS[\"" + name() + "\"" + ",";
    QString geocs, proj, ell, datum;
    geocs += QString(" ").repeated(spaces);
    QString ending = spaces == 0 ? "" : "\n";
    if ( _datum){
        geocs += "GEOCS[\"";
        if ( name().indexOf("/") != -1){
            geocs += name().left( name().indexOf("/")).trimmed() + "\"";
        }else
            geocs += name() + "\"";

        datum = _datum->toWKT(spaces * 2);
    }
    QString primm = "PRIMEM[\"Greenwich\",0, AUTHORITY[\"EPSG\",8901\"]],";
    if ( _ellipsoid.isValid()){
        ell = _ellipsoid->toWKT(spaces * 2);
    }
    if ( _projection.isValid())
         proj= _projection->toWKT(spaces * 2) + ",";

    if ( geocs != ""){
        wkt += geocs + (datum !="" ? "," + datum : "") + "," + ell + primm + "]," + ending;
    }else
        wkt += ell + ",";
    wkt += proj;

    if ( _unit != ""){
        wkt += "UNIT[" + _unit + ",1.0]";
    }

    return wkt + "]";
}

QString ConventionalCoordinateSystem::toProj4() const
{
    if ( this->projection().isValid())
        return this->projection()->toProj4();
    else
        return QString("?");
}

QString ConventionalCoordinateSystem::unit() const
{
    return _unit;
}

void ConventionalCoordinateSystem::unit(const QString& unit)
{
    _unit = unit;
}

const std::unique_ptr<GeodeticDatum>& ConventionalCoordinateSystem::datum() const
{
    return _datum;
}

void ConventionalCoordinateSystem::setDatum(GeodeticDatum *datum)
{
    _datum.reset(datum);
}

IEllipsoid ConventionalCoordinateSystem::ellipsoid() const
{
    return _ellipsoid;
}

void ConventionalCoordinateSystem::setEllipsoid(const IEllipsoid &ell)
{
    _ellipsoid = ell;
}

bool ConventionalCoordinateSystem::isLatLon() const
{
    return _unit == "degrees";
}

IlwisTypes ConventionalCoordinateSystem::ilwisType() const
{
    return itCONVENTIONALCOORDSYSTEM;
}

bool ConventionalCoordinateSystem::isValid() const
{
    bool ok1 =  _projection.isValid();
    bool ok2 =_ellipsoid.isValid();

    return ok1 && ok2;
}

void ConventionalCoordinateSystem::setProjection(const IProjection &proj)
{
    _projection = proj;
    if ( proj->code().contains("longlat") || proj->code().contains("latlon"))
        _unit = "degrees";
}

IProjection ConventionalCoordinateSystem::projection() const
{
    return _projection;
}

bool ConventionalCoordinateSystem::prepare()
{
    return CoordinateSystem::prepare();
}

bool ConventionalCoordinateSystem::prepare(const QString &parms)
{
    Proj4Parameters proj4(parms);

    QString ell = proj4["ellps"];
    _ellipsoid = new Ellipsoid();
    if ( ell != sUNDEF) {
        _ellipsoid.prepare("code=" + ell);
    } else {
        QString laxis = proj4["a"];
        if ( laxis != sUNDEF) {
            QString saxis = proj4["b"];
            bool ok;
            double a = laxis.toDouble(&ok);
            if (!ok) return ERROR2(ERR_INVALID_PROPERTY_FOR_2, "ellipsoid", name());
            double b = saxis.toDouble(&ok);
            if (!ok) return ERROR2(ERR_INVALID_PROPERTY_FOR_2, "ellipsoid", name());

            double f = (a - b) / a;
            QString newName = _ellipsoid->setEllipsoid(a, f);
            _ellipsoid->name(newName);
        }
    }
    if ( proj4.hasDatum()) {
        _datum.reset(new GeodeticDatum());
        if ( proj4["dx"] != sUNDEF) {
            _datum->set7TransformationParameters(proj4["dx"].toDouble(),
                                                 proj4["dy"].toDouble(),
                                                 proj4["dz"].toDouble(),
                                                 proj4["rx"].toDouble(),
                                                 proj4["ry"].toDouble(),
                                                 proj4["rz"].toDouble(),
                                                 proj4["dscale"].toDouble());
        }
    }
    QString code = proj4["proj"];

    if ( code == sUNDEF) {
        kernel()->issues()->log(TR(ERR_INVALID_PROPERTY_FOR_2).arg("projection name", name()));
        return false;
    }
    code = "code=" + code;
    Resource prj = mastercatalog()->name2Resource(code, itPROJECTION);
    if ( !prj.isValid()) {
         return ERROR1(ERR_COULDNT_CREATE_OBJECT_FOR_1,"projection " + code );
    }
    bool ok =_projection.prepare(prj.id());
    _projection->setCoordinateSystem(this);
    if ( _projection.isValid())  {
        ok = _projection->prepare(parms);
    }
    QString unit = proj4["units"];
    if ( ok && (_projection->code().contains("longlat") || _projection->code().contains("latlon") || unit=="?"))
        _unit = "degrees";
    else{
        if ( unit == "m")
            _unit = "meter";
        else
            _unit = "feet";
    }

    return ok;
}

<commit_msg>ellipsoid code was not transferred to projection proj4 defintion<commit_after>#include "kernel.h"
#include "geometries.h"
#include "ilwisdata.h"
#include "ellipsoid.h"
#include "geodeticdatum.h"
#include "projection.h"
#include "coordinatesystem.h"
#include "conventionalcoordinatesystem.h"
#include "proj4parameters.h"

using namespace Ilwis;

ConventionalCoordinateSystem::ConventionalCoordinateSystem() : _unit(sUNDEF)
{
}

ConventionalCoordinateSystem::ConventionalCoordinateSystem(const Resource &resource) : CoordinateSystem(resource),_unit(sUNDEF)
{
}

ConventionalCoordinateSystem::~ConventionalCoordinateSystem()
{
    _projection.set(0);
    _ellipsoid.set(0);
}

Coordinate ConventionalCoordinateSystem::coord2coord(const ICoordinateSystem &sourceCs, const Coordinate &crdSource) const
{
    //TODO isLatLon guard doesn't consider latlon cs other than WGS84!
    if (sourceCs->id() == id()) //  the 'real'isEqual test is too expensive here, as this method can be called 100000's of times (resample)
        return crdSource;
    LatLon ll = sourceCs->isLatLon() ? LatLon(crdSource.y,crdSource.x) : sourceCs->coord2latlon(crdSource);
    if ( ll.isValid()) {
        return isLatLon() ? ll : latlon2coord(ll);
    }
    return Coordinate();
}

LatLon ConventionalCoordinateSystem::coord2latlon(const Coordinate &crdSource) const
{
    LatLon pl = _projection->coord2latlon(crdSource);
    if (!pl.isValid())
        return llUNDEF;
    if (abs(pl.lon()) > 90)
        return llUNDEF;
    return pl;
}

Coordinate ConventionalCoordinateSystem::latlon2coord(const LatLon &ll) const
{
    Coordinate xy = _projection->latlon2coord(ll);
    if (xy == crdUNDEF)
        return crdUNDEF;
    return xy;

}

bool ConventionalCoordinateSystem::isEqual(const IlwisObject *obj) const
{
    if ( !obj || !hasType(obj->ilwisType(), itCONVENTIONALCOORDSYSTEM))
        return false;

    if(id() == obj->id())
        return true;

    const ConventionalCoordinateSystem *csy = static_cast<const ConventionalCoordinateSystem *>(obj);
    if ( !csy->isValid())
        return false;

    if ( ellipsoid().isValid() && ellipsoid()->isEqual(csy->ellipsoid())) {
        if ( csy->projection().isValid() && projection().isValid()){ //  special case; in general datums will be checked first
            if (csy->projection()->code() == "longlat" && projection()->code() == "longlat")
                return true;
        }
        if ( datum() && csy->datum()) {
            if  (datum()->code() == csy->datum()->code())
                    return true;
        } else {
            if ( csy->projection().isValid() && projection().isValid()) {
                return csy->projection()->isEqual(projection().ptr());
            }
        }
    }

    return false;
}

QString ConventionalCoordinateSystem::toWKT(quint32 spaces) const
{
    QString wkt = "PROJCS[\"" + name() + "\"" + ",";
    QString geocs, proj, ell, datum;
    geocs += QString(" ").repeated(spaces);
    QString ending = spaces == 0 ? "" : "\n";
    if ( _datum){
        geocs += "GEOCS[\"";
        if ( name().indexOf("/") != -1){
            geocs += name().left( name().indexOf("/")).trimmed() + "\"";
        }else
            geocs += name() + "\"";

        datum = _datum->toWKT(spaces * 2);
    }
    QString primm = "PRIMEM[\"Greenwich\",0, AUTHORITY[\"EPSG\",8901\"]],";
    if ( _ellipsoid.isValid()){
        ell = _ellipsoid->toWKT(spaces * 2);
    }
    if ( _projection.isValid())
         proj= _projection->toWKT(spaces * 2) + ",";

    if ( geocs != ""){
        wkt += geocs + (datum !="" ? "," + datum : "") + "," + ell + primm + "]," + ending;
    }else
        wkt += ell + ",";
    wkt += proj;

    if ( _unit != ""){
        wkt += "UNIT[" + _unit + ",1.0]";
    }

    return wkt + "]";
}

QString ConventionalCoordinateSystem::toProj4() const
{
    if ( this->projection().isValid())
        return this->projection()->toProj4();
    else
        return QString("?");
}

QString ConventionalCoordinateSystem::unit() const
{
    return _unit;
}

void ConventionalCoordinateSystem::unit(const QString& unit)
{
    _unit = unit;
}

const std::unique_ptr<GeodeticDatum>& ConventionalCoordinateSystem::datum() const
{
    return _datum;
}

void ConventionalCoordinateSystem::setDatum(GeodeticDatum *datum)
{
    _datum.reset(datum);
}

IEllipsoid ConventionalCoordinateSystem::ellipsoid() const
{
    return _ellipsoid;
}

void ConventionalCoordinateSystem::setEllipsoid(const IEllipsoid &ell)
{
    _ellipsoid = ell;
    if ( _projection.isValid() && ell.isValid()){
        _projection->setParameter(Projection::pvELLCODE,ell->toProj4());
    }
}

bool ConventionalCoordinateSystem::isLatLon() const
{
    return _unit == "degrees";
}

IlwisTypes ConventionalCoordinateSystem::ilwisType() const
{
    return itCONVENTIONALCOORDSYSTEM;
}

bool ConventionalCoordinateSystem::isValid() const
{
    bool ok1 =  _projection.isValid();
    bool ok2 =_ellipsoid.isValid();

    return ok1 && ok2;
}

void ConventionalCoordinateSystem::setProjection(const IProjection &proj)
{
    _projection = proj;
    if ( proj->code().contains("longlat") || proj->code().contains("latlon"))
        _unit = "degrees";
}

IProjection ConventionalCoordinateSystem::projection() const
{
    return _projection;
}

bool ConventionalCoordinateSystem::prepare()
{
    return CoordinateSystem::prepare();
}

bool ConventionalCoordinateSystem::prepare(const QString &parms)
{
    Proj4Parameters proj4(parms);

    QString ell = proj4["ellps"];
    _ellipsoid = new Ellipsoid();
    if ( ell != sUNDEF) {
        _ellipsoid.prepare("code=" + ell);
    } else {
        QString laxis = proj4["a"];
        if ( laxis != sUNDEF) {
            QString saxis = proj4["b"];
            bool ok;
            double a = laxis.toDouble(&ok);
            if (!ok) return ERROR2(ERR_INVALID_PROPERTY_FOR_2, "ellipsoid", name());
            double b = saxis.toDouble(&ok);
            if (!ok) return ERROR2(ERR_INVALID_PROPERTY_FOR_2, "ellipsoid", name());

            double f = (a - b) / a;
            QString newName = _ellipsoid->setEllipsoid(a, f);
            _ellipsoid->name(newName);
        }
    }
    if ( proj4.hasDatum()) {
        _datum.reset(new GeodeticDatum());
        if ( proj4["dx"] != sUNDEF) {
            _datum->set7TransformationParameters(proj4["dx"].toDouble(),
                                                 proj4["dy"].toDouble(),
                                                 proj4["dz"].toDouble(),
                                                 proj4["rx"].toDouble(),
                                                 proj4["ry"].toDouble(),
                                                 proj4["rz"].toDouble(),
                                                 proj4["dscale"].toDouble());
        }
    }
    QString code = proj4["proj"];

    if ( code == sUNDEF) {
        kernel()->issues()->log(TR(ERR_INVALID_PROPERTY_FOR_2).arg("projection name", name()));
        return false;
    }
    code = "code=" + code;
    Resource prj = mastercatalog()->name2Resource(code, itPROJECTION);
    if ( !prj.isValid()) {
         return ERROR1(ERR_COULDNT_CREATE_OBJECT_FOR_1,"projection " + code );
    }
    bool ok =_projection.prepare(prj.id());
    _projection->setCoordinateSystem(this);
    if ( _projection.isValid())  {
        ok = _projection->prepare(parms);
    }
    QString unit = proj4["units"];
    if ( ok && (_projection->code().contains("longlat") || _projection->code().contains("latlon") || unit=="?"))
        _unit = "degrees";
    else{
        if ( unit == "m")
            _unit = "meter";
        else
            _unit = "feet";
    }

    return ok;
}

<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
#define DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH

#include <iostream>

// dune-common
#include <dune/common/densevector.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/deprecated.hh>

namespace Dune {
namespace Stuff {
namespace Common {

template< class VectorImp >
void clear(Dune::DenseVector< VectorImp >& vector)
{
  vector = typename Dune::DenseVector< VectorImp >::value_type(0);
} // void clear( DenseVectorType& vector )

template< class T >
DUNE_DEPRECATED_MSG("THIS WILL BE REMOVED ONCE ExtendedParameterTree::getVector() IS PROPERLY IMPLEMENTED!")
Dune::DynamicVector< T > resize(const Dune::DynamicVector< T >& inVector,
                                const size_t newSize,
                                const T fill = T(0))
{
  Dune::DynamicVector< T > outVector(newSize);
  for (size_t ii = 0; ii < std::min(inVector.size(), newSize); ++ii)
    outVector[ii] = inVector[ii];
  for (size_t ii = std::min(inVector.size(), newSize); ii < newSize; ++ii)
    outVector[ii] = fill;
  return outVector;
}

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
<commit_msg>[common.vector] added float_cmp is probably obsolete, this should be in common somewhere<commit_after>#ifndef DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
#define DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH

#include <iostream>

#include <dune/common/densevector.hh>
#include <dune/common/dynvector.hh>
#include <dune/common/fvector.hh>
#include <dune/common/deprecated.hh>

namespace Dune {
namespace Stuff {
namespace Common {

template< class VectorImp >
void clear(Dune::DenseVector< VectorImp >& vector)
{
  vector = typename Dune::DenseVector< VectorImp >::value_type(0);
}

/**
 *  \brief Compare x and y component-wise for almost equality.
 *
 *  This implementation is taken from pymor: https://github.com/pyMor/pyMor/blob/master/src/pymor/tools/floatcmp.py
 *  Credit goes to Stephan Rave
 */
template< class Field, int size >
bool float_cmp(const Dune::FieldVector< Field, size >& x,
               const Dune::FieldVector< Field, size >& y,
               const Field atol,
               const Field rtol)
{
  unsigned int failure = 0;
  for (size_t ii = 0; ii < size; ++ii)
    if (std::abs(x[ii] - y[ii]) > atol + std::abs(y[ii]) * rtol)
      ++failure;
  return !bool(failure);
}

template< class Field, int size >
bool float_cmp(const Dune::FieldVector< Field, size >& x,
               const Dune::FieldVector< Field, size >& y,
               const Field atol)
{
  unsigned int failure = 0;
  for (size_t ii = 0; ii < size; ++ii)
    if (std::abs(x[ii] - y[ii]) > atol + std::abs(y[ii]) * atol)
      ++failure;
  return !bool(failure);
}

template< class T >
DUNE_DEPRECATED_MSG("THIS WILL BE REMOVED ONCE ExtendedParameterTree::getVector() IS PROPERLY IMPLEMENTED!")
Dune::DynamicVector< T > resize(const Dune::DynamicVector< T >& inVector,
                                const size_t newSize,
                                const T fill = T(0))
{
  Dune::DynamicVector< T > outVector(newSize);
  for (size_t ii = 0; ii < std::min(inVector.size(), newSize); ++ii)
    outVector[ii] = inVector[ii];
  for (size_t ii = std::min(inVector.size(), newSize); ii < newSize; ++ii)
    outVector[ii] = fill;
  return outVector;
}

} // namespace Common
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_TOOLS_COMMON_VEECTOR_HH
<|endoftext|>