<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file brw_wm_vector_splitting.cpp
 *
 * If a vector is only ever referenced by its components, then
 * split those components out to individual variables so they can be
 * handled normally by other optimization passes.
 *
 * This skips vectors in uniforms and varyings, which need to be
 * accessible as vectors for their access by the GL.  Also, vector
 * results of non-variable-derefs in assignments aren't handled
 * because to do so we would have to store the vector result to a
 * temporary in order to unload each channel, and to do so would just
 * loop us back to where we started.  For the 965, this is exactly the
 * behavior we want for the results of texture lookups, but probably not for
 */

extern "C" {
#include "main/core.h"
#include "brw_context.h"
}
#include "glsl/ir.h"
#include "glsl/ir_visitor.h"
#include "glsl/ir_rvalue_visitor.h"
#include "glsl/glsl_types.h"

static bool debug = false;

class variable_entry : public exec_node
{
public:
   variable_entry(ir_variable *var)
   {
      this->var = var;
      this->whole_vector_access = 0;
      this->declaration = false;
      this->mem_ctx = NULL;
   }

   ir_variable *var; /* The key: the variable's pointer. */

   /** Number of times the variable is referenced, including assignments. */
   unsigned whole_vector_access;

   bool declaration; /* If the variable had a decl in the instruction stream */

   ir_variable *components[4];

   /** ralloc_parent(this->var) -- the shader's ralloc context. */
   void *mem_ctx;
};

class ir_vector_reference_visitor : public ir_hierarchical_visitor {
public:
   ir_vector_reference_visitor(void)
   {
      this->mem_ctx = ralloc_context(NULL);
      this->variable_list.make_empty();
   }

   ~ir_vector_reference_visitor(void)
   {
      ralloc_free(mem_ctx);
   }

   virtual ir_visitor_status visit(ir_variable *);
   virtual ir_visitor_status visit(ir_dereference_variable *);
   virtual ir_visitor_status visit_enter(ir_swizzle *);
   virtual ir_visitor_status visit_enter(ir_assignment *);
   virtual ir_visitor_status visit_enter(ir_function_signature *);

   variable_entry *get_variable_entry(ir_variable *var);

   /* List of variable_entry */
   exec_list variable_list;

   void *mem_ctx;
};

variable_entry *
ir_vector_reference_visitor::get_variable_entry(ir_variable *var)
{
   assert(var);

   if (!var->type->is_vector())
      return NULL;

   switch (var->mode) {
   case ir_var_uniform:
   case ir_var_shader_in:
   case ir_var_shader_out:
   case ir_var_function_in:
   case ir_var_function_out:
   case ir_var_function_inout:
      /* Can't split varyings or uniforms.  Function in/outs won't get split
       * either.
       */
      return NULL;
   case ir_var_auto:
   case ir_var_temporary:
      break;
   }

   foreach_list(node, &this->variable_list) {
      variable_entry *entry = (variable_entry *)node;
      if (entry->var == var)
	 return entry;
   }

   variable_entry *entry = new(mem_ctx) variable_entry(var);
   this->variable_list.push_tail(entry);
   return entry;
}

ir_visitor_status
ir_vector_reference_visitor::visit(ir_variable *ir)
{
   variable_entry *entry = this->get_variable_entry(ir);

   if (entry)
      entry->declaration = true;

   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit(ir_dereference_variable *ir)
{
   ir_variable *const var = ir->var;
   variable_entry *entry = this->get_variable_entry(var);

   if (entry)
      entry->whole_vector_access++;

   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit_enter(ir_swizzle *ir)
{
   /* Don't descend into a vector ir_dereference_variable below. */
   if (ir->val->as_dereference_variable() && ir->type->is_scalar())
      return visit_continue_with_parent;

   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit_enter(ir_assignment *ir)
{
   if (ir->lhs->as_dereference_variable() &&
       ir->rhs->as_dereference_variable() &&
       !ir->condition) {
      /* We'll split copies of a vector to copies of channels, so don't
       * descend to the ir_dereference_variables.
       */
      return visit_continue_with_parent;
   }
   if (ir->lhs->as_dereference_variable() &&
       is_power_of_two(ir->write_mask) &&
       !ir->condition) {
      /* If we're writing just a channel, then channel-splitting the LHS is OK.
       */
      ir->rhs->accept(this);
      return visit_continue_with_parent;
   }
   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit_enter(ir_function_signature *ir)
{
   /* We don't want to descend into the function parameters and
    * split them, so just accept the body here.
    */
   visit_list_elements(this, &ir->body);
   return visit_continue_with_parent;
}

class ir_vector_splitting_visitor : public ir_rvalue_visitor {
public:
   ir_vector_splitting_visitor(exec_list *vars)
   {
      this->variable_list = vars;
   }

   virtual ir_visitor_status visit_leave(ir_assignment *);

   void handle_rvalue(ir_rvalue **rvalue);
   variable_entry *get_splitting_entry(ir_variable *var);

   exec_list *variable_list;
};

variable_entry *
ir_vector_splitting_visitor::get_splitting_entry(ir_variable *var)
{
   assert(var);

   if (!var->type->is_vector())
      return NULL;

   foreach_list(node, &*this->variable_list) {
      variable_entry *entry = (variable_entry *)node;
      if (entry->var == var) {
	 return entry;
      }
   }

   return NULL;
}

void
ir_vector_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
{
   if (!*rvalue)
      return;

   ir_swizzle *swiz = (*rvalue)->as_swizzle();
   if (!swiz || !swiz->type->is_scalar())
      return;

   ir_dereference_variable *deref_var = swiz->val->as_dereference_variable();
   if (!deref_var)
      return;

   variable_entry *entry = get_splitting_entry(deref_var->var);
   if (!entry)
      return;

   ir_variable *var = entry->components[swiz->mask.x];
   *rvalue = new(entry->mem_ctx) ir_dereference_variable(var);
}

ir_visitor_status
ir_vector_splitting_visitor::visit_leave(ir_assignment *ir)
{
   ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable();
   ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable();
   variable_entry *lhs = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL;
   variable_entry *rhs = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL;

   if (lhs_deref && rhs_deref && (lhs || rhs) && !ir->condition) {
      unsigned int rhs_chan = 0;

      /* Straight assignment of vector variables. */
      for (unsigned int i = 0; i < ir->lhs->type->vector_elements; i++) {
	 ir_dereference *new_lhs;
	 ir_rvalue *new_rhs;
	 void *mem_ctx = lhs ? lhs->mem_ctx : rhs->mem_ctx;
	 unsigned int writemask;

	 if (!(ir->write_mask & (1 << i)))
	    continue;

	 if (lhs) {
	    new_lhs = new(mem_ctx) ir_dereference_variable(lhs->components[i]);
	    writemask = 1;
	 } else {
	    new_lhs = ir->lhs->clone(mem_ctx, NULL);
	    writemask = 1 << i;
	 }

	 if (rhs) {
	    new_rhs =
	       new(mem_ctx) ir_dereference_variable(rhs->components[rhs_chan]);
	 } else {
	    new_rhs = new(mem_ctx) ir_swizzle(ir->rhs->clone(mem_ctx, NULL),
					      rhs_chan, 0, 0, 0, 1);
	 }

	 ir->insert_before(new(mem_ctx) ir_assignment(new_lhs,
						      new_rhs,
						      NULL, writemask));

	 rhs_chan++;
      }
      ir->remove();
   } else if (lhs) {
      void *mem_ctx = lhs->mem_ctx;
      int elem = -1;

      switch (ir->write_mask) {
      case (1 << 0):
	 elem = 0;
	 break;
      case (1 << 1):
	 elem = 1;
	 break;
      case (1 << 2):
	 elem = 2;
	 break;
      case (1 << 3):
	 elem = 3;
	 break;
      default:
	 ir->print();
	 assert(!"not reached: non-channelwise dereference of LHS.");
      }

      ir->lhs = new(mem_ctx) ir_dereference_variable(lhs->components[elem]);
      ir->write_mask = (1 << 0);

      handle_rvalue(&ir->rhs);
   } else {
      handle_rvalue(&ir->rhs);
   }

   handle_rvalue(&ir->condition);

   return visit_continue;
}

bool
brw_do_vector_splitting(exec_list *instructions)
{
   ir_vector_reference_visitor refs;

   visit_list_elements(&refs, instructions);

   /* Trim out variables we can't split. */
   foreach_list_safe(node, &refs.variable_list) {
      variable_entry *entry = (variable_entry *)node;

      if (debug) {
	 printf("vector %s@%p: decl %d, whole_access %d\n",
		entry->var->name, (void *) entry->var, entry->declaration,
		entry->whole_vector_access);
      }

      if (!entry->declaration || entry->whole_vector_access) {
	 entry->remove();
      }
   }

   if (refs.variable_list.is_empty())
      return false;

   void *mem_ctx = ralloc_context(NULL);

   /* Replace the decls of the vectors to be split with their split
    * components.
    */
   foreach_list(node, &refs.variable_list) {
      variable_entry *entry = (variable_entry *)node;
      const struct glsl_type *type;
      type = glsl_type::get_instance(entry->var->type->base_type, 1, 1);

      entry->mem_ctx = ralloc_parent(entry->var);

      for (unsigned int i = 0; i < entry->var->type->vector_elements; i++) {
	 const char *name = ralloc_asprintf(mem_ctx, "%s_%c",
					    entry->var->name,
					    "xyzw"[i]);

	 entry->components[i] = new(entry->mem_ctx) ir_variable(type, name,
								ir_var_temporary);
	 entry->var->insert_before(entry->components[i]);
      }

      entry->var->remove();
   }

   ir_vector_splitting_visitor split(&refs.variable_list);
   visit_list_elements(&split, instructions);

   ralloc_free(mem_ctx);

   return true;
}
<commit_msg>i965: Don't do vector splitting for ir_var_system_value<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * \file brw_wm_vector_splitting.cpp
 *
 * If a vector is only ever referenced by its components, then
 * split those components out to individual variables so they can be
 * handled normally by other optimization passes.
 *
 * This skips vectors in uniforms and varyings, which need to be
 * accessible as vectors for their access by the GL.  Also, vector
 * results of non-variable-derefs in assignments aren't handled
 * because to do so we would have to store the vector result to a
 * temporary in order to unload each channel, and to do so would just
 * loop us back to where we started.  For the 965, this is exactly the
 * behavior we want for the results of texture lookups, but probably not for
 */

extern "C" {
#include "main/core.h"
#include "brw_context.h"
}
#include "glsl/ir.h"
#include "glsl/ir_visitor.h"
#include "glsl/ir_rvalue_visitor.h"
#include "glsl/glsl_types.h"

static bool debug = false;

class variable_entry : public exec_node
{
public:
   variable_entry(ir_variable *var)
   {
      this->var = var;
      this->whole_vector_access = 0;
      this->declaration = false;
      this->mem_ctx = NULL;
   }

   ir_variable *var; /* The key: the variable's pointer. */

   /** Number of times the variable is referenced, including assignments. */
   unsigned whole_vector_access;

   bool declaration; /* If the variable had a decl in the instruction stream */

   ir_variable *components[4];

   /** ralloc_parent(this->var) -- the shader's ralloc context. */
   void *mem_ctx;
};

class ir_vector_reference_visitor : public ir_hierarchical_visitor {
public:
   ir_vector_reference_visitor(void)
   {
      this->mem_ctx = ralloc_context(NULL);
      this->variable_list.make_empty();
   }

   ~ir_vector_reference_visitor(void)
   {
      ralloc_free(mem_ctx);
   }

   virtual ir_visitor_status visit(ir_variable *);
   virtual ir_visitor_status visit(ir_dereference_variable *);
   virtual ir_visitor_status visit_enter(ir_swizzle *);
   virtual ir_visitor_status visit_enter(ir_assignment *);
   virtual ir_visitor_status visit_enter(ir_function_signature *);

   variable_entry *get_variable_entry(ir_variable *var);

   /* List of variable_entry */
   exec_list variable_list;

   void *mem_ctx;
};

variable_entry *
ir_vector_reference_visitor::get_variable_entry(ir_variable *var)
{
   assert(var);

   if (!var->type->is_vector())
      return NULL;

   switch (var->mode) {
   case ir_var_uniform:
   case ir_var_shader_in:
   case ir_var_shader_out:
   case ir_var_system_value:
   case ir_var_function_in:
   case ir_var_function_out:
   case ir_var_function_inout:
      /* Can't split varyings or uniforms.  Function in/outs won't get split
       * either.
       */
      return NULL;
   case ir_var_auto:
   case ir_var_temporary:
      break;
   }

   foreach_list(node, &this->variable_list) {
      variable_entry *entry = (variable_entry *)node;
      if (entry->var == var)
	 return entry;
   }

   variable_entry *entry = new(mem_ctx) variable_entry(var);
   this->variable_list.push_tail(entry);
   return entry;
}

ir_visitor_status
ir_vector_reference_visitor::visit(ir_variable *ir)
{
   variable_entry *entry = this->get_variable_entry(ir);

   if (entry)
      entry->declaration = true;

   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit(ir_dereference_variable *ir)
{
   ir_variable *const var = ir->var;
   variable_entry *entry = this->get_variable_entry(var);

   if (entry)
      entry->whole_vector_access++;

   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit_enter(ir_swizzle *ir)
{
   /* Don't descend into a vector ir_dereference_variable below. */
   if (ir->val->as_dereference_variable() && ir->type->is_scalar())
      return visit_continue_with_parent;

   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit_enter(ir_assignment *ir)
{
   if (ir->lhs->as_dereference_variable() &&
       ir->rhs->as_dereference_variable() &&
       !ir->condition) {
      /* We'll split copies of a vector to copies of channels, so don't
       * descend to the ir_dereference_variables.
       */
      return visit_continue_with_parent;
   }
   if (ir->lhs->as_dereference_variable() &&
       is_power_of_two(ir->write_mask) &&
       !ir->condition) {
      /* If we're writing just a channel, then channel-splitting the LHS is OK.
       */
      ir->rhs->accept(this);
      return visit_continue_with_parent;
   }
   return visit_continue;
}

ir_visitor_status
ir_vector_reference_visitor::visit_enter(ir_function_signature *ir)
{
   /* We don't want to descend into the function parameters and
    * split them, so just accept the body here.
    */
   visit_list_elements(this, &ir->body);
   return visit_continue_with_parent;
}

class ir_vector_splitting_visitor : public ir_rvalue_visitor {
public:
   ir_vector_splitting_visitor(exec_list *vars)
   {
      this->variable_list = vars;
   }

   virtual ir_visitor_status visit_leave(ir_assignment *);

   void handle_rvalue(ir_rvalue **rvalue);
   variable_entry *get_splitting_entry(ir_variable *var);

   exec_list *variable_list;
};

variable_entry *
ir_vector_splitting_visitor::get_splitting_entry(ir_variable *var)
{
   assert(var);

   if (!var->type->is_vector())
      return NULL;

   foreach_list(node, &*this->variable_list) {
      variable_entry *entry = (variable_entry *)node;
      if (entry->var == var) {
	 return entry;
      }
   }

   return NULL;
}

void
ir_vector_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
{
   if (!*rvalue)
      return;

   ir_swizzle *swiz = (*rvalue)->as_swizzle();
   if (!swiz || !swiz->type->is_scalar())
      return;

   ir_dereference_variable *deref_var = swiz->val->as_dereference_variable();
   if (!deref_var)
      return;

   variable_entry *entry = get_splitting_entry(deref_var->var);
   if (!entry)
      return;

   ir_variable *var = entry->components[swiz->mask.x];
   *rvalue = new(entry->mem_ctx) ir_dereference_variable(var);
}

ir_visitor_status
ir_vector_splitting_visitor::visit_leave(ir_assignment *ir)
{
   ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable();
   ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable();
   variable_entry *lhs = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL;
   variable_entry *rhs = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL;

   if (lhs_deref && rhs_deref && (lhs || rhs) && !ir->condition) {
      unsigned int rhs_chan = 0;

      /* Straight assignment of vector variables. */
      for (unsigned int i = 0; i < ir->lhs->type->vector_elements; i++) {
	 ir_dereference *new_lhs;
	 ir_rvalue *new_rhs;
	 void *mem_ctx = lhs ? lhs->mem_ctx : rhs->mem_ctx;
	 unsigned int writemask;

	 if (!(ir->write_mask & (1 << i)))
	    continue;

	 if (lhs) {
	    new_lhs = new(mem_ctx) ir_dereference_variable(lhs->components[i]);
	    writemask = 1;
	 } else {
	    new_lhs = ir->lhs->clone(mem_ctx, NULL);
	    writemask = 1 << i;
	 }

	 if (rhs) {
	    new_rhs =
	       new(mem_ctx) ir_dereference_variable(rhs->components[rhs_chan]);
	 } else {
	    new_rhs = new(mem_ctx) ir_swizzle(ir->rhs->clone(mem_ctx, NULL),
					      rhs_chan, 0, 0, 0, 1);
	 }

	 ir->insert_before(new(mem_ctx) ir_assignment(new_lhs,
						      new_rhs,
						      NULL, writemask));

	 rhs_chan++;
      }
      ir->remove();
   } else if (lhs) {
      void *mem_ctx = lhs->mem_ctx;
      int elem = -1;

      switch (ir->write_mask) {
      case (1 << 0):
	 elem = 0;
	 break;
      case (1 << 1):
	 elem = 1;
	 break;
      case (1 << 2):
	 elem = 2;
	 break;
      case (1 << 3):
	 elem = 3;
	 break;
      default:
	 ir->print();
	 assert(!"not reached: non-channelwise dereference of LHS.");
      }

      ir->lhs = new(mem_ctx) ir_dereference_variable(lhs->components[elem]);
      ir->write_mask = (1 << 0);

      handle_rvalue(&ir->rhs);
   } else {
      handle_rvalue(&ir->rhs);
   }

   handle_rvalue(&ir->condition);

   return visit_continue;
}

bool
brw_do_vector_splitting(exec_list *instructions)
{
   ir_vector_reference_visitor refs;

   visit_list_elements(&refs, instructions);

   /* Trim out variables we can't split. */
   foreach_list_safe(node, &refs.variable_list) {
      variable_entry *entry = (variable_entry *)node;

      if (debug) {
	 printf("vector %s@%p: decl %d, whole_access %d\n",
		entry->var->name, (void *) entry->var, entry->declaration,
		entry->whole_vector_access);
      }

      if (!entry->declaration || entry->whole_vector_access) {
	 entry->remove();
      }
   }

   if (refs.variable_list.is_empty())
      return false;

   void *mem_ctx = ralloc_context(NULL);

   /* Replace the decls of the vectors to be split with their split
    * components.
    */
   foreach_list(node, &refs.variable_list) {
      variable_entry *entry = (variable_entry *)node;
      const struct glsl_type *type;
      type = glsl_type::get_instance(entry->var->type->base_type, 1, 1);

      entry->mem_ctx = ralloc_parent(entry->var);

      for (unsigned int i = 0; i < entry->var->type->vector_elements; i++) {
	 const char *name = ralloc_asprintf(mem_ctx, "%s_%c",
					    entry->var->name,
					    "xyzw"[i]);

	 entry->components[i] = new(entry->mem_ctx) ir_variable(type, name,
								ir_var_temporary);
	 entry->var->insert_before(entry->components[i]);
      }

      entry->var->remove();
   }

   ir_vector_splitting_visitor split(&refs.variable_list);
   visit_list_elements(&split, instructions);

   ralloc_free(mem_ctx);

   return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Klaralvdalens Datakonsult AB (KDAB).
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "debug.h"

#include <QString>
#include <QDebug>

#include <iostream>

std::ostream& operator<<(std::ostream& stream, const wchar_t *input)
{
    return stream << qPrintable(QString::fromWCharArray(input));
}

QDebug operator<<(QDebug stream, const CefString& string)
{
  return stream << QString::fromStdString(string.ToString());
}

Q_LOGGING_CATEGORY(handler, "phantomjs.handler", QtWarningMsg)
Q_LOGGING_CATEGORY(print, "phantomjs.print", QtWarningMsg)
Q_LOGGING_CATEGORY(app, "phantomjs.app", QtWarningMsg)

<commit_msg>Make code compile with Qt 5.2<commit_after>// Copyright (c) 2015 Klaralvdalens Datakonsult AB (KDAB).
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "debug.h"

#include <QString>
#include <QDebug>

#include <iostream>

std::ostream& operator<<(std::ostream& stream, const wchar_t *input)
{
    return stream << qPrintable(QString::fromWCharArray(input));
}

QDebug operator<<(QDebug stream, const CefString& string)
{
  return stream << QString::fromStdString(string.ToString());
}

#if QT_VERSION >= 0x050400
#define WARNING_BY_DEFAULT , QtWarningMsg
#else
#define WARNING_BY_DEFAULT
#endif

Q_LOGGING_CATEGORY(handler, "phantomjs.handler" WARNING_BY_DEFAULT)
Q_LOGGING_CATEGORY(print, "phantomjs.print" WARNING_BY_DEFAULT)
Q_LOGGING_CATEGORY(app, "phantomjs.app" WARNING_BY_DEFAULT)
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2016 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains Template Metaprogramming (TMP) utilities
 */

#ifndef CPP_UTILS_TMP_HPP
#define CPP_UTILS_TMP_HPP

#include <tuple>
#include <utility>

#include "tmp/tmp.hpp"
#include "tmp/sfinae.hpp"
#include "tmp/variadic.hpp"

namespace cpp {

namespace tmp_detail {

    /*!
     * \brief Helper Traits to test if all the types from I to N in
     * T are homogeneous
     */
template <std::size_t I, std::size_t S, typename F, typename... T>
struct is_homogeneous_helper {
    /*!
     * \brief Sub helper for recursive instantiations
     */
    template <std::size_t I1, std::size_t S1, typename Enable = void>
    struct helper_int : and_helper<std::is_same<F, nth_type_t<I1, T...>>::value, is_homogeneous_helper<I1 + 1, S1, F, T...>::value> {};

    /*!
     * \copydoc helper_int
     */
    template <std::size_t I1, std::size_t S1>
    struct helper_int<I1, S1, std::enable_if_t<I1 == S1>> : std::is_same<F, nth_type_t<I1, T...>> {};

    static constexpr const auto value = helper_int<I, S>::value; ///< Indicates if the sequence of types is homogeneous
};

} //end of namespace tmp_detail

/*!
 * \brief Implementation of helper for for_each_tuple_t
 */
template <int I, typename Tuple, typename Functor>
struct for_each_tuple_t_impl {
    /*!
     * \brief Apply the functof for each elements in the tuple, from I
     */
    static void for_each(Functor&& func) {
        std::forward<Functor>(func).template operator()<typename std::tuple_element<I, Tuple>::type>();
        for_each_tuple_t_impl<I - 1, Tuple, Functor>::for_each(std::forward<Functor>(func));
    }
};

/*!
 * \copydoc for_each_tuple_t_impl
 */
template <typename Tuple, typename Functor>
struct for_each_tuple_t_impl<0, Tuple, Functor> {
    /*!
     * \brief Apply the functof for each elements in the tuple, from I
     */
    static void for_each(Functor&& func) {
        std::forward<Functor>(func).template operator()<typename std::tuple_element<0, Tuple>::type>();
    }
};

/*!
 * \copydoc for_each_tuple_t_impl
 */
template <typename Tuple, typename Functor>
struct for_each_tuple_t_impl<-1, Tuple, Functor> {
    /*!
     * \brief End of the the recursion
     */
    static void for_each(Functor&& /*func*/) {
        //Nothing to be done
    }
};

/*!
 * \brief Call the given functor for each type in the tuple
 * \tparam Tuple The tuple type
 * \param func The functor to call
 */
template <typename Tuple, typename Functor>
void for_each_tuple_t(Functor&& func) {
    for_each_tuple_t_impl<static_cast<int>(std::tuple_size<Tuple>::value) - 1, Tuple, Functor>::for_each(std::forward<Functor>(func));
}

/*!
 * \brief Traits to test if a type is a specialization of a template
 * \tparam TT The template type
 * \tparam T The type to test
 */
template <template <typename...> class TT, typename T>
struct is_specialization_of : std::false_type {};

/*!
 * \copydoc is_specialization_of
 */
template <template <typename...> class TT, typename... Args>
struct is_specialization_of<TT, TT<Args...>> : std::true_type {};

/*!
 * \brief Traits to test if all the given types are convertible to V
 * \tparam V The target type
 * \tparam F The first type to test
 * \tparam S The types to test
 */
template <typename V, typename F, typename... S>
struct all_convertible_to : bool_constant_c<and_c<all_convertible_to<V, F>, all_convertible_to<V, S...>>> {};

/*!
 * \copydoc all_convertible_to
 */
template <typename V, typename F>
struct all_convertible_to<V, F> : bool_constant_c<std::is_convertible<F, V>> {};

/*!
 * \brief Test is a list of types homogeneous
 * \tparam F The first type
 * \tparam T The types
 */
template <typename F, typename... T>
struct is_homogeneous : bool_constant_c<tmp_detail::is_homogeneous_helper<0, sizeof...(T)-1, F, T...>> {};

/*!
 * \copydoc all_convertible_to
 */
template <typename F>
struct is_homogeneous<F> : std::true_type {};

/*
 * \brief Test if a list of types is sub-homogeneous
 *
 * A sub-homogeneous list of types is a list where the N-1 first types are the
 * same and the last one is different
 */
template <typename... T>
struct is_sub_homogeneous;

/*!
 * \copydoc is_sub_homogeneous
 */
template <>
struct is_sub_homogeneous<> : std::false_type {};

/*!
 * \copydoc is_sub_homogeneous
 */
template <typename T>
struct is_sub_homogeneous<T> : std::false_type {};

/*!
 * \copydoc is_sub_homogeneous
 */
template <typename T1, typename T2>
struct is_sub_homogeneous<T1, T2> : bool_constant_c<not_c<std::is_same<T1, T2>>> {};

/*!
 * \copydoc is_sub_homogeneous
 */
template <typename T1, typename T2, typename T3, typename... T>
struct is_sub_homogeneous<T1, T2, T3, T...> : bool_constant_c<
                                                  and_c<
                                                      std::is_same<T1, T2>,
                                                      is_sub_homogeneous<T2, T3, T...>>> {};

/*!
 * \brief Apply the given function to each element of the variadic
 * packs whose position is present in the sequence
 * \param f The functor
 * \param i The index sequence
 * \param args The arguments
 */
template <typename F, std::size_t I1, std::size_t... I, typename... T, enable_if_u<(sizeof...(I) == 0)> = detail::dummy>
void for_each_in_subset(F&& f, const std::index_sequence<I1, I...>& i, T&&... args) {
    f(std::forward<nth_type_t<I1, T...>>(nth_value<I1>(args...)));
    cpp_unused(i);
}

/*!
 * \brief Apply the given function to each element of the variadic
 * packs whose position is present in the sequence
 * \param f The functor
 * \param i The index sequence
 * \param args The arguments
 */
template <typename F, std::size_t I1, std::size_t... I, typename... T, enable_if_u<(sizeof...(I) > 0)> = detail::dummy>
void for_each_in_subset(F&& f, const std::index_sequence<I1, I...>& i, T&&... args) {
    f(std::forward<nth_type_t<I1, T...>>(nth_value<I1>(args...)));
    for_each_in_subset(f, std::index_sequence<I...>(), std::forward<T>(args)...);
    cpp_unused(i);
}

/*!
 * \brief Apply the given function to each element of the variadic pack
 * \param f The functor
 * \param args The arguments
 */
template <typename F, typename... T>
void for_each_in(F&& f, T&&... args) {
    for_each_in_subset(f, std::make_index_sequence<sizeof...(T)>(), std::forward<T>(args)...);
}

/*!
 * \brief Test if the variadic list of types containg the given type
 * \tparam T1 The type to search
 * \tparam T The list of types
 */
template <typename T1, typename... T>
struct variadic_contains;

/*!
 * \copydoc variadic_contains
 */
template <typename T1, typename T2, typename... T>
struct variadic_contains<T1, T2, T...> : bool_constant_c<or_c<std::is_same<T1, T2>, variadic_contains<T1, T...>>> {};

/*!
 * \copydoc variadic_contains
 */
template <typename T1>
struct variadic_contains<T1> : std::false_type {};

/*!
 * \brief A compile-time type list.
 */
template <typename... T>
struct type_list {
    /*!
     * \brief Indicates if the list contains the given type
     * \tparam V The type to search in the list
     * \return true if the type is in the list, false otherwise.
     */
    template <typename V>
    static constexpr bool contains() {
        return variadic_contains<V, T...>::value;
    }
};

} //end of namespace cpp

#endif //CPP_UTILS_TMP_HPP
<commit_msg>Add missing include<commit_after>//=======================================================================
// Copyright (c) 2013-2016 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains Template Metaprogramming (TMP) utilities
 */

#ifndef CPP_UTILS_TMP_HPP
#define CPP_UTILS_TMP_HPP

#include <tuple>
#include <utility>

#include "assert.hpp"

#include "tmp/tmp.hpp"
#include "tmp/sfinae.hpp"
#include "tmp/variadic.hpp"

namespace cpp {

namespace tmp_detail {

    /*!
     * \brief Helper Traits to test if all the types from I to N in
     * T are homogeneous
     */
template <std::size_t I, std::size_t S, typename F, typename... T>
struct is_homogeneous_helper {
    /*!
     * \brief Sub helper for recursive instantiations
     */
    template <std::size_t I1, std::size_t S1, typename Enable = void>
    struct helper_int : and_helper<std::is_same<F, nth_type_t<I1, T...>>::value, is_homogeneous_helper<I1 + 1, S1, F, T...>::value> {};

    /*!
     * \copydoc helper_int
     */
    template <std::size_t I1, std::size_t S1>
    struct helper_int<I1, S1, std::enable_if_t<I1 == S1>> : std::is_same<F, nth_type_t<I1, T...>> {};

    static constexpr const auto value = helper_int<I, S>::value; ///< Indicates if the sequence of types is homogeneous
};

} //end of namespace tmp_detail

/*!
 * \brief Implementation of helper for for_each_tuple_t
 */
template <int I, typename Tuple, typename Functor>
struct for_each_tuple_t_impl {
    /*!
     * \brief Apply the functof for each elements in the tuple, from I
     */
    static void for_each(Functor&& func) {
        std::forward<Functor>(func).template operator()<typename std::tuple_element<I, Tuple>::type>();
        for_each_tuple_t_impl<I - 1, Tuple, Functor>::for_each(std::forward<Functor>(func));
    }
};

/*!
 * \copydoc for_each_tuple_t_impl
 */
template <typename Tuple, typename Functor>
struct for_each_tuple_t_impl<0, Tuple, Functor> {
    /*!
     * \brief Apply the functof for each elements in the tuple, from I
     */
    static void for_each(Functor&& func) {
        std::forward<Functor>(func).template operator()<typename std::tuple_element<0, Tuple>::type>();
    }
};

/*!
 * \copydoc for_each_tuple_t_impl
 */
template <typename Tuple, typename Functor>
struct for_each_tuple_t_impl<-1, Tuple, Functor> {
    /*!
     * \brief End of the the recursion
     */
    static void for_each(Functor&& /*func*/) {
        //Nothing to be done
    }
};

/*!
 * \brief Call the given functor for each type in the tuple
 * \tparam Tuple The tuple type
 * \param func The functor to call
 */
template <typename Tuple, typename Functor>
void for_each_tuple_t(Functor&& func) {
    for_each_tuple_t_impl<static_cast<int>(std::tuple_size<Tuple>::value) - 1, Tuple, Functor>::for_each(std::forward<Functor>(func));
}

/*!
 * \brief Traits to test if a type is a specialization of a template
 * \tparam TT The template type
 * \tparam T The type to test
 */
template <template <typename...> class TT, typename T>
struct is_specialization_of : std::false_type {};

/*!
 * \copydoc is_specialization_of
 */
template <template <typename...> class TT, typename... Args>
struct is_specialization_of<TT, TT<Args...>> : std::true_type {};

/*!
 * \brief Traits to test if all the given types are convertible to V
 * \tparam V The target type
 * \tparam F The first type to test
 * \tparam S The types to test
 */
template <typename V, typename F, typename... S>
struct all_convertible_to : bool_constant_c<and_c<all_convertible_to<V, F>, all_convertible_to<V, S...>>> {};

/*!
 * \copydoc all_convertible_to
 */
template <typename V, typename F>
struct all_convertible_to<V, F> : bool_constant_c<std::is_convertible<F, V>> {};

/*!
 * \brief Test is a list of types homogeneous
 * \tparam F The first type
 * \tparam T The types
 */
template <typename F, typename... T>
struct is_homogeneous : bool_constant_c<tmp_detail::is_homogeneous_helper<0, sizeof...(T)-1, F, T...>> {};

/*!
 * \copydoc all_convertible_to
 */
template <typename F>
struct is_homogeneous<F> : std::true_type {};

/*
 * \brief Test if a list of types is sub-homogeneous
 *
 * A sub-homogeneous list of types is a list where the N-1 first types are the
 * same and the last one is different
 */
template <typename... T>
struct is_sub_homogeneous;

/*!
 * \copydoc is_sub_homogeneous
 */
template <>
struct is_sub_homogeneous<> : std::false_type {};

/*!
 * \copydoc is_sub_homogeneous
 */
template <typename T>
struct is_sub_homogeneous<T> : std::false_type {};

/*!
 * \copydoc is_sub_homogeneous
 */
template <typename T1, typename T2>
struct is_sub_homogeneous<T1, T2> : bool_constant_c<not_c<std::is_same<T1, T2>>> {};

/*!
 * \copydoc is_sub_homogeneous
 */
template <typename T1, typename T2, typename T3, typename... T>
struct is_sub_homogeneous<T1, T2, T3, T...> : bool_constant_c<
                                                  and_c<
                                                      std::is_same<T1, T2>,
                                                      is_sub_homogeneous<T2, T3, T...>>> {};

/*!
 * \brief Apply the given function to each element of the variadic
 * packs whose position is present in the sequence
 * \param f The functor
 * \param i The index sequence
 * \param args The arguments
 */
template <typename F, std::size_t I1, std::size_t... I, typename... T, enable_if_u<(sizeof...(I) == 0)> = detail::dummy>
void for_each_in_subset(F&& f, const std::index_sequence<I1, I...>& i, T&&... args) {
    f(std::forward<nth_type_t<I1, T...>>(nth_value<I1>(args...)));
    cpp_unused(i);
}

/*!
 * \brief Apply the given function to each element of the variadic
 * packs whose position is present in the sequence
 * \param f The functor
 * \param i The index sequence
 * \param args The arguments
 */
template <typename F, std::size_t I1, std::size_t... I, typename... T, enable_if_u<(sizeof...(I) > 0)> = detail::dummy>
void for_each_in_subset(F&& f, const std::index_sequence<I1, I...>& i, T&&... args) {
    f(std::forward<nth_type_t<I1, T...>>(nth_value<I1>(args...)));
    for_each_in_subset(f, std::index_sequence<I...>(), std::forward<T>(args)...);
    cpp_unused(i);
}

/*!
 * \brief Apply the given function to each element of the variadic pack
 * \param f The functor
 * \param args The arguments
 */
template <typename F, typename... T>
void for_each_in(F&& f, T&&... args) {
    for_each_in_subset(f, std::make_index_sequence<sizeof...(T)>(), std::forward<T>(args)...);
}

/*!
 * \brief Test if the variadic list of types containg the given type
 * \tparam T1 The type to search
 * \tparam T The list of types
 */
template <typename T1, typename... T>
struct variadic_contains;

/*!
 * \copydoc variadic_contains
 */
template <typename T1, typename T2, typename... T>
struct variadic_contains<T1, T2, T...> : bool_constant_c<or_c<std::is_same<T1, T2>, variadic_contains<T1, T...>>> {};

/*!
 * \copydoc variadic_contains
 */
template <typename T1>
struct variadic_contains<T1> : std::false_type {};

/*!
 * \brief A compile-time type list.
 */
template <typename... T>
struct type_list {
    /*!
     * \brief Indicates if the list contains the given type
     * \tparam V The type to search in the list
     * \return true if the type is in the list, false otherwise.
     */
    template <typename V>
    static constexpr bool contains() {
        return variadic_contains<V, T...>::value;
    }
};

} //end of namespace cpp

#endif //CPP_UTILS_TMP_HPP
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://www.qt.io/licensing.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "jsonwizard.h"

#include "jsonwizardgeneratorfactory.h"

#include <utils/algorithm.h>
#include <utils/qtcassert.h>

#include <QFileInfo>
#include <QMessageBox>
#include <QVariant>

namespace ProjectExplorer {

JsonWizard::JsonWizard(QWidget *parent) :
    Utils::Wizard(parent)
{
    m_expander.registerExtraResolver([this](const QString &name, QString *ret) -> bool {
        QVariant v = value(name);
        if (v.isValid()) {
            if (v.type() == QVariant::Bool)
                *ret = v.toBool() ? QLatin1String("true") : QString();
            else
                *ret = v.toString();
        }
        return v.isValid();
    });
    m_expander.registerPrefix("Exists", tr("Check whether a variable exists. Returns \"true\" if it does and an empty string if not."),
                   [this](const QString &value) -> QString
    {
        const QString key = QString::fromLatin1("%{") + value + QLatin1Char('}');
        return m_expander.expand(key) == key ? QString() : QLatin1String("true");
    });

}

JsonWizard::~JsonWizard()
{
    qDeleteAll(m_generators);
}

void JsonWizard::addGenerator(JsonWizardGenerator *gen)
{
    QTC_ASSERT(gen, return);
    QTC_ASSERT(!m_generators.contains(gen), return);

    m_generators.append(gen);
}

Utils::MacroExpander *JsonWizard::expander()
{
    return &m_expander;
}

void JsonWizard::resetFileList()
{
    m_files.clear();
}

JsonWizard::GeneratorFiles JsonWizard::fileList()
{
    QString errorMessage;
    GeneratorFiles list;

    QString targetPath = value(QLatin1String("TargetPath")).toString();
    if (targetPath.isEmpty()) {
        errorMessage = tr("Could not determine target path. \"TargetPath\" was not set on any page.");
        return list;
    }

    if (m_files.isEmpty()) {
        emit preGenerateFiles();
        foreach (JsonWizardGenerator *gen, m_generators) {
            Core::GeneratedFiles tmp = gen->fileList(&m_expander, value(QStringLiteral("WizardDir")).toString(),
                                                     targetPath, &errorMessage);
            if (!errorMessage.isEmpty())
                break;
            list.append(Utils::transform(tmp, [&gen](const Core::GeneratedFile &f)
                                              { return JsonWizard::GeneratorFile(f, gen); }));
        }

        if (errorMessage.isEmpty())
            m_files = list;
        emit postGenerateFiles(m_files);
    }

    if (!errorMessage.isEmpty()) {
        QMessageBox::critical(this, tr("File Generation Failed"),
                              tr("The wizard failed to generate files.
"
                                 "The error message was: \"%1\".").arg(errorMessage));
        reject();
        return GeneratorFiles();
    }

    return m_files;
}

QVariant JsonWizard::value(const QString &n) const
{
    QVariant v = property(n.toUtf8());
    if (v.isValid()) {
        if (v.type() == QVariant::String)
            return m_expander.expand(v.toString());
        else
            return v;
    }
    if (hasField(n))
        return field(n); // Can not contain macros!
    return QVariant();
}

void JsonWizard::setValue(const QString &key, const QVariant &value)
{
    setProperty(key.toUtf8(), value);
}

bool JsonWizard::boolFromVariant(const QVariant &v, Utils::MacroExpander *expander)
{
    if (v.type() == QVariant::String)
        return !expander->expand(v.toString()).isEmpty();
    return v.toBool();
}

void JsonWizard::removeAttributeFromAllFiles(Core::GeneratedFile::Attribute a)
{
    for (int i = 0; i < m_files.count(); ++i)
        m_files[i].file.setAttributes(m_files.at(i).file.attributes() ^ a);
}

void JsonWizard::accept()
{
    Utils::Wizard::accept();

    QString errorMessage;
    GeneratorFiles list = fileList();

    if (list.isEmpty())
        return;

    emit prePromptForOverwrite(m_files);
    JsonWizardGenerator::OverwriteResult overwrite =
            JsonWizardGenerator::promptForOverwrite(&list, &errorMessage);
    if (overwrite == JsonWizardGenerator::OverwriteError) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Overwrite Files"), errorMessage);
        return;
    }

    emit preFormatFiles(m_files);
    if (!JsonWizardGenerator::formatFiles(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Format Files"), errorMessage);
        return;
    }

    emit preWriteFiles(m_files);
    if (!JsonWizardGenerator::writeFiles(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Write Files"), errorMessage);
        return;
    }

    emit postProcessFiles(m_files);
    if (!JsonWizardGenerator::postWrite(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Post-Process Files"), errorMessage);
        return;
    }
    emit filesReady(m_files);
    if (!JsonWizardGenerator::allDone(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Open Files"), errorMessage);
        return;
    }

    emit allDone(m_files);
}

} // namespace ProjectExplorer
<commit_msg>JsonWizard: Force minimum size to something sensible<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://www.qt.io/licensing.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "jsonwizard.h"

#include "jsonwizardgeneratorfactory.h"

#include <utils/algorithm.h>
#include <utils/qtcassert.h>

#include <QFileInfo>
#include <QMessageBox>
#include <QVariant>

namespace ProjectExplorer {

JsonWizard::JsonWizard(QWidget *parent) :
    Utils::Wizard(parent)
{
    setMinimumSize(800, 500);
    m_expander.registerExtraResolver([this](const QString &name, QString *ret) -> bool {
        QVariant v = value(name);
        if (v.isValid()) {
            if (v.type() == QVariant::Bool)
                *ret = v.toBool() ? QLatin1String("true") : QString();
            else
                *ret = v.toString();
        }
        return v.isValid();
    });
    m_expander.registerPrefix("Exists", tr("Check whether a variable exists. Returns \"true\" if it does and an empty string if not."),
                   [this](const QString &value) -> QString
    {
        const QString key = QString::fromLatin1("%{") + value + QLatin1Char('}');
        return m_expander.expand(key) == key ? QString() : QLatin1String("true");
    });

}

JsonWizard::~JsonWizard()
{
    qDeleteAll(m_generators);
}

void JsonWizard::addGenerator(JsonWizardGenerator *gen)
{
    QTC_ASSERT(gen, return);
    QTC_ASSERT(!m_generators.contains(gen), return);

    m_generators.append(gen);
}

Utils::MacroExpander *JsonWizard::expander()
{
    return &m_expander;
}

void JsonWizard::resetFileList()
{
    m_files.clear();
}

JsonWizard::GeneratorFiles JsonWizard::fileList()
{
    QString errorMessage;
    GeneratorFiles list;

    QString targetPath = value(QLatin1String("TargetPath")).toString();
    if (targetPath.isEmpty()) {
        errorMessage = tr("Could not determine target path. \"TargetPath\" was not set on any page.");
        return list;
    }

    if (m_files.isEmpty()) {
        emit preGenerateFiles();
        foreach (JsonWizardGenerator *gen, m_generators) {
            Core::GeneratedFiles tmp = gen->fileList(&m_expander, value(QStringLiteral("WizardDir")).toString(),
                                                     targetPath, &errorMessage);
            if (!errorMessage.isEmpty())
                break;
            list.append(Utils::transform(tmp, [&gen](const Core::GeneratedFile &f)
                                              { return JsonWizard::GeneratorFile(f, gen); }));
        }

        if (errorMessage.isEmpty())
            m_files = list;
        emit postGenerateFiles(m_files);
    }

    if (!errorMessage.isEmpty()) {
        QMessageBox::critical(this, tr("File Generation Failed"),
                              tr("The wizard failed to generate files.
"
                                 "The error message was: \"%1\".").arg(errorMessage));
        reject();
        return GeneratorFiles();
    }

    return m_files;
}

QVariant JsonWizard::value(const QString &n) const
{
    QVariant v = property(n.toUtf8());
    if (v.isValid()) {
        if (v.type() == QVariant::String)
            return m_expander.expand(v.toString());
        else
            return v;
    }
    if (hasField(n))
        return field(n); // Can not contain macros!
    return QVariant();
}

void JsonWizard::setValue(const QString &key, const QVariant &value)
{
    setProperty(key.toUtf8(), value);
}

bool JsonWizard::boolFromVariant(const QVariant &v, Utils::MacroExpander *expander)
{
    if (v.type() == QVariant::String)
        return !expander->expand(v.toString()).isEmpty();
    return v.toBool();
}

void JsonWizard::removeAttributeFromAllFiles(Core::GeneratedFile::Attribute a)
{
    for (int i = 0; i < m_files.count(); ++i)
        m_files[i].file.setAttributes(m_files.at(i).file.attributes() ^ a);
}

void JsonWizard::accept()
{
    Utils::Wizard::accept();

    QString errorMessage;
    GeneratorFiles list = fileList();

    if (list.isEmpty())
        return;

    emit prePromptForOverwrite(m_files);
    JsonWizardGenerator::OverwriteResult overwrite =
            JsonWizardGenerator::promptForOverwrite(&list, &errorMessage);
    if (overwrite == JsonWizardGenerator::OverwriteError) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Overwrite Files"), errorMessage);
        return;
    }

    emit preFormatFiles(m_files);
    if (!JsonWizardGenerator::formatFiles(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Format Files"), errorMessage);
        return;
    }

    emit preWriteFiles(m_files);
    if (!JsonWizardGenerator::writeFiles(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Write Files"), errorMessage);
        return;
    }

    emit postProcessFiles(m_files);
    if (!JsonWizardGenerator::postWrite(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Post-Process Files"), errorMessage);
        return;
    }
    emit filesReady(m_files);
    if (!JsonWizardGenerator::allDone(this, &list, &errorMessage)) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Open Files"), errorMessage);
        return;
    }

    emit allDone(m_files);
}

} // namespace ProjectExplorer
<|endoftext|>


<commit_before>/**************************************************************************
**
** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved.
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "blackberryrunconfigurationfactory.h"
#include "qnxconstants.h"
#include "blackberryrunconfiguration.h"
#include "blackberrydeviceconfigurationfactory.h"

#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <qmakeprojectmanager/qmakenodes.h>

using namespace Qnx;
using namespace Qnx::Internal;

static QString pathFromId(Core::Id id)
{
    return id.suffixAfter(Constants::QNX_BB_RUNCONFIGURATION_PREFIX);
}

BlackBerryRunConfigurationFactory::BlackBerryRunConfigurationFactory(QObject *parent) :
    ProjectExplorer::IRunConfigurationFactory(parent)
{
}

QList<Core::Id> BlackBerryRunConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent, CreationMode mode) const
{
    using QmakeProjectManager::QmakeProject;
    if (!canHandle(parent))
        return QList<Core::Id>();

    QmakeProject *qt4Project = qobject_cast<QmakeProject *>(parent->project());
    if (!qt4Project)
        return QList<Core::Id>();

    QList<QmakeProjectManager::QmakeProFileNode *>  nodes = qt4Project->applicationProFiles();
    if (mode == AutoCreate)
        nodes = QmakeProject::nodesWithQtcRunnable(nodes);
    return QmakeProject::idsForNodes(Core::Id(Constants::QNX_QNX_RUNCONFIGURATION_PREFIX),
                                     nodes);
}

QString BlackBerryRunConfigurationFactory::displayNameForId(Core::Id id) const
{
    const QString path = pathFromId(id);
    if (path.isEmpty())
        return QString();

    if (id.name().startsWith(Constants::QNX_BB_RUNCONFIGURATION_PREFIX))
        return QFileInfo(path).completeBaseName();

    return QString();
}

bool BlackBerryRunConfigurationFactory::canCreate(ProjectExplorer::Target *parent, Core::Id id) const
{
    if (!canHandle(parent))
        return false;

    QmakeProjectManager::QmakeProject *qt4Project = qobject_cast<QmakeProjectManager::QmakeProject *>(parent->project());
    if (!qt4Project)
        return false;

    if (!id.name().startsWith(Constants::QNX_BB_RUNCONFIGURATION_PREFIX))
        return false;

    return qt4Project->hasApplicationProFile(pathFromId(id));
}

ProjectExplorer::RunConfiguration *BlackBerryRunConfigurationFactory::doCreate(ProjectExplorer::Target *parent,
                                                                      const Core::Id id)
{
    return new BlackBerryRunConfiguration(parent, id, pathFromId(id));
}

bool BlackBerryRunConfigurationFactory::canRestore(ProjectExplorer::Target *parent,
                                            const QVariantMap &map) const
{
    if (!canHandle(parent))
        return false;

    return ProjectExplorer::idFromMap(map).name().startsWith(Constants::QNX_BB_RUNCONFIGURATION_PREFIX);
}

ProjectExplorer::RunConfiguration *BlackBerryRunConfigurationFactory::doRestore(
        ProjectExplorer::Target *parent,
        const QVariantMap &map)
{
    Q_UNUSED(map);
    return new BlackBerryRunConfiguration(parent, Core::Id(Constants::QNX_BB_RUNCONFIGURATION_PREFIX), QString());
}

bool BlackBerryRunConfigurationFactory::canClone(ProjectExplorer::Target *parent,
                                          ProjectExplorer::RunConfiguration *source) const
{
    return canCreate(parent, source->id());
}

ProjectExplorer::RunConfiguration *BlackBerryRunConfigurationFactory::clone(
        ProjectExplorer::Target *parent,
        ProjectExplorer::RunConfiguration *source)
{
    if (!canClone(parent, source))
        return 0;

    BlackBerryRunConfiguration *old = static_cast<BlackBerryRunConfiguration *>(source);
    return new BlackBerryRunConfiguration(parent, old);

}

bool BlackBerryRunConfigurationFactory::canHandle(ProjectExplorer::Target *t) const
{
    if (!t->project()->supportsKit(t->kit()))
        return false;
    if (!qobject_cast<QmakeProjectManager::QmakeProject *>(t->project()))
        return false;

    Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(t->kit());
    if (deviceType != BlackBerryDeviceConfigurationFactory::deviceType())
        return false;

    return true;
}
<commit_msg>Qnx: Fix the Id for the BlackBerry run configuration<commit_after>/**************************************************************************
**
** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved.
**
** Contact: BlackBerry (qt@blackberry.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "blackberryrunconfigurationfactory.h"
#include "qnxconstants.h"
#include "blackberryrunconfiguration.h"
#include "blackberrydeviceconfigurationfactory.h"

#include <projectexplorer/kitinformation.h>
#include <projectexplorer/target.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <qmakeprojectmanager/qmakenodes.h>

using namespace Qnx;
using namespace Qnx::Internal;

static QString pathFromId(Core::Id id)
{
    return id.suffixAfter(Constants::QNX_BB_RUNCONFIGURATION_PREFIX);
}

BlackBerryRunConfigurationFactory::BlackBerryRunConfigurationFactory(QObject *parent) :
    ProjectExplorer::IRunConfigurationFactory(parent)
{
}

QList<Core::Id> BlackBerryRunConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent, CreationMode mode) const
{
    using QmakeProjectManager::QmakeProject;
    if (!canHandle(parent))
        return QList<Core::Id>();

    QmakeProject *qt4Project = qobject_cast<QmakeProject *>(parent->project());
    if (!qt4Project)
        return QList<Core::Id>();

    QList<QmakeProjectManager::QmakeProFileNode *>  nodes = qt4Project->applicationProFiles();
    if (mode == AutoCreate)
        nodes = QmakeProject::nodesWithQtcRunnable(nodes);
    return QmakeProject::idsForNodes(Core::Id(Constants::QNX_BB_RUNCONFIGURATION_PREFIX),
                                     nodes);
}

QString BlackBerryRunConfigurationFactory::displayNameForId(Core::Id id) const
{
    const QString path = pathFromId(id);
    if (path.isEmpty())
        return QString();

    if (id.name().startsWith(Constants::QNX_BB_RUNCONFIGURATION_PREFIX))
        return QFileInfo(path).completeBaseName();

    return QString();
}

bool BlackBerryRunConfigurationFactory::canCreate(ProjectExplorer::Target *parent, Core::Id id) const
{
    if (!canHandle(parent))
        return false;

    QmakeProjectManager::QmakeProject *qt4Project = qobject_cast<QmakeProjectManager::QmakeProject *>(parent->project());
    if (!qt4Project)
        return false;

    if (!id.name().startsWith(Constants::QNX_BB_RUNCONFIGURATION_PREFIX))
        return false;

    return qt4Project->hasApplicationProFile(pathFromId(id));
}

ProjectExplorer::RunConfiguration *BlackBerryRunConfigurationFactory::doCreate(ProjectExplorer::Target *parent,
                                                                      const Core::Id id)
{
    return new BlackBerryRunConfiguration(parent, id, pathFromId(id));
}

bool BlackBerryRunConfigurationFactory::canRestore(ProjectExplorer::Target *parent,
                                            const QVariantMap &map) const
{
    if (!canHandle(parent))
        return false;

    return ProjectExplorer::idFromMap(map).name().startsWith(Constants::QNX_BB_RUNCONFIGURATION_PREFIX);
}

ProjectExplorer::RunConfiguration *BlackBerryRunConfigurationFactory::doRestore(
        ProjectExplorer::Target *parent,
        const QVariantMap &map)
{
    Q_UNUSED(map);
    return new BlackBerryRunConfiguration(parent, Core::Id(Constants::QNX_BB_RUNCONFIGURATION_PREFIX), QString());
}

bool BlackBerryRunConfigurationFactory::canClone(ProjectExplorer::Target *parent,
                                          ProjectExplorer::RunConfiguration *source) const
{
    return canCreate(parent, source->id());
}

ProjectExplorer::RunConfiguration *BlackBerryRunConfigurationFactory::clone(
        ProjectExplorer::Target *parent,
        ProjectExplorer::RunConfiguration *source)
{
    if (!canClone(parent, source))
        return 0;

    BlackBerryRunConfiguration *old = static_cast<BlackBerryRunConfiguration *>(source);
    return new BlackBerryRunConfiguration(parent, old);

}

bool BlackBerryRunConfigurationFactory::canHandle(ProjectExplorer::Target *t) const
{
    if (!t->project()->supportsKit(t->kit()))
        return false;
    if (!qobject_cast<QmakeProjectManager::QmakeProject *>(t->project()))
        return false;

    Core::Id deviceType = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(t->kit());
    if (deviceType != BlackBerryDeviceConfigurationFactory::deviceType())
        return false;

    return true;
}
<|endoftext|>


<commit_before>/*
 * 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.
 *
 * Written (W) 2012 Fernando José Iglesias García
 * Copyright (C) 2012 Fernando José Iglesias García
 */

#include <shogun/converter/StochasticProximityEmbedding.h>
#include <shogun/lib/config.h>
#ifdef HAVE_LAPACK
#include <shogun/converter/EmbeddingConverter.h>
#include <shogun/io/SGIO.h>
#include <shogun/lib/CoverTree.h>
#include <shogun/mathematics/Math.h>
#include <shogun/distance/Distance.h>

using namespace shogun;

class SPE_COVERTREE_POINT
{
public:

	SPE_COVERTREE_POINT(int32_t index, const SGMatrix<float64_t>& dmatrix)
	{
		point_index = index;
		distance_matrix = dmatrix;
	}

	inline double distance(const SPE_COVERTREE_POINT& p) const
	{
		return distance_matrix[point_index*distance_matrix.num_rows+p.point_index];
	}

	inline bool operator==(const SPE_COVERTREE_POINT& p) const
	{
		return (p.point_index==point_index);
	}

	int32_t point_index;
	SGMatrix<float64_t> distance_matrix;
};

CStochasticProximityEmbedding::CStochasticProximityEmbedding() :
	CEmbeddingConverter()
{
	// Initialize to default values
	m_k         = 12;
	m_nupdates  = 100;
	m_strategy  = SPE_GLOBAL;
	m_tolerance = 1e-5;

	init();
}

void CStochasticProximityEmbedding::init()
{
	SG_ADD(&m_k, "m_k", "Number of neighbors", MS_NOT_AVAILABLE);
	SG_ADD((machine_int_t*) &m_strategy, "m_strategy", "SPE strategy",
			MS_NOT_AVAILABLE);
	SG_ADD(&m_tolerance, "m_tolerance", "Regularization parameter",
			MS_NOT_AVAILABLE);
}

CStochasticProximityEmbedding::~CStochasticProximityEmbedding()
{
}

void CStochasticProximityEmbedding::set_k(int32_t k)
{
	if ( k <= 0 )
		SG_ERROR("Number of neighbors k must be greater than 0");

	m_k = k;
}

int32_t CStochasticProximityEmbedding::get_k() const
{
	return m_k;
}

void CStochasticProximityEmbedding::set_strategy(ESPEStrategy strategy)
{
	m_strategy = strategy;
}

ESPEStrategy CStochasticProximityEmbedding::get_strategy() const
{
	return m_strategy;
}

void CStochasticProximityEmbedding::set_tolerance(float32_t tolerance)
{
	if ( tolerance <= 0 )
		SG_ERROR("Tolerance regularization parameter must be greater "
			 "than 0");

	m_tolerance = tolerance;
}

int32_t CStochasticProximityEmbedding::get_tolerance() const
{
	return m_tolerance;
}

void CStochasticProximityEmbedding::set_nupdates(int32_t nupdates)
{
	if ( nupdates <= 0 )
		SG_ERROR("The number of updates must be greater than 0");

	m_nupdates = nupdates;
}

int32_t CStochasticProximityEmbedding::get_nupdates() const
{
	return m_nupdates;
}

const char * CStochasticProximityEmbedding::get_name() const
{
	return "StochasticProximityEmbedding";
}

CFeatures* CStochasticProximityEmbedding::apply(CFeatures* features)
{
	if ( !features )
		SG_ERROR("Features are required to apply SPE\n");

	if ( !(features->get_feature_class() == C_SIMPLE &&
	       features->get_feature_type()  == F_DREAL) )
		SG_ERROR("Features must be dense real features\n");

	// Shorthand for the SimpleFeatures
	CSimpleFeatures< float64_t >* simple_features =
		(CSimpleFeatures< float64_t >*) features;
	SG_REF(features);

	// Get and check the number of vectors
	int32_t N = simple_features->get_num_vectors();
	if ( m_strategy == SPE_LOCAL && m_k >= N )
		SG_ERROR("The number of neighbors (%d) must be less than "
		         "the number of vectors (%d)\n", m_k, N);

	if ( 2*m_nupdates > N )
		SG_ERROR("The number of vectors (%d) must be at least two times "
			 "the number of updates (%d)\n", N, m_nupdates);

	// Compute distance matrix
	SG_DEBUG("Computing distance matrix\n");

	if ( m_distance->get_distance_type() != D_EUCLIDIAN )
		SG_ERROR("SPE only supports Euclidian distance, %s given\n",
				m_distance->get_name());

	m_distance->init(simple_features, simple_features);
	SGMatrix< float64_t > distance_matrix = m_distance->get_distance_matrix();
	m_distance->remove_lhs_and_rhs();

	// Normalize the distance matrix if global strategy used
	if ( m_strategy == SPE_GLOBAL )
	{
		float64_t alpha = 1.0 / CMath::max(distance_matrix.matrix, N*N)
					* CMath::sqrt(2.0);
		CMath::scale_vector(alpha, distance_matrix.matrix, N*N);
	}

	// Compute neighborhood matrix if local strategy used
	SGMatrix< int32_t > neighbors_mat;
	if ( m_strategy == SPE_LOCAL )
	{
		SG_DEBUG("Computing neighborhood matrix\n");
		neighbors_mat = get_neighborhood_matrix(distance_matrix, m_k);
	}

	// Initialize vectors in the embedded space randomly, Y is the short for
	// new_feature_matrix
	SGMatrix< float64_t > Y(m_target_dim, N);
	CMath::random_vector(Y.matrix, m_target_dim*N, 0.0, 1.0);

	// SPE's loop

	// Initialize the maximum number of iterations
	int32_t max_iter = 2000 + CMath::round(0.04 * N*N);
	if ( m_strategy == SPE_LOCAL )
		max_iter *= 3;

	// Initialize the learning parameter
	float32_t lambda = 1.0;

	// Initialize variables to use in the main loop
	int32_t i, j, k;
	float64_t sum = 0.0;
	index_t   idx1 = 0, idx2 = 0, idx = 0;

	SGVector< float64_t > scale(m_nupdates);
	SGVector< float64_t > D(m_nupdates);
	SGMatrix< float64_t > Yd(m_nupdates, m_target_dim);
	SGVector< float64_t > Rt(m_nupdates);
	int32_t* ind2 = NULL;

	// Variables required just if local strategy used
	SGMatrix< int32_t > ind1Neighbors;
	SGVector< int32_t > J2;
	if ( m_strategy == SPE_LOCAL )
	{
		ind2 = SG_MALLOC(int32_t, m_nupdates);

		CMath::resize(ind1Neighbors.matrix, 0, m_k*m_nupdates);
		ind1Neighbors.num_rows = m_k;
		ind1Neighbors.num_cols = m_nupdates;

		CMath::resize(J2.vector, 0, m_nupdates);
		J2.vlen = m_nupdates;
	}

	for ( i = 0 ; i < max_iter ; ++i )
	{
		if ( !(i % 1000) )
			SG_DEBUG("SPE's loop, iteration %d of %d\n", i, max_iter);

		// Select the vectors to be updated in this iteration
		int32_t* J = CMath::randperm(N);

		// Pointer to the first set of vector indices to update
		int32_t* ind1 = J;

		// Pointer ind2 to the second set of vector indices to update
		if ( m_strategy == SPE_GLOBAL )
			ind2 = J + m_nupdates;
		else
		{
			// Select the second set of indices to update among neighbors
			// of the first set

			// Get the neighbors of interest
			for ( j = 0 ; j < m_nupdates ; ++j )
			{
				for ( k = 0 ; k < m_k ; ++k )
					ind1Neighbors[k + j*m_k] =
						neighbors_mat.matrix[k + ind1[j]*m_k];
			}

			// Generate pseudo-random indices
			for ( j = 0 ; j < m_nupdates ; ++j )
			{
				J2[j] = CMath::round( CMath::random(0.0, 1.0)*(m_k-1) )
						+ m_k*j;
			}

			// Select final indices
			for ( j = 0 ; j < m_nupdates ; ++j )
				ind2[j] = ind1Neighbors.matrix[ J2[j] ];
		}

		// Compute distances betweeen the selected points in embedded space

		for ( j = 0 ; j < m_nupdates ; ++j )
		{
			sum = 0.0;

			for ( k = 0 ; k < m_target_dim ; ++k )
			{
				idx1 = k + ind1[j]*m_target_dim;
				idx2 = k + ind2[j]*m_target_dim;
				sum += CMath::sq(Y.matrix[idx1] - Y.matrix[idx2]);
			}

			D[j] = CMath::sqrt(sum);
		}

		// Get the corresponding distances in the original space
		for ( j = 0 ; j < m_nupdates ; ++j )
			Rt[j] = distance_matrix.matrix[ ind1[j]*N + ind2[j] ];

		// Compute some terms for update

		// Scale factor: (Rt - D) ./ (D + m_tolerance)
		for ( j = 0 ; j < m_nupdates ; ++j )
			scale[j] = ( Rt[j] - D[j] ) / ( D[j] + m_tolerance );

		// Difference matrix: Y(ind1) - Y(ind2)
		for ( j = 0 ; j < m_nupdates ; ++j )
			for ( k = 0 ; k < m_target_dim ; ++k )
			{
				idx1 = k + ind1[j]*m_target_dim;
				idx2 = k + ind2[j]*m_target_dim;
				idx  = k +      j *m_target_dim;

				Yd[idx] = Y[idx1] - Y[idx2];
			}

		// Update the location of the vectors in the embedded space
		for ( j = 0 ; j < m_nupdates ; ++j )
			for ( k = 0 ; k < m_target_dim ; ++k )
			{
				idx1 = k + ind1[j]*m_target_dim;
				idx2 = k + ind2[j]*m_target_dim;
				idx  = k +      j *m_target_dim;

				Y[idx1] += lambda / 2 * scale[j] * Yd[idx];
				Y[idx2] -= lambda / 2 * scale[j] * Yd[idx];
			}

		// Update the learning parameter
		lambda = lambda - ( lambda / max_iter );

		// Free memory
		delete[] J;
	}

	// Free memory
	distance_matrix.destroy_matrix();
	scale.destroy_vector();
	D.destroy_vector();
	Yd.destroy_matrix();
	Rt.destroy_vector();
	if ( m_strategy == SPE_LOCAL )
	{
		ind1Neighbors.destroy_matrix();
		neighbors_mat.destroy_matrix();
		J2.destroy_vector();
		delete[] ind2;
	}
	SG_UNREF(features);

	return (CFeatures*)( new CSimpleFeatures< float64_t >(Y) );
}

SGMatrix<int32_t> CStochasticProximityEmbedding::get_neighborhood_matrix(SGMatrix<float64_t> distance_matrix, int32_t k)
{
	int32_t i;
	int32_t N = distance_matrix.num_rows;

	int32_t* neighborhood_matrix = SG_MALLOC(int32_t, N*k);

	float64_t max_dist = CMath::max(distance_matrix.matrix,N*N);

	CoverTree<SPE_COVERTREE_POINT>* coverTree = new CoverTree<SPE_COVERTREE_POINT>(max_dist);

	for (i=0; i<N; i++)
		coverTree->insert(SPE_COVERTREE_POINT(i,distance_matrix));

	for (i=0; i<N; i++)
	{
		std::vector<SPE_COVERTREE_POINT> neighbors =
		   coverTree->kNearestNeighbors(SPE_COVERTREE_POINT(i,distance_matrix),k+1);
		for (std::size_t m=1; m<unsigned(k+1); m++)
			neighborhood_matrix[i*k+m-1] = neighbors[m].point_index;
	}

	delete coverTree;

	return SGMatrix<int32_t>(neighborhood_matrix,k,N);
}

#endif /* HAVE_LAPACK */
<commit_msg>- check for simple and real features in SPE -> distance makes the check<commit_after>/*
 * 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.
 *
 * Written (W) 2012 Fernando José Iglesias García
 * Copyright (C) 2012 Fernando José Iglesias García
 */

#include <shogun/converter/StochasticProximityEmbedding.h>
#include <shogun/lib/config.h>
#ifdef HAVE_LAPACK
#include <shogun/converter/EmbeddingConverter.h>
#include <shogun/io/SGIO.h>
#include <shogun/lib/CoverTree.h>
#include <shogun/mathematics/Math.h>
#include <shogun/distance/Distance.h>

using namespace shogun;

class SPE_COVERTREE_POINT
{
public:

	SPE_COVERTREE_POINT(int32_t index, const SGMatrix<float64_t>& dmatrix)
	{
		point_index = index;
		distance_matrix = dmatrix;
	}

	inline double distance(const SPE_COVERTREE_POINT& p) const
	{
		return distance_matrix[point_index*distance_matrix.num_rows+p.point_index];
	}

	inline bool operator==(const SPE_COVERTREE_POINT& p) const
	{
		return (p.point_index==point_index);
	}

	int32_t point_index;
	SGMatrix<float64_t> distance_matrix;
};

CStochasticProximityEmbedding::CStochasticProximityEmbedding() :
	CEmbeddingConverter()
{
	// Initialize to default values
	m_k         = 12;
	m_nupdates  = 100;
	m_strategy  = SPE_GLOBAL;
	m_tolerance = 1e-5;

	init();
}

void CStochasticProximityEmbedding::init()
{
	SG_ADD(&m_k, "m_k", "Number of neighbors", MS_NOT_AVAILABLE);
	SG_ADD((machine_int_t*) &m_strategy, "m_strategy", "SPE strategy",
			MS_NOT_AVAILABLE);
	SG_ADD(&m_tolerance, "m_tolerance", "Regularization parameter",
			MS_NOT_AVAILABLE);
}

CStochasticProximityEmbedding::~CStochasticProximityEmbedding()
{
}

void CStochasticProximityEmbedding::set_k(int32_t k)
{
	if ( k <= 0 )
		SG_ERROR("Number of neighbors k must be greater than 0");

	m_k = k;
}

int32_t CStochasticProximityEmbedding::get_k() const
{
	return m_k;
}

void CStochasticProximityEmbedding::set_strategy(ESPEStrategy strategy)
{
	m_strategy = strategy;
}

ESPEStrategy CStochasticProximityEmbedding::get_strategy() const
{
	return m_strategy;
}

void CStochasticProximityEmbedding::set_tolerance(float32_t tolerance)
{
	if ( tolerance <= 0 )
		SG_ERROR("Tolerance regularization parameter must be greater "
			 "than 0");

	m_tolerance = tolerance;
}

int32_t CStochasticProximityEmbedding::get_tolerance() const
{
	return m_tolerance;
}

void CStochasticProximityEmbedding::set_nupdates(int32_t nupdates)
{
	if ( nupdates <= 0 )
		SG_ERROR("The number of updates must be greater than 0");

	m_nupdates = nupdates;
}

int32_t CStochasticProximityEmbedding::get_nupdates() const
{
	return m_nupdates;
}

const char * CStochasticProximityEmbedding::get_name() const
{
	return "StochasticProximityEmbedding";
}

CFeatures* CStochasticProximityEmbedding::apply(CFeatures* features)
{
	if ( !features )
		SG_ERROR("Features are required to apply SPE\n");

	// Shorthand for the SimpleFeatures
	CSimpleFeatures< float64_t >* simple_features =
		(CSimpleFeatures< float64_t >*) features;
	SG_REF(features);

	// Get and check the number of vectors
	int32_t N = simple_features->get_num_vectors();
	if ( m_strategy == SPE_LOCAL && m_k >= N )
		SG_ERROR("The number of neighbors (%d) must be less than "
		         "the number of vectors (%d)\n", m_k, N);

	if ( 2*m_nupdates > N )
		SG_ERROR("The number of vectors (%d) must be at least two times "
			 "the number of updates (%d)\n", N, m_nupdates);

	// Compute distance matrix
	SG_DEBUG("Computing distance matrix\n");

	if ( m_distance->get_distance_type() != D_EUCLIDIAN )
		SG_ERROR("SPE only supports Euclidian distance, %s given\n",
				m_distance->get_name());

	m_distance->init(simple_features, simple_features);
	SGMatrix< float64_t > distance_matrix = m_distance->get_distance_matrix();
	m_distance->remove_lhs_and_rhs();

	// Normalize the distance matrix if global strategy used
	if ( m_strategy == SPE_GLOBAL )
	{
		float64_t alpha = 1.0 / CMath::max(distance_matrix.matrix, N*N)
					* CMath::sqrt(2.0);
		CMath::scale_vector(alpha, distance_matrix.matrix, N*N);
	}

	// Compute neighborhood matrix if local strategy used
	SGMatrix< int32_t > neighbors_mat;
	if ( m_strategy == SPE_LOCAL )
	{
		SG_DEBUG("Computing neighborhood matrix\n");
		neighbors_mat = get_neighborhood_matrix(distance_matrix, m_k);
	}

	// Initialize vectors in the embedded space randomly, Y is the short for
	// new_feature_matrix
	SGMatrix< float64_t > Y(m_target_dim, N);
	CMath::random_vector(Y.matrix, m_target_dim*N, 0.0, 1.0);

	// SPE's loop

	// Initialize the maximum number of iterations
	int32_t max_iter = 2000 + CMath::round(0.04 * N*N);
	if ( m_strategy == SPE_LOCAL )
		max_iter *= 3;

	// Initialize the learning parameter
	float32_t lambda = 1.0;

	// Initialize variables to use in the main loop
	int32_t i, j, k;
	float64_t sum = 0.0;
	index_t   idx1 = 0, idx2 = 0, idx = 0;

	SGVector< float64_t > scale(m_nupdates);
	SGVector< float64_t > D(m_nupdates);
	SGMatrix< float64_t > Yd(m_nupdates, m_target_dim);
	SGVector< float64_t > Rt(m_nupdates);
	int32_t* ind2 = NULL;

	// Variables required just if local strategy used
	SGMatrix< int32_t > ind1Neighbors;
	SGVector< int32_t > J2;
	if ( m_strategy == SPE_LOCAL )
	{
		ind2 = SG_MALLOC(int32_t, m_nupdates);

		CMath::resize(ind1Neighbors.matrix, 0, m_k*m_nupdates);
		ind1Neighbors.num_rows = m_k;
		ind1Neighbors.num_cols = m_nupdates;

		CMath::resize(J2.vector, 0, m_nupdates);
		J2.vlen = m_nupdates;
	}

	for ( i = 0 ; i < max_iter ; ++i )
	{
		if ( !(i % 1000) )
			SG_DEBUG("SPE's loop, iteration %d of %d\n", i, max_iter);

		// Select the vectors to be updated in this iteration
		int32_t* J = CMath::randperm(N);

		// Pointer to the first set of vector indices to update
		int32_t* ind1 = J;

		// Pointer ind2 to the second set of vector indices to update
		if ( m_strategy == SPE_GLOBAL )
			ind2 = J + m_nupdates;
		else
		{
			// Select the second set of indices to update among neighbors
			// of the first set

			// Get the neighbors of interest
			for ( j = 0 ; j < m_nupdates ; ++j )
			{
				for ( k = 0 ; k < m_k ; ++k )
					ind1Neighbors[k + j*m_k] =
						neighbors_mat.matrix[k + ind1[j]*m_k];
			}

			// Generate pseudo-random indices
			for ( j = 0 ; j < m_nupdates ; ++j )
			{
				J2[j] = CMath::round( CMath::random(0.0, 1.0)*(m_k-1) )
						+ m_k*j;
			}

			// Select final indices
			for ( j = 0 ; j < m_nupdates ; ++j )
				ind2[j] = ind1Neighbors.matrix[ J2[j] ];
		}

		// Compute distances betweeen the selected points in embedded space

		for ( j = 0 ; j < m_nupdates ; ++j )
		{
			sum = 0.0;

			for ( k = 0 ; k < m_target_dim ; ++k )
			{
				idx1 = k + ind1[j]*m_target_dim;
				idx2 = k + ind2[j]*m_target_dim;
				sum += CMath::sq(Y.matrix[idx1] - Y.matrix[idx2]);
			}

			D[j] = CMath::sqrt(sum);
		}

		// Get the corresponding distances in the original space
		for ( j = 0 ; j < m_nupdates ; ++j )
			Rt[j] = distance_matrix.matrix[ ind1[j]*N + ind2[j] ];

		// Compute some terms for update

		// Scale factor: (Rt - D) ./ (D + m_tolerance)
		for ( j = 0 ; j < m_nupdates ; ++j )
			scale[j] = ( Rt[j] - D[j] ) / ( D[j] + m_tolerance );

		// Difference matrix: Y(ind1) - Y(ind2)
		for ( j = 0 ; j < m_nupdates ; ++j )
			for ( k = 0 ; k < m_target_dim ; ++k )
			{
				idx1 = k + ind1[j]*m_target_dim;
				idx2 = k + ind2[j]*m_target_dim;
				idx  = k +      j *m_target_dim;

				Yd[idx] = Y[idx1] - Y[idx2];
			}

		// Update the location of the vectors in the embedded space
		for ( j = 0 ; j < m_nupdates ; ++j )
			for ( k = 0 ; k < m_target_dim ; ++k )
			{
				idx1 = k + ind1[j]*m_target_dim;
				idx2 = k + ind2[j]*m_target_dim;
				idx  = k +      j *m_target_dim;

				Y[idx1] += lambda / 2 * scale[j] * Yd[idx];
				Y[idx2] -= lambda / 2 * scale[j] * Yd[idx];
			}

		// Update the learning parameter
		lambda = lambda - ( lambda / max_iter );

		// Free memory
		delete[] J;
	}

	// Free memory
	distance_matrix.destroy_matrix();
	scale.destroy_vector();
	D.destroy_vector();
	Yd.destroy_matrix();
	Rt.destroy_vector();
	if ( m_strategy == SPE_LOCAL )
	{
		ind1Neighbors.destroy_matrix();
		neighbors_mat.destroy_matrix();
		J2.destroy_vector();
		delete[] ind2;
	}
	SG_UNREF(features);

	return (CFeatures*)( new CSimpleFeatures< float64_t >(Y) );
}

SGMatrix<int32_t> CStochasticProximityEmbedding::get_neighborhood_matrix(SGMatrix<float64_t> distance_matrix, int32_t k)
{
	int32_t i;
	int32_t N = distance_matrix.num_rows;

	int32_t* neighborhood_matrix = SG_MALLOC(int32_t, N*k);

	float64_t max_dist = CMath::max(distance_matrix.matrix,N*N);

	CoverTree<SPE_COVERTREE_POINT>* coverTree = new CoverTree<SPE_COVERTREE_POINT>(max_dist);

	for (i=0; i<N; i++)
		coverTree->insert(SPE_COVERTREE_POINT(i,distance_matrix));

	for (i=0; i<N; i++)
	{
		std::vector<SPE_COVERTREE_POINT> neighbors =
		   coverTree->kNearestNeighbors(SPE_COVERTREE_POINT(i,distance_matrix),k+1);
		for (std::size_t m=1; m<unsigned(k+1); m++)
			neighborhood_matrix[i*k+m-1] = neighbors[m].point_index;
	}

	delete coverTree;

	return SGMatrix<int32_t>(neighborhood_matrix,k,N);
}

#endif /* HAVE_LAPACK */
<|endoftext|>


<commit_before>#include <opencv2/opencv.hpp>

using namespace cv;

int main(int, char**)
{
    // open the default camera
    VideoCapture cap(0);

    // check if we succeeded
    if(!cap.isOpened()) {
        std::cout << "Fix your camera!" << std::endl;
        return -1;
    }

    Mat frame;
    namedWindow("video", WINDOW_AUTOSIZE);

    while(1)
    {
        // Get a new frame from camera
        cap >> frame;

        // Show the frame
        imshow("video", frame);

        // Exit
        if(waitKey(30) >= 0) break;
    }

    return 0;
}<commit_msg>small refactor<commit_after>#include <opencv2/opencv.hpp>

int main(int, char**)
{
    // Open default camera
    cv::VideoCapture cap(0);

    // Camera working?
    if(!cap.isOpened()) {
        std::cout << "Fix your camera!" << std::endl;
        return -1;
    }

    cv::Mat frame;
    cv::namedWindow("video", cv::WINDOW_AUTOSIZE);

    while(1)
    {
        // Get a new frame from camera
        cap >> frame;

        // Show the frame
        imshow("video", frame);

        // Exit
        if(cv::waitKey(30) >= 0) break;
    }

    return 0;
}<|endoftext|>