<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/hid/winkey/winkey_input_driver.h"

#include "xenia/base/platform_win.h"
#include "xenia/hid/hid_flags.h"

namespace xe {
namespace hid {
namespace winkey {

WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
    : InputDriver(input_system), packet_number_(1) {}

WinKeyInputDriver::~WinKeyInputDriver() = default;

X_STATUS WinKeyInputDriver::Setup() { return X_STATUS_SUCCESS; }

X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
                                            X_INPUT_CAPABILITIES* out_caps) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  // TODO(benvanik): confirm with a real XInput controller.
  out_caps->type = 0x01;      // XINPUT_DEVTYPE_GAMEPAD
  out_caps->sub_type = 0x01;  // XINPUT_DEVSUBTYPE_GAMEPAD
  out_caps->flags = 0;
  out_caps->gamepad.buttons = 0xFFFF;
  out_caps->gamepad.left_trigger = 0xFF;
  out_caps->gamepad.right_trigger = 0xFF;
  out_caps->gamepad.thumb_lx = (int16_t)0xFFFFu;
  out_caps->gamepad.thumb_ly = (int16_t)0xFFFFu;
  out_caps->gamepad.thumb_rx = (int16_t)0xFFFFu;
  out_caps->gamepad.thumb_ry = (int16_t)0xFFFFu;
  out_caps->vibration.left_motor_speed = 0;
  out_caps->vibration.right_motor_speed = 0;
  return X_ERROR_SUCCESS;
}

#define IS_KEY_TOGGLED(key) ((GetKeyState(key) & 0x1) == 0x1)
#define IS_KEY_DOWN(key) ((GetAsyncKeyState(key) & 0x8000) == 0x8000)

X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
                                     X_INPUT_STATE* out_state) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  packet_number_++;

  uint16_t buttons = 0;
  uint8_t left_trigger = 0;
  uint8_t right_trigger = 0;
  int16_t thumb_lx = 0;
  int16_t thumb_ly = 0;
  int16_t thumb_rx = 0;
  int16_t thumb_ry = 0;

  if (IS_KEY_TOGGLED(VK_CAPITAL)) {
    // dpad toggled
    if (IS_KEY_DOWN(0x41)) {
      // A
      buttons |= 0x0004;  // XINPUT_GAMEPAD_DPAD_LEFT
    }
    if (IS_KEY_DOWN(0x44)) {
      // D
      buttons |= 0x0008;  // XINPUT_GAMEPAD_DPAD_RIGHT
    }
    if (IS_KEY_DOWN(0x53)) {
      // S
      buttons |= 0x0002;  // XINPUT_GAMEPAD_DPAD_DOWN
    }
    if (IS_KEY_DOWN(0x57)) {
      // W
      buttons |= 0x0001;  // XINPUT_GAMEPAD_DPAD_UP
    }
  } else {
    // left stick
    if (IS_KEY_DOWN(0x41)) {
      // A
      thumb_lx += SHRT_MIN;
    }
    if (IS_KEY_DOWN(0x44)) {
      // D
      thumb_lx += SHRT_MAX;
    }
    if (IS_KEY_DOWN(0x53)) {
      // S
      thumb_ly += SHRT_MIN;
    }
    if (IS_KEY_DOWN(0x57)) {
      // W
      thumb_ly += SHRT_MAX;
    }
  }

  if (IS_KEY_DOWN(0x4C)) {
    // L
    buttons |= 0x4000;  // XINPUT_GAMEPAD_X
  }
  if (IS_KEY_DOWN(VK_OEM_7)) {
    // '
    buttons |= 0x2000;  // XINPUT_GAMEPAD_B
  }
  if (IS_KEY_DOWN(VK_OEM_1)) {
    // ;
    buttons |= 0x1000;  // XINPUT_GAMEPAD_A
  }
  if (IS_KEY_DOWN(0x50)) {
    // P
    buttons |= 0x8000;  // XINPUT_GAMEPAD_Y
  }

  if (IS_KEY_DOWN(0x5A)) {
    // Z
    buttons |= 0x0020;  // XINPUT_GAMEPAD_BACK
  }
  if (IS_KEY_DOWN(0x58)) {
    // X
    buttons |= 0x0010;  // XINPUT_GAMEPAD_START
  }

  out_state->packet_number = packet_number_;
  out_state->gamepad.buttons = buttons;
  out_state->gamepad.left_trigger = left_trigger;
  out_state->gamepad.right_trigger = right_trigger;
  out_state->gamepad.thumb_lx = thumb_lx;
  out_state->gamepad.thumb_ly = thumb_ly;
  out_state->gamepad.thumb_rx = thumb_rx;
  out_state->gamepad.thumb_ry = thumb_ry;

  return X_ERROR_SUCCESS;
}

X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
                                     X_INPUT_VIBRATION* vibration) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  return X_ERROR_SUCCESS;
}

X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
                                         X_INPUT_KEYSTROKE* out_keystroke) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  X_RESULT result = X_ERROR_EMPTY;

  uint16_t virtual_key = 0;
  uint16_t unicode = 0;
  uint16_t keystroke_flags = 0;
  uint8_t hid_code = 0;

  out_keystroke->virtual_key = virtual_key;
  out_keystroke->unicode = unicode;
  out_keystroke->flags = keystroke_flags;
  out_keystroke->user_index = 0;
  out_keystroke->hid_code = hid_code;

  // X_ERROR_EMPTY if no new keys
  // X_ERROR_DEVICE_NOT_CONNECTED if no device
  // X_ERROR_SUCCESS if key
  return result;
}

}  // namespace winkey
}  // namespace hid
}  // namespace xe
<commit_msg>Winkey support GetKeystroke (need to fix flags though) and support right stick<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2014 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/hid/winkey/winkey_input_driver.h"

#include "xenia/base/platform_win.h"
#include "xenia/hid/hid_flags.h"

namespace xe {
namespace hid {
namespace winkey {

WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system)
    : InputDriver(input_system), packet_number_(1) {}

WinKeyInputDriver::~WinKeyInputDriver() = default;

X_STATUS WinKeyInputDriver::Setup() { return X_STATUS_SUCCESS; }

X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
                                            X_INPUT_CAPABILITIES* out_caps) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  // TODO(benvanik): confirm with a real XInput controller.
  out_caps->type = 0x01;      // XINPUT_DEVTYPE_GAMEPAD
  out_caps->sub_type = 0x01;  // XINPUT_DEVSUBTYPE_GAMEPAD
  out_caps->flags = 0;
  out_caps->gamepad.buttons = 0xFFFF;
  out_caps->gamepad.left_trigger = 0xFF;
  out_caps->gamepad.right_trigger = 0xFF;
  out_caps->gamepad.thumb_lx = (int16_t)0xFFFFu;
  out_caps->gamepad.thumb_ly = (int16_t)0xFFFFu;
  out_caps->gamepad.thumb_rx = (int16_t)0xFFFFu;
  out_caps->gamepad.thumb_ry = (int16_t)0xFFFFu;
  out_caps->vibration.left_motor_speed = 0;
  out_caps->vibration.right_motor_speed = 0;
  return X_ERROR_SUCCESS;
}

#define IS_KEY_TOGGLED(key) ((GetKeyState(key) & 0x1) == 0x1)
#define IS_KEY_DOWN(key) ((GetAsyncKeyState(key) & 0x8000) == 0x8000)

X_RESULT WinKeyInputDriver::GetState(uint32_t user_index,
                                     X_INPUT_STATE* out_state) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  packet_number_++;

  uint16_t buttons = 0;
  uint8_t left_trigger = 0;
  uint8_t right_trigger = 0;
  int16_t thumb_lx = 0;
  int16_t thumb_ly = 0;
  int16_t thumb_rx = 0;
  int16_t thumb_ry = 0;

  if (IS_KEY_TOGGLED(VK_CAPITAL)) {
    // dpad toggled
    if (IS_KEY_DOWN(0x41)) {
      // A
      buttons |= 0x0004;  // XINPUT_GAMEPAD_DPAD_LEFT
    }
    if (IS_KEY_DOWN(0x44)) {
      // D
      buttons |= 0x0008;  // XINPUT_GAMEPAD_DPAD_RIGHT
    }
    if (IS_KEY_DOWN(0x53)) {
      // S
      buttons |= 0x0002;  // XINPUT_GAMEPAD_DPAD_DOWN
    }
    if (IS_KEY_DOWN(0x57)) {
      // W
      buttons |= 0x0001;  // XINPUT_GAMEPAD_DPAD_UP
    }
  } else {
    // left stick
    if (IS_KEY_DOWN(0x41)) {
      // A
      thumb_lx += SHRT_MIN;
    }
    if (IS_KEY_DOWN(0x44)) {
      // D
      thumb_lx += SHRT_MAX;
    }
    if (IS_KEY_DOWN(0x53)) {
      // S
      thumb_ly += SHRT_MIN;
    }
    if (IS_KEY_DOWN(0x57)) {
      // W
      thumb_ly += SHRT_MAX;
    }
  }

  // Right stick
  if (IS_KEY_DOWN(0x26)) {
    // Up
    thumb_ry += SHRT_MAX;
  }
  if (IS_KEY_DOWN(0x28)) {
    // Down
    thumb_ry += SHRT_MIN;
  }
  if (IS_KEY_DOWN(0x27)) {
    // Right
    thumb_rx += SHRT_MAX;
  }
  if (IS_KEY_DOWN(0x25)) {
    // Left
    thumb_rx += SHRT_MIN;
  }

  if (IS_KEY_DOWN(0x4C)) {
    // L
    buttons |= 0x4000;  // XINPUT_GAMEPAD_X
  }
  if (IS_KEY_DOWN(VK_OEM_7)) {
    // '
    buttons |= 0x2000;  // XINPUT_GAMEPAD_B
  }
  if (IS_KEY_DOWN(VK_OEM_1)) {
    // ;
    buttons |= 0x1000;  // XINPUT_GAMEPAD_A
  }
  if (IS_KEY_DOWN(0x50)) {
    // P
    buttons |= 0x8000;  // XINPUT_GAMEPAD_Y
  }

  if (IS_KEY_DOWN(0x5A)) {
    // Z
    buttons |= 0x0020;  // XINPUT_GAMEPAD_BACK
  }
  if (IS_KEY_DOWN(0x58)) {
    // X
    buttons |= 0x0010;  // XINPUT_GAMEPAD_START
  }

  out_state->packet_number = packet_number_;
  out_state->gamepad.buttons = buttons;
  out_state->gamepad.left_trigger = left_trigger;
  out_state->gamepad.right_trigger = right_trigger;
  out_state->gamepad.thumb_lx = thumb_lx;
  out_state->gamepad.thumb_ly = thumb_ly;
  out_state->gamepad.thumb_rx = thumb_rx;
  out_state->gamepad.thumb_ry = thumb_ry;

  return X_ERROR_SUCCESS;
}

X_RESULT WinKeyInputDriver::SetState(uint32_t user_index,
                                     X_INPUT_VIBRATION* vibration) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  return X_ERROR_SUCCESS;
}

X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags,
                                         X_INPUT_KEYSTROKE* out_keystroke) {
  if (user_index != 0) {
    return X_ERROR_DEVICE_NOT_CONNECTED;
  }

  X_RESULT result = X_ERROR_EMPTY;

  uint16_t virtual_key = 0;
  uint16_t unicode = 0;
  uint16_t keystroke_flags = 0;
  uint8_t hid_code = 0;

  if (IS_KEY_TOGGLED(VK_CAPITAL)) {
    // dpad toggled
    if (IS_KEY_DOWN(0x41)) {
      // A
      virtual_key = 0x5812;  // VK_PAD_DPAD_LEFT
    } else if (IS_KEY_DOWN(0x44)) {
      // D
      virtual_key = 0x5813;  // VK_PAD_DPAD_RIGHT
    } else if (IS_KEY_DOWN(0x53)) {
      // S
      virtual_key = 0x5811;  // VK_PAD_DPAD_DOWN
    } else if (IS_KEY_DOWN(0x57)) {
      // W
      virtual_key = 0x5810;  // VK_PAD_DPAD_UP
    }
  } else {
    // left stick
    if (IS_KEY_DOWN(0x57)) {
      // W
      virtual_key = 0x5820; // VK_PAD_LTHUMB_UP
    }
    if (IS_KEY_DOWN(0x53)) {
      // S
      virtual_key = 0x5821; // VK_PAD_LTHUMB_DOWN
    }
    if (IS_KEY_DOWN(0x44)) {
      // D
      virtual_key = 0x5822; // VK_PAD_LTHUMB_RIGHT
    }
    if (IS_KEY_DOWN(0x41)) {
      // A
      virtual_key = 0x5823; // VK_PAD_LTHUMB_LEFT
    }
  }

  // Right stick
  if (IS_KEY_DOWN(0x26)) {
    // Up
    virtual_key = 0x5830;
  }
  if (IS_KEY_DOWN(0x28)) {
    // Down
    virtual_key = 0x5831;
  }
  if (IS_KEY_DOWN(0x27)) {
    // Right
    virtual_key = 0x5832;
  }
  if (IS_KEY_DOWN(0x25)) {
    // Left
    virtual_key = 0x5833;
  }

  if (IS_KEY_DOWN(0x4C)) {
    // L
    virtual_key = 0x5802;  // VK_PAD_X
  } else if (IS_KEY_DOWN(VK_OEM_7)) {
    // '
    virtual_key = 0x5801;  // VK_PAD_B
  } else if (IS_KEY_DOWN(VK_OEM_1)) {
    // ;
    virtual_key = 0x5800;  // VK_PAD_A
  } else if (IS_KEY_DOWN(0x50)) {
    // P
    virtual_key = 0x5803;  // VK_PAD_Y
  }

  if (IS_KEY_DOWN(0x58)) {
    // X
    virtual_key = 0x5814;  // VK_PAD_START
  }
  if (IS_KEY_DOWN(0x5A)) {
    // Z
    virtual_key = 0x5815;  // VK_PAD_BACK
  }

  if (virtual_key != 0) {
    keystroke_flags |= 0x0001; // XINPUT_KEYSTROKE_DOWN
    result = X_ERROR_SUCCESS;
  }

  out_keystroke->virtual_key = virtual_key;
  out_keystroke->unicode = unicode;
  out_keystroke->flags = keystroke_flags;
  out_keystroke->user_index = 0;
  out_keystroke->hid_code = hid_code;

  // X_ERROR_EMPTY if no new keys
  // X_ERROR_DEVICE_NOT_CONNECTED if no device
  // X_ERROR_SUCCESS if key
  return result;
}

}  // namespace winkey
}  // namespace hid
}  // namespace xe
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_FUNCTOR_MULTI_EXPRESSION_HPP
#define STAN_MATH_PRIM_FUNCTOR_MULTI_EXPRESSION_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/err.hpp>
#include <tuple>

namespace stan {
namespace math {

namespace internal {
constexpr int constexpr_sum() { return 0; }

template <typename Arg0, typename... Args>
constexpr int constexpr_sum(Arg0 arg0, Args... args) {
  return arg0 + constexpr_sum(args...);
}

constexpr bool constexpr_all() { return true; }
template <typename Arg0, typename... Args>
constexpr bool constexpr_all(Arg0 arg0, Args... args) {
  return arg0 && constexpr_all(args...);
}

}  // namespace internal

/**
 * Represents multiple exprs that will be calculated in same loop.
 * @tparam T_expressions types of exprs
 */
template <typename... T_expressions>
class eigen_expressions_ {
 public:
  /**
   * Constructor.
   * @param exprs expresions that will be calculated in same loop.
   * @throw invalid_argument expressions have different sizes (for row major
   * expressions rows and columns are swapped for the check)
   */
  explicit eigen_expressions_(T_expressions&&... exprs)
      : exprs_(std::forward<T_expressions>(exprs)...) {
    index_apply<sizeof...(T_expressions) - 1>([&](auto... Is) {
      constexpr auto first_flags = Eigen::internal::evaluator<std::decay_t<
          std::tuple_element_t<0, std::tuple<T_expressions...>>>>::Flags;
      static_cast<void>(std::initializer_list<int>{
          ((((Eigen::internal::evaluator<std::decay_t<std::tuple_element_t<
                  Is + 1, std::tuple<T_expressions...>>>>::Flags
              ^ first_flags)
             & Eigen::RowMajorBit)
                ? check_matching_dims("eigen_expressions_.eigen_expressions_",
                                      "first expression", std::get<0>(exprs_),
                                      "transposed expression",
                                      std::get<Is + 1>(exprs_).transpose())
                : check_matching_dims("eigen_expressions_.eigen_expressions_",
                                      "first expression", std::get<0>(exprs_),
                                      "expression", std::get<Is + 1>(exprs_))),
           0)...});
    });
  }

 private:
  std::tuple<T_expressions...> exprs_;
  template <typename... T_results>
  friend class eigen_results_;
};

/**
 * Deduces types for constructing \c expressions_ object.
 * @tparam T_expressions types of exprs
 * @param exprs exprs that will be used in same kernel.
 */
template <typename... T_expressions,
          require_all_eigen_t<T_expressions...>* = nullptr>
eigen_expressions_<T_expressions...> eigen_expressions(
    T_expressions&&... exprs) {
  return eigen_expressions_<T_expressions...>(
      std::forward<T_expressions>(exprs)...);
}

/**
 * Represents results that will be calculated in same loop.
 * @tparam T_results types of results
 */
template <typename... T_results>
class eigen_results_ {
  std::tuple<T_results...> results_;

  /**
   * Assign expressions to results using linear indexing.
   * @tparam Linear whether to use linear indexing
   * @tparam T_expr_evals types of expression evaluators
   * @param expr_evals evaluators for expressions to assign
   * @param rows number of rows
   * @param cols number of cols
   */
  template <bool Linear, typename... T_expr_evals,
            std::enable_if_t<Linear>* = nullptr>
  inline void assign(const std::tuple<T_expr_evals...>& expr_evals,
                     Eigen::Index rows, Eigen::Index cols) {
    for (size_t i = 0; i < rows * cols; i++) {
      index_apply<sizeof...(T_results)>([&](auto... Is) {
        static_cast<void>(
            std::initializer_list<int>{(std::get<Is>(this->results_).coeffRef(i)
                                        = std::get<Is>(expr_evals).coeff(i),
                                        0)...});
      });
    }
  }
  /**
   * Assign expressions to results using 2d indexing.
   * @tparam Linear whether to use linear indexing
   * @tparam T_expr_evals types of expression evaluators
   * @param expr_evals evaluators for expressions to assign
   * @param rows number of rows
   * @param cols number of cols
   */
  template <bool Linear, typename... T_expr_evals,
            std::enable_if_t<!Linear>* = nullptr>
  inline void assign(const std::tuple<T_expr_evals...>& expr_evals,
                     Eigen::Index rows, Eigen::Index cols) {
    constexpr bool is_first_row_major
        = std::decay_t<decltype(std::get<0>(expr_evals))>::Flags
          & Eigen::RowMajorBit;
    const Eigen::Index outer_dimension = is_first_row_major ? rows : cols;
    const Eigen::Index inner_dimension = is_first_row_major ? cols : rows;
    for (size_t i = 0; i < outer_dimension; i++) {
      for (size_t j = 0; j < inner_dimension; j++) {
        index_apply<sizeof...(T_results)>([&](auto... Is) {
          static_cast<void>(std::initializer_list<int>{
              ((std::decay_t<decltype(std::get<0>(expr_evals))>::Flags
                        & Eigen::RowMajorBit
                    ? std::get<Is>(this->results_).coeffRef(i, j)
                      = std::get<Is>(expr_evals).coeff(i, j)
                    : std::get<Is>(this->results_).coeffRef(j, i)
                      = std::get<Is>(expr_evals).coeff(j, i)),
               0)...});
        });
      }
    }
  }

  /**
   * Selects and calls appropriate `assign`.
   * @tparam T_expressions types of expressions
   * @param expressions expressions
   */
  template <typename... T_expressions,
            std::enable_if_t<sizeof...(T_results)
                             == sizeof...(T_expressions)>* = nullptr>
  void assign_select(const eigen_expressions_<T_expressions...>& expressions) {
    constexpr bool all_linear = internal::constexpr_all(
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_expressions>>::Flags
            & Eigen::LinearAccessBit)...,
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_results>>::Flags
            & Eigen::LinearAccessBit)...);
    constexpr int N_row_major = internal::constexpr_sum(
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_expressions>>::Flags
            & Eigen::RowMajorBit)...,
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_results>>::Flags
            & Eigen::RowMajorBit)...);
    constexpr int N_col_major
        = sizeof...(T_results) + sizeof...(T_expressions) - N_row_major;

    index_apply<sizeof...(T_results)>([&](auto... Is) {
      std::tuple<Eigen::internal::evaluator<
          std::decay_t<decltype(std::get<Is>(expressions.exprs_))>>...>
      expression_evaluators(std::get<Is>(expressions.exprs_)...);

      this->assign<all_linear && (N_col_major == 0 || N_row_major == 0)>(
          expression_evaluators,
          std::get<0>(expressions.exprs_).rows(),
          std::get<0>(expressions.exprs_).cols());
    });
  }

 public:
  /**
   * Constructor.
   * @param results results that will be calculated in same kernel
   */
  explicit eigen_results_(T_results&&... results)
      : results_(std::forward<T_results>(results)...) {}

  /**
   * Assigning \c expressions_cl object to \c eigen_results_ object evals the
   * expressions into results.
   * @tparam T_expressions types of expressions
   * @param expressions expressions
   */
  template <typename... T_expressions,
            std::enable_if_t<sizeof...(T_results)
                             == sizeof...(T_expressions)>* = nullptr>
  void operator=(const eigen_expressions_<T_expressions...>& expressions) {
    index_apply<sizeof...(T_results)>([&, this](auto... Is) {
      static_cast<void>(std::initializer_list<int>{
          (Eigen::internal::resize_if_allowed(
               std::get<Is>(this->results_), std::get<Is>(expressions.exprs_),
               Eigen::internal::assign_op<int, int>()),
           // types in the assign_op don't matter for the resizing
           0)...});
    });

    assign_select(expressions);
  }

  /**
   * Add \c eigen_results_ to \c expressions_cl in place.
   * @tparam T_expressions types of expressions
   * @param expressions expressions
   */
  template <typename... T_expressions,
            std::enable_if_t<sizeof...(T_results)
                             == sizeof...(T_expressions)>* = nullptr>
  void operator+=(const eigen_expressions_<T_expressions...>& expressions) {
    index_apply<sizeof...(T_results)>([&, this](auto... Is) {
      this->assign_select(eigen_expressions((
          std::get<Is>(this->results_) + std::get<Is>(expressions.exprs_))...));
    });
  }
};

/**
 * Deduces types for constructing \c results_cl object.
 * @tparam T_results types of results
 * @param results results that will be calculated in same kernel.
 */
template <typename... T_results, require_all_eigen_t<T_results...>* = nullptr>
eigen_results_<T_results...> eigen_results(T_results&&... results) {
  return eigen_results_<T_results...>(std::forward<T_results>(results)...);
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.04.1 (tags/RELEASE_600/final)<commit_after>#ifndef STAN_MATH_PRIM_FUNCTOR_MULTI_EXPRESSION_HPP
#define STAN_MATH_PRIM_FUNCTOR_MULTI_EXPRESSION_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/err.hpp>
#include <tuple>

namespace stan {
namespace math {

namespace internal {
constexpr int constexpr_sum() { return 0; }

template <typename Arg0, typename... Args>
constexpr int constexpr_sum(Arg0 arg0, Args... args) {
  return arg0 + constexpr_sum(args...);
}

constexpr bool constexpr_all() { return true; }
template <typename Arg0, typename... Args>
constexpr bool constexpr_all(Arg0 arg0, Args... args) {
  return arg0 && constexpr_all(args...);
}

}  // namespace internal

/**
 * Represents multiple exprs that will be calculated in same loop.
 * @tparam T_expressions types of exprs
 */
template <typename... T_expressions>
class eigen_expressions_ {
 public:
  /**
   * Constructor.
   * @param exprs expresions that will be calculated in same loop.
   * @throw invalid_argument expressions have different sizes (for row major
   * expressions rows and columns are swapped for the check)
   */
  explicit eigen_expressions_(T_expressions&&... exprs)
      : exprs_(std::forward<T_expressions>(exprs)...) {
    index_apply<sizeof...(T_expressions) - 1>([&](auto... Is) {
      constexpr auto first_flags = Eigen::internal::evaluator<std::decay_t<
          std::tuple_element_t<0, std::tuple<T_expressions...>>>>::Flags;
      static_cast<void>(std::initializer_list<int>{
          ((((Eigen::internal::evaluator<std::decay_t<std::tuple_element_t<
                  Is + 1, std::tuple<T_expressions...>>>>::Flags
              ^ first_flags)
             & Eigen::RowMajorBit)
                ? check_matching_dims("eigen_expressions_.eigen_expressions_",
                                      "first expression", std::get<0>(exprs_),
                                      "transposed expression",
                                      std::get<Is + 1>(exprs_).transpose())
                : check_matching_dims("eigen_expressions_.eigen_expressions_",
                                      "first expression", std::get<0>(exprs_),
                                      "expression", std::get<Is + 1>(exprs_))),
           0)...});
    });
  }

 private:
  std::tuple<T_expressions...> exprs_;
  template <typename... T_results>
  friend class eigen_results_;
};

/**
 * Deduces types for constructing \c expressions_ object.
 * @tparam T_expressions types of exprs
 * @param exprs exprs that will be used in same kernel.
 */
template <typename... T_expressions,
          require_all_eigen_t<T_expressions...>* = nullptr>
eigen_expressions_<T_expressions...> eigen_expressions(
    T_expressions&&... exprs) {
  return eigen_expressions_<T_expressions...>(
      std::forward<T_expressions>(exprs)...);
}

/**
 * Represents results that will be calculated in same loop.
 * @tparam T_results types of results
 */
template <typename... T_results>
class eigen_results_ {
  std::tuple<T_results...> results_;

  /**
   * Assign expressions to results using linear indexing.
   * @tparam Linear whether to use linear indexing
   * @tparam T_expr_evals types of expression evaluators
   * @param expr_evals evaluators for expressions to assign
   * @param rows number of rows
   * @param cols number of cols
   */
  template <bool Linear, typename... T_expr_evals,
            std::enable_if_t<Linear>* = nullptr>
  inline void assign(const std::tuple<T_expr_evals...>& expr_evals,
                     Eigen::Index rows, Eigen::Index cols) {
    for (size_t i = 0; i < rows * cols; i++) {
      index_apply<sizeof...(T_results)>([&](auto... Is) {
        static_cast<void>(
            std::initializer_list<int>{(std::get<Is>(this->results_).coeffRef(i)
                                        = std::get<Is>(expr_evals).coeff(i),
                                        0)...});
      });
    }
  }
  /**
   * Assign expressions to results using 2d indexing.
   * @tparam Linear whether to use linear indexing
   * @tparam T_expr_evals types of expression evaluators
   * @param expr_evals evaluators for expressions to assign
   * @param rows number of rows
   * @param cols number of cols
   */
  template <bool Linear, typename... T_expr_evals,
            std::enable_if_t<!Linear>* = nullptr>
  inline void assign(const std::tuple<T_expr_evals...>& expr_evals,
                     Eigen::Index rows, Eigen::Index cols) {
    constexpr bool is_first_row_major
        = std::decay_t<decltype(std::get<0>(expr_evals))>::Flags
          & Eigen::RowMajorBit;
    const Eigen::Index outer_dimension = is_first_row_major ? rows : cols;
    const Eigen::Index inner_dimension = is_first_row_major ? cols : rows;
    for (size_t i = 0; i < outer_dimension; i++) {
      for (size_t j = 0; j < inner_dimension; j++) {
        index_apply<sizeof...(T_results)>([&](auto... Is) {
          static_cast<void>(std::initializer_list<int>{
              ((std::decay_t<decltype(std::get<0>(expr_evals))>::Flags
                        & Eigen::RowMajorBit
                    ? std::get<Is>(this->results_).coeffRef(i, j)
                      = std::get<Is>(expr_evals).coeff(i, j)
                    : std::get<Is>(this->results_).coeffRef(j, i)
                      = std::get<Is>(expr_evals).coeff(j, i)),
               0)...});
        });
      }
    }
  }

  /**
   * Selects and calls appropriate `assign`.
   * @tparam T_expressions types of expressions
   * @param expressions expressions
   */
  template <typename... T_expressions,
            std::enable_if_t<sizeof...(T_results)
                             == sizeof...(T_expressions)>* = nullptr>
  void assign_select(const eigen_expressions_<T_expressions...>& expressions) {
    constexpr bool all_linear = internal::constexpr_all(
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_expressions>>::Flags
            & Eigen::LinearAccessBit)...,
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_results>>::Flags
            & Eigen::LinearAccessBit)...);
    constexpr int N_row_major = internal::constexpr_sum(
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_expressions>>::Flags
            & Eigen::RowMajorBit)...,
        static_cast<bool>(
            Eigen::internal::evaluator<std::decay_t<T_results>>::Flags
            & Eigen::RowMajorBit)...);
    constexpr int N_col_major
        = sizeof...(T_results) + sizeof...(T_expressions) - N_row_major;

    index_apply<sizeof...(T_results)>([&](auto... Is) {
      std::tuple<Eigen::internal::evaluator<
          std::decay_t<decltype(std::get<Is>(expressions.exprs_))>>...>
      expression_evaluators(std::get<Is>(expressions.exprs_)...);

      this->assign<all_linear && (N_col_major == 0 || N_row_major == 0)>(
          expression_evaluators, std::get<0>(expressions.exprs_).rows(),
          std::get<0>(expressions.exprs_).cols());
    });
  }

 public:
  /**
   * Constructor.
   * @param results results that will be calculated in same kernel
   */
  explicit eigen_results_(T_results&&... results)
      : results_(std::forward<T_results>(results)...) {}

  /**
   * Assigning \c expressions_cl object to \c eigen_results_ object evals the
   * expressions into results.
   * @tparam T_expressions types of expressions
   * @param expressions expressions
   */
  template <typename... T_expressions,
            std::enable_if_t<sizeof...(T_results)
                             == sizeof...(T_expressions)>* = nullptr>
  void operator=(const eigen_expressions_<T_expressions...>& expressions) {
    index_apply<sizeof...(T_results)>([&, this](auto... Is) {
      static_cast<void>(std::initializer_list<int>{
          (Eigen::internal::resize_if_allowed(
               std::get<Is>(this->results_), std::get<Is>(expressions.exprs_),
               Eigen::internal::assign_op<int, int>()),
           // types in the assign_op don't matter for the resizing
           0)...});
    });

    assign_select(expressions);
  }

  /**
   * Add \c eigen_results_ to \c expressions_cl in place.
   * @tparam T_expressions types of expressions
   * @param expressions expressions
   */
  template <typename... T_expressions,
            std::enable_if_t<sizeof...(T_results)
                             == sizeof...(T_expressions)>* = nullptr>
  void operator+=(const eigen_expressions_<T_expressions...>& expressions) {
    index_apply<sizeof...(T_results)>([&, this](auto... Is) {
      this->assign_select(eigen_expressions((
          std::get<Is>(this->results_) + std::get<Is>(expressions.exprs_))...));
    });
  }
};

/**
 * Deduces types for constructing \c results_cl object.
 * @tparam T_results types of results
 * @param results results that will be calculated in same kernel.
 */
template <typename... T_results, require_all_eigen_t<T_results...>* = nullptr>
eigen_results_<T_results...> eigen_results(T_results&&... results) {
  return eigen_results_<T_results...>(std::forward<T_results>(results)...);
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/* Copyright 2015 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/kernels/control_flow_ops.h"

#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/public/tensor.h"

namespace tensorflow {

// A switch op has two inputs and two outputs. It forwards the value of
// Input:0 to the output specified by input:1. Input:1 is a boolean tensor.
// Input:0 is forwarded to output:0 if input:1 is false, otherwise to
// output:1.
class SwitchOp : public OpKernel {
 public:
  explicit SwitchOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    const Tensor& outputPorts = context->input(1);
    OP_REQUIRES(
        context, TensorShapeUtils::IsScalar(outputPorts.shape()),
        errors::InvalidArgument("The second input must be a scalar, "
                                "but it has shape ",
                                outputPorts.shape().ShortDebugString()));

    bool pred = outputPorts.scalar<bool>()();
    int port = (pred) ? 1 : 0;
    if (IsRefType(context->input_dtype(0))) {
      context->forward_ref_input_to_ref_output(0, port);
    } else {
      context->set_output(port, context->input(0));
    }
  }

  bool IsExpensive() override { return false; }

  ~SwitchOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(SwitchOp);
};

#define REGISTER_CPU_SWITCH(type)                         \
  REGISTER_KERNEL_BUILDER(Name("Switch")                  \
                              .Device(DEVICE_CPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_CPU_REF_SWITCH(type)                     \
  REGISTER_KERNEL_BUILDER(Name("RefSwitch")               \
                              .Device(DEVICE_CPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_GPU_SWITCH(type)                         \
  REGISTER_KERNEL_BUILDER(Name("Switch")                  \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_GPU_REF_SWITCH(type)                     \
  REGISTER_KERNEL_BUILDER(Name("RefSwitch")               \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

TF_CALL_ALL_TYPES(REGISTER_CPU_SWITCH);
TF_CALL_ALL_TYPES(REGISTER_CPU_REF_SWITCH);

TF_CALL_GPU_NUMBER_TYPES(REGISTER_GPU_SWITCH);
REGISTER_GPU_SWITCH(int64);
REGISTER_GPU_SWITCH(bool);
TF_CALL_GPU_NUMBER_TYPES(REGISTER_GPU_REF_SWITCH);
REGISTER_GPU_REF_SWITCH(int32);
REGISTER_GPU_REF_SWITCH(int64);
REGISTER_GPU_REF_SWITCH(bool);

#undef REGISTER_CPU_SWITCH
#undef REGISTER_CPU_REF_SWITCH
#undef REGISTER_GPU_SWITCH
#undef REGISTER_GPU_REF_SWITCH

// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("Switch")
                            .Device(DEVICE_GPU)
                            .HostMemory("data")
                            .HostMemory("pred")
                            .HostMemory("output_false")
                            .HostMemory("output_true")
                            .TypeConstraint<int32>("T"),
                        SwitchOp);

class RefSelectOp : public OpKernel {
 public:
  explicit RefSelectOp(OpKernelConstruction* context) : OpKernel(context) {
    OP_REQUIRES_OK(context, context->GetAttr("N", &num_ref_inputs_));
  }

  void Compute(OpKernelContext* context) override {
    const Tensor& index_tensor = context->input(0);
    OP_REQUIRES(
        context, TensorShapeUtils::IsScalar(index_tensor.shape()),
        errors::InvalidArgument("Index must be a scalar, "
                                "but it has shape ",
                                index_tensor.shape().ShortDebugString()));

    int32 index = index_tensor.scalar<int32>()();

    OP_REQUIRES(context, index >= 0 && index < num_ref_inputs_,
                errors::InvalidArgument("Index must be in the range [0, ",
                                        num_ref_inputs_, ") but got ", index));
    context->forward_ref_input_to_ref_output(index + 1, 0);
  }

  bool IsExpensive() override { return false; }

  ~RefSelectOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(RefSelectOp);

 private:
  int num_ref_inputs_;
};

#define REGISTER_CPU_REF_SELECT(type)                     \
  REGISTER_KERNEL_BUILDER(Name("RefSelect")               \
                              .Device(DEVICE_CPU)         \
                              .HostMemory("index")        \
                              .TypeConstraint<type>("T"), \
                          RefSelectOp)
TF_CALL_ALL_TYPES(REGISTER_CPU_REF_SELECT);

#undef REGISTER_CPU_REF_SWITCH

// A merge op has n inputs and two outputs. It forwards the value of the
// first input that becomes available to its first output, and the
// index of the first input to its second output.
class MergeOp : public OpKernel {
 public:
  explicit MergeOp(OpKernelConstruction* context) : OpKernel(context) {
    const DataType dt = context->input_type(0);
    const int num_in = context->num_inputs();
    OP_REQUIRES_OK(context, context->MatchSignature(DataTypeVector(num_in, dt),
                                                    {dt, DT_INT32}));
  }

  void Compute(OpKernelContext* context) override {
    bool input_seen = false;
    for (int i = 0; i < context->num_inputs(); ++i) {
      if (context->has_input(i)) {
        if (input_seen) {
          context->SetStatus(errors::Internal(
              "Merge can not have more than one valid input."));
          return;
        }
        input_seen = true;

        context->set_output(0, context->input(i));
        Tensor* value_index = nullptr;
        OP_REQUIRES_OK(context, context->allocate_output(1, TensorShape({}),
                                                         &value_index));
        value_index->scalar<int32>()() = i;
      }
    }
  }

  bool IsExpensive() override { return false; }

  ~MergeOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(MergeOp);
};

REGISTER_KERNEL_BUILDER(Name("Merge").Device(DEVICE_CPU), MergeOp);

#define REGISTER_GPU_KERNEL(type)                         \
  REGISTER_KERNEL_BUILDER(Name("Merge")                   \
                              .Device(DEVICE_GPU)         \
                              .TypeConstraint<type>("T")  \
                              .HostMemory("value_index"), \
                          MergeOp);

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);

#undef REGISTER_GPU_KERNEL

// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("Merge")
                            .Device(DEVICE_GPU)
                            .HostMemory("inputs")
                            .HostMemory("output")
                            .HostMemory("value_index")
                            .TypeConstraint<int32>("T"),
                        MergeOp);

// An enter op has one input and one output. It creates or finds
// the child frame that is uniquely identified by the frame_name,
// and makes its input available to the child frame.
class EnterOp : public OpKernel {
 public:
  explicit EnterOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    if (IsRefType(context->input_dtype(0))) {
      context->forward_ref_input_to_ref_output(0, 0);
    } else {
      context->set_output(0, context->input(0));
    }
  }

  bool IsExpensive() override { return false; }

  ~EnterOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(EnterOp);
};

REGISTER_KERNEL_BUILDER(Name("Enter").Device(DEVICE_CPU), EnterOp);
REGISTER_KERNEL_BUILDER(Name("RefEnter").Device(DEVICE_CPU), EnterOp);

#define REGISTER_GPU_KERNEL(type) \
  REGISTER_KERNEL_BUILDER(        \
      Name("Enter").Device(DEVICE_GPU).TypeConstraint<type>("T"), EnterOp);
#define REGISTER_GPU_REF_KERNEL(type) \
  REGISTER_KERNEL_BUILDER(            \
      Name("RefEnter").Device(DEVICE_GPU).TypeConstraint<type>("T"), EnterOp);

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
TF_CALL_NUMBER_TYPES(REGISTER_GPU_REF_KERNEL);

#undef REGISTER_GPU_KERNEL
#undef REGISTER_GPU_REF_KERNEL

// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("Enter")
                            .Device(DEVICE_GPU)
                            .HostMemory("data")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        EnterOp);

// Special GPU kernels for string.
REGISTER_KERNEL_BUILDER(Name("Enter")
                            .Device(DEVICE_GPU)
                            .HostMemory("data")
                            .HostMemory("output")
                            .TypeConstraint<string>("T"),
                        EnterOp);

REGISTER_KERNEL_BUILDER(Name("RefEnter")
                            .Device(DEVICE_GPU)
                            .HostMemory("data")
                            .HostMemory("output")
                            .TypeConstraint<string>("T"),
                        EnterOp);

// An exit op has one input and one output. It exits the current
// frame to its parent frame, and makes its input available to the
// parent frame.
class ExitOp : public OpKernel {
 public:
  explicit ExitOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    context->set_output(0, context->input(0));
  }

  bool IsExpensive() override { return false; }

  ~ExitOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(ExitOp);
};

REGISTER_KERNEL_BUILDER(Name("Exit").Device(DEVICE_CPU), ExitOp);

#define REGISTER_GPU_KERNEL(type) \
  REGISTER_KERNEL_BUILDER(        \
      Name("Exit").Device(DEVICE_GPU).TypeConstraint<type>("T"), ExitOp);

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);

#undef REGISTER_GPU_KERNEL

// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("Exit")
                            .Device(DEVICE_GPU)
                            .HostMemory("data")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        ExitOp);

// A next_iteration op has one input and one output. It makes its input
// available to the next iteration.
class NextIterationOp : public OpKernel {
 public:
  explicit NextIterationOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    context->set_output(0, context->input(0));
  }

  bool IsExpensive() override { return false; }

  ~NextIterationOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(NextIterationOp);
};

REGISTER_KERNEL_BUILDER(Name("NextIteration").Device(DEVICE_CPU),
                        NextIterationOp);

#define REGISTER_GPU_KERNEL(type)                                         \
  REGISTER_KERNEL_BUILDER(                                                \
      Name("NextIteration").Device(DEVICE_GPU).TypeConstraint<type>("T"), \
      NextIterationOp);

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);

#undef REGISTER_GPU_KERNEL

// A special GPU kernel for int32.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
REGISTER_KERNEL_BUILDER(Name("NextIteration")
                            .Device(DEVICE_GPU)
                            .HostMemory("data")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        NextIterationOp);

// A LoopCond op has one input and one output. The input is a boolean
// scalar representing the taken branches of the "pivot" Switch that
// determines loop termination. As a contract, any high-level front-end
// should always use port '0' of the "pivot" switches for loop exit.
class LoopCondOp : public OpKernel {
 public:
  explicit LoopCondOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    context->set_output(0, context->input(0));
  }

  bool IsExpensive() override { return false; }

  ~LoopCondOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(LoopCondOp);
};

REGISTER_KERNEL_BUILDER(Name("LoopCond").Device(DEVICE_CPU), LoopCondOp);
REGISTER_KERNEL_BUILDER(Name("LoopCond")
                            .Device(DEVICE_GPU)
                            .HostMemory("input")
                            .HostMemory("output"),
                        LoopCondOp);

// ControlTrigger kernels
REGISTER_KERNEL_BUILDER(Name("ControlTrigger").Device(DEVICE_CPU),
                        ControlTriggerOp);

REGISTER_KERNEL_BUILDER(Name("ControlTrigger").Device(DEVICE_GPU),
                        ControlTriggerOp);

}  // namespace tensorflow
<commit_msg>Clean up GPU kernel registrations for control flow ops. Change: 112492676<commit_after>/* Copyright 2015 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/core/kernels/control_flow_ops.h"

#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/platform/macros.h"
#include "tensorflow/core/public/tensor.h"

namespace tensorflow {

// A switch op has two inputs and two outputs. It forwards the value of
// Input:0 to the output specified by input:1. Input:1 is a boolean tensor.
// Input:0 is forwarded to output:0 if input:1 is false, otherwise to
// output:1.
class SwitchOp : public OpKernel {
 public:
  explicit SwitchOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    const Tensor& outputPorts = context->input(1);
    OP_REQUIRES(
        context, TensorShapeUtils::IsScalar(outputPorts.shape()),
        errors::InvalidArgument("The second input must be a scalar, "
                                "but it has shape ",
                                outputPorts.shape().ShortDebugString()));

    bool pred = outputPorts.scalar<bool>()();
    int port = (pred) ? 1 : 0;
    if (IsRefType(context->input_dtype(0))) {
      context->forward_ref_input_to_ref_output(0, port);
    } else {
      context->set_output(port, context->input(0));
    }
  }

  bool IsExpensive() override { return false; }

  ~SwitchOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(SwitchOp);
};

#define REGISTER_CPU_SWITCH(type)                         \
  REGISTER_KERNEL_BUILDER(Name("Switch")                  \
                              .Device(DEVICE_CPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_CPU_REF_SWITCH(type)                     \
  REGISTER_KERNEL_BUILDER(Name("RefSwitch")               \
                              .Device(DEVICE_CPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_GPU_SWITCH(type)                         \
  REGISTER_KERNEL_BUILDER(Name("Switch")                  \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_GPU_REF_SWITCH(type)                     \
  REGISTER_KERNEL_BUILDER(Name("RefSwitch")               \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("pred")         \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

TF_CALL_ALL_TYPES(REGISTER_CPU_SWITCH);
TF_CALL_ALL_TYPES(REGISTER_CPU_REF_SWITCH);

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_SWITCH);
REGISTER_GPU_SWITCH(bool);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_REF_SWITCH);
REGISTER_GPU_REF_SWITCH(bool);

#undef REGISTER_CPU_SWITCH
#undef REGISTER_CPU_REF_SWITCH
#undef REGISTER_GPU_SWITCH
#undef REGISTER_GPU_REF_SWITCH

// Special GPU kernels for int32 and string.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
#define REGISTER_GPU_HOST_KERNEL(type)                    \
  REGISTER_KERNEL_BUILDER(Name("Switch")                  \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("data")         \
                              .HostMemory("pred")         \
                              .HostMemory("output_false") \
                              .HostMemory("output_true")  \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

#define REGISTER_GPU_HOST_REF_KERNEL(type)                \
  REGISTER_KERNEL_BUILDER(Name("RefSwitch")               \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("data")         \
                              .HostMemory("pred")         \
                              .HostMemory("output_false") \
                              .HostMemory("output_true")  \
                              .TypeConstraint<type>("T"), \
                          SwitchOp)

REGISTER_GPU_HOST_KERNEL(int32);
REGISTER_GPU_HOST_REF_KERNEL(int32);
REGISTER_GPU_HOST_KERNEL(string);
REGISTER_GPU_HOST_REF_KERNEL(string);

#undef REGISTER_GPU_HOST_KERNEL
#undef REGISTER_GPU_HOST_REF_KERNEL

class RefSelectOp : public OpKernel {
 public:
  explicit RefSelectOp(OpKernelConstruction* context) : OpKernel(context) {
    OP_REQUIRES_OK(context, context->GetAttr("N", &num_ref_inputs_));
  }

  void Compute(OpKernelContext* context) override {
    const Tensor& index_tensor = context->input(0);
    OP_REQUIRES(
        context, TensorShapeUtils::IsScalar(index_tensor.shape()),
        errors::InvalidArgument("Index must be a scalar, "
                                "but it has shape ",
                                index_tensor.shape().ShortDebugString()));

    int32 index = index_tensor.scalar<int32>()();

    OP_REQUIRES(context, index >= 0 && index < num_ref_inputs_,
                errors::InvalidArgument("Index must be in the range [0, ",
                                        num_ref_inputs_, ") but got ", index));
    context->forward_ref_input_to_ref_output(index + 1, 0);
  }

  bool IsExpensive() override { return false; }

  ~RefSelectOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(RefSelectOp);

 private:
  int num_ref_inputs_;
};

#define REGISTER_CPU_REF_SELECT(type)                     \
  REGISTER_KERNEL_BUILDER(Name("RefSelect")               \
                              .Device(DEVICE_CPU)         \
                              .HostMemory("index")        \
                              .TypeConstraint<type>("T"), \
                          RefSelectOp)
TF_CALL_ALL_TYPES(REGISTER_CPU_REF_SELECT);

#undef REGISTER_CPU_REF_SWITCH

// A merge op has n inputs and two outputs. It forwards the value of the
// first input that becomes available to its first output, and the
// index of the first input to its second output.
class MergeOp : public OpKernel {
 public:
  explicit MergeOp(OpKernelConstruction* context) : OpKernel(context) {
    const DataType dt = context->input_type(0);
    const int num_in = context->num_inputs();
    OP_REQUIRES_OK(context, context->MatchSignature(DataTypeVector(num_in, dt),
                                                    {dt, DT_INT32}));
  }

  void Compute(OpKernelContext* context) override {
    bool input_seen = false;
    for (int i = 0; i < context->num_inputs(); ++i) {
      if (context->has_input(i)) {
        if (input_seen) {
          context->SetStatus(errors::Internal(
              "Merge can not have more than one valid input."));
          return;
        }
        input_seen = true;

        context->set_output(0, context->input(i));
        Tensor* value_index = nullptr;
        OP_REQUIRES_OK(context, context->allocate_output(1, TensorShape({}),
                                                         &value_index));
        value_index->scalar<int32>()() = i;
      }
    }
  }

  bool IsExpensive() override { return false; }

  ~MergeOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(MergeOp);
};

REGISTER_KERNEL_BUILDER(Name("Merge").Device(DEVICE_CPU), MergeOp);

#define REGISTER_GPU_KERNEL(type)                         \
  REGISTER_KERNEL_BUILDER(Name("Merge")                   \
                              .Device(DEVICE_GPU)         \
                              .TypeConstraint<type>("T")  \
                              .HostMemory("value_index"), \
                          MergeOp)

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
REGISTER_GPU_KERNEL(bool);

#undef REGISTER_GPU_KERNEL

// Special GPU kernels for int32 and string.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
#define REGISTER_GPU_HOST_KERNEL(type)                    \
  REGISTER_KERNEL_BUILDER(Name("Merge")                   \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("inputs")       \
                              .HostMemory("output")       \
                              .HostMemory("value_index")  \
                              .TypeConstraint<type>("T"), \
                          MergeOp)

REGISTER_GPU_HOST_KERNEL(int32);
REGISTER_GPU_HOST_KERNEL(string);

#undef REGISTER_GPU_HOST_KERNEL

// An enter op has one input and one output. It creates or finds
// the child frame that is uniquely identified by the frame_name,
// and makes its input available to the child frame.
class EnterOp : public OpKernel {
 public:
  explicit EnterOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    if (IsRefType(context->input_dtype(0))) {
      context->forward_ref_input_to_ref_output(0, 0);
    } else {
      context->set_output(0, context->input(0));
    }
  }

  bool IsExpensive() override { return false; }

  ~EnterOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(EnterOp);
};

REGISTER_KERNEL_BUILDER(Name("Enter").Device(DEVICE_CPU), EnterOp);
REGISTER_KERNEL_BUILDER(Name("RefEnter").Device(DEVICE_CPU), EnterOp);

#define REGISTER_GPU_KERNEL(type) \
  REGISTER_KERNEL_BUILDER(        \
      Name("Enter").Device(DEVICE_GPU).TypeConstraint<type>("T"), EnterOp)
#define REGISTER_GPU_REF_KERNEL(type) \
  REGISTER_KERNEL_BUILDER(            \
      Name("RefEnter").Device(DEVICE_GPU).TypeConstraint<type>("T"), EnterOp)

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_REF_KERNEL);
REGISTER_GPU_KERNEL(bool);
REGISTER_GPU_REF_KERNEL(bool);

#undef REGISTER_GPU_KERNEL
#undef REGISTER_GPU_REF_KERNEL

// Special GPU kernels for int32 and string.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
#define REGISTER_GPU_HOST_KERNEL(type)                    \
  REGISTER_KERNEL_BUILDER(Name("Enter")                   \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("data")         \
                              .HostMemory("output")       \
                              .TypeConstraint<type>("T"), \
                          EnterOp)

#define REGISTER_GPU_HOST_REF_KERNEL(type)                \
  REGISTER_KERNEL_BUILDER(Name("RefEnter")                \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("data")         \
                              .HostMemory("output")       \
                              .TypeConstraint<type>("T"), \
                          EnterOp)

REGISTER_GPU_HOST_KERNEL(int32);
REGISTER_GPU_HOST_REF_KERNEL(int32);
REGISTER_GPU_HOST_KERNEL(string);
REGISTER_GPU_HOST_REF_KERNEL(string);

#undef REGISTER_GPU_HOST_KERNEL
#undef REGISTER_GPU_HOST_REF_KERNEL

// An exit op has one input and one output. It exits the current
// frame to its parent frame, and makes its input available to the
// parent frame.
class ExitOp : public OpKernel {
 public:
  explicit ExitOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    context->set_output(0, context->input(0));
  }

  bool IsExpensive() override { return false; }

  ~ExitOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(ExitOp);
};

REGISTER_KERNEL_BUILDER(Name("Exit").Device(DEVICE_CPU), ExitOp);

#define REGISTER_GPU_KERNEL(type) \
  REGISTER_KERNEL_BUILDER(        \
      Name("Exit").Device(DEVICE_GPU).TypeConstraint<type>("T"), ExitOp);

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
REGISTER_GPU_KERNEL(bool);

#undef REGISTER_GPU_KERNEL

// Special GPU kernels for int32 and string.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
#define REGISTER_GPU_HOST_KERNEL(type)                    \
  REGISTER_KERNEL_BUILDER(Name("Exit")                    \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("data")         \
                              .HostMemory("output")       \
                              .TypeConstraint<type>("T"), \
                          ExitOp)

REGISTER_GPU_HOST_KERNEL(int32);
REGISTER_GPU_HOST_KERNEL(string);

#undef REGISTER_GPU_HOST_KERNEL

// A next_iteration op has one input and one output. It makes its input
// available to the next iteration.
class NextIterationOp : public OpKernel {
 public:
  explicit NextIterationOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    context->set_output(0, context->input(0));
  }

  bool IsExpensive() override { return false; }

  ~NextIterationOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(NextIterationOp);
};

REGISTER_KERNEL_BUILDER(Name("NextIteration").Device(DEVICE_CPU),
                        NextIterationOp);

#define REGISTER_GPU_KERNEL(type)                                         \
  REGISTER_KERNEL_BUILDER(                                                \
      Name("NextIteration").Device(DEVICE_GPU).TypeConstraint<type>("T"), \
      NextIterationOp)

TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER_GPU_KERNEL);
REGISTER_GPU_KERNEL(bool);

#undef REGISTER_GPU_KERNEL

// Special GPU kernels for int32 and string.
// TODO(b/25387198): Also enable int32 in device memory. This kernel
// registration requires all int32 inputs and outputs to be in host memory.
#define REGISTER_GPU_HOST_KERNEL(type)                    \
  REGISTER_KERNEL_BUILDER(Name("NextIteration")           \
                              .Device(DEVICE_GPU)         \
                              .HostMemory("data")         \
                              .HostMemory("output")       \
                              .TypeConstraint<type>("T"), \
                          NextIterationOp)

REGISTER_GPU_HOST_KERNEL(int32);
REGISTER_GPU_HOST_KERNEL(string);

#undef REGISTER_GPU_HOST_KERNEL

// A LoopCond op has one input and one output. The input is a boolean
// scalar representing the taken branches of the "pivot" Switch that
// determines loop termination. As a contract, any high-level front-end
// should always use port '0' of the "pivot" switches for loop exit.
class LoopCondOp : public OpKernel {
 public:
  explicit LoopCondOp(OpKernelConstruction* context) : OpKernel(context) {}

  void Compute(OpKernelContext* context) override {
    context->set_output(0, context->input(0));
  }

  bool IsExpensive() override { return false; }

  ~LoopCondOp() override {}

  TF_DISALLOW_COPY_AND_ASSIGN(LoopCondOp);
};

REGISTER_KERNEL_BUILDER(Name("LoopCond").Device(DEVICE_CPU), LoopCondOp);
REGISTER_KERNEL_BUILDER(Name("LoopCond")
                            .Device(DEVICE_GPU)
                            .HostMemory("input")
                            .HostMemory("output"),
                        LoopCondOp);

// ControlTrigger kernels
REGISTER_KERNEL_BUILDER(Name("ControlTrigger").Device(DEVICE_CPU),
                        ControlTriggerOp);

REGISTER_KERNEL_BUILDER(Name("ControlTrigger").Device(DEVICE_GPU),
                        ControlTriggerOp);

}  // namespace tensorflow
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s

struct X1 {
  X1();
};

struct X2 {
  X2();
  ~X2();
};

void vararg(...);

void f(X1 x1, X2 x2) {
  vararg(x1); // okay
  vararg(x2); // expected-error{{cannot pass object of non-trivial type 'X2' through variadic function; call will abort at runtime}}
}

namespace PR11131 {
  struct S;

  S &getS();

  void f(...);

  void g() {
    (void)sizeof(f(getS()));
  }
}
<commit_msg>Test that we correctly deal with multiple copy constructors when detecting non-trivial special members for varargs calls.<commit_after>// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s

struct X1 {
  X1();
};

struct X2 {
  X2();
  ~X2();
};

struct X3 {
  X3(const X3&) = default;
};

struct X4 {
  X4(const X4&) = default;
  X4(X4&);
};

void vararg(...);

void f(X1 x1, X2 x2, X3 x3, X4 x4) {
  vararg(x1); // OK
  vararg(x2); // expected-error{{cannot pass object of non-trivial type 'X2' through variadic function; call will abort at runtime}}
  vararg(x3); // OK
  vararg(x4); // expected-error{{cannot pass object of non-trivial type 'X4' through variadic function; call will abort at runtime}}
}

namespace PR11131 {
  struct S;

  S &getS();

  void f(...);

  void g() {
    (void)sizeof(f(getS()));
  }
}
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s

// Not trivially copyable because of the explicit destructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: DIFlagTypePassByReference
struct RefDtor {
  int i;
  ~RefDtor() {}
} refDtor;

// Not trivially copyable because of the explicit copy constructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: DIFlagTypePassByReference
struct RefCopy {
  int i;
  RefCopy() = default;
  RefCopy(RefCopy &Copy) {}
} refCopy;

// Not trivially copyable because of the explicit move constructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "RefMove",{{.*}}flags: DIFlagTypePassByReference
struct RefMove {
  int i;
  RefMove() = default;
  RefMove(RefMove &&Move) {}
} refMove;

// POD-like type even though it defines a destructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: DIFlagTypePassByValue
struct Podlike {
  int i;
  Podlike() = default;
  Podlike(Podlike &&Move) = default;
  ~Podlike() = default;
} podlike;

// This is a POD type.
// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: DIFlagTypePassByValue
struct Pod {
  int i;
} pod;

// This is definitely not a POD type.
// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: DIFlagTypePassByReference
struct Complex {
  Complex() {}
  Complex(Complex &Copy) : i(Copy.i) {};
  int i;
} complex;
<commit_msg>Remove redundant test<commit_after>// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s

// Not trivially copyable because of the explicit destructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "RefDtor",{{.*}}flags: DIFlagTypePassByReference
struct RefDtor {
  int i;
  ~RefDtor() {}
} refDtor;

// Not trivially copyable because of the explicit copy constructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "RefCopy",{{.*}}flags: DIFlagTypePassByReference
struct RefCopy {
  int i;
  RefCopy() = default;
  RefCopy(RefCopy &Copy) {}
} refCopy;

// POD-like type even though it defines a destructor.
// CHECK-DAG: !DICompositeType({{.*}}, name: "Podlike", {{.*}}flags: DIFlagTypePassByValue
struct Podlike {
  int i;
  Podlike() = default;
  Podlike(Podlike &&Move) = default;
  ~Podlike() = default;
} podlike;

// This is a POD type.
// CHECK-DAG: !DICompositeType({{.*}}, name: "Pod",{{.*}}flags: DIFlagTypePassByValue
struct Pod {
  int i;
} pod;

// This is definitely not a POD type.
// CHECK-DAG: !DICompositeType({{.*}}, name: "Complex",{{.*}}flags: DIFlagTypePassByReference
struct Complex {
  Complex() {}
  Complex(Complex &Copy) : i(Copy.i) {};
  int i;
} complex;
<|endoftext|>


<commit_before>#include "orwell/game/Robot.hpp"
#include "orwell/game/Team.hpp"

#include <iostream>
#include <unistd.h>
#include <cstdint>

#include <log4cxx/ndc.h>

#include "orwell/support/GlobalLogger.hpp"
#include "orwell/game/Item.hpp"
#include "orwell/game/Ruleset.hpp"
#include "orwell/game/Game.hpp"
#include "orwell/game/Robot.hpp"
#include "orwell/game/item/Flag.hpp"
#include "orwell/game/item/FlagDetector.hpp"

#include "Common.hpp"

using ::testing::_;

class TestOrwellGameItemFlagDetector : public ::testing::Test
{
protected:
	TestOrwellGameItemFlagDetector()
		: m_type("flag")
		, m_name("FLAG")
		, m_colourCode(12)
		//, m_timeToCapture(boost::posix_time::milliseconds(30))
		//, m_pointsOnCapture(1)
		//, m_flag(m_name, m_colourCode, m_timeToCapture, m_pointsOnCapture)
		, m_teamName("Team Name")
		, m_robotName("Robot Name")
		, m_robotId("robot_id")
		, m_videoPort(42)
		, m_commandPort(43)
		, m_team(m_teamName)
		, m_robot(std::make_shared< orwell::game::Robot >(
				m_fakeSystemProxy,
				m_robotName,
				m_robotId,
				m_team,
				m_videoPort,
				m_commandPort))
		, m_flagDetector(
				m_contactHandler,
				m_robot)
	{
	}

	virtual void SetUp()
	{
		orwell::game::Item::CreateItem(
				m_type,
				m_name,
				m_rfids,
				m_colourCode,
				m_ruleset);
	}

	virtual void TearDown()
	{
	}

	std::string m_type;
	std::string const m_name;
	std::set< std::string > m_rfids;
	int32_t const m_colourCode;
	orwell::game::Ruleset m_ruleset;
	//orwell::game::item::Flag m_flag;
	FakeSystemProxy m_fakeSystemProxy;
	std::string const m_teamName;
	std::string const m_robotName;
	std::string const m_robotId;
	uint16_t const m_videoPort;
	uint16_t const m_commandPort;
	orwell::game::Team m_team;
	std::shared_ptr< orwell::game::Robot > m_robot;
	FakeContactHandler m_contactHandler;
	orwell::game::item::FlagDetector m_flagDetector;
};

TEST_F(TestOrwellGameItemFlagDetector, Frontier)
{
	EXPECT_CALL(m_contactHandler, robotIsInContactWith(_, _)).Times(0);
	EXPECT_CALL(m_contactHandler, robotDropsContactWith(_, _)).Times(0);
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
}

TEST_F(TestOrwellGameItemFlagDetector, Frontier_Colour_Frontier_Outside)
{
	EXPECT_CALL(m_contactHandler, robotIsInContactWith(_, _)).Times(1);
	EXPECT_CALL(m_contactHandler, robotDropsContactWith(_, _)).Times(1);
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			m_colourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kNoneColourCode,
			boost::posix_time::microsec_clock::local_time());
}

TEST_F(TestOrwellGameItemFlagDetector, Frontier_Colour_Frontier)
{
	EXPECT_CALL(m_contactHandler, robotIsInContactWith(_, _)).Times(1);
	EXPECT_CALL(m_contactHandler, robotDropsContactWith(_, _)).Times(0);
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			m_colourCode,
			boost::posix_time::microsec_clock::local_time());
}

int main(int argc, char ** argv)
{
	orwell::support::GlobalLogger::Create("test_orwell_game_item_FlagDetector", "test_orwell_game_item_FlagDetector.log", true);
	log4cxx::NDC ndc("test_orwell_game_item_FlagDetector");
	ORWELL_LOG_INFO("Test starts\n");
	::testing::InitGoogleTest(&argc, argv);
	int aResult = RUN_ALL_TESTS();
	orwell::support::GlobalLogger::Clear();
	return aResult;
}
<commit_msg>Clean-up<commit_after>#include "orwell/game/Robot.hpp"
#include "orwell/game/Team.hpp"

#include <iostream>
#include <unistd.h>
#include <cstdint>

#include <log4cxx/ndc.h>

#include "orwell/support/GlobalLogger.hpp"
#include "orwell/game/Item.hpp"
#include "orwell/game/Ruleset.hpp"
#include "orwell/game/Game.hpp"
#include "orwell/game/Robot.hpp"
#include "orwell/game/item/Flag.hpp"
#include "orwell/game/item/FlagDetector.hpp"

#include "Common.hpp"

using ::testing::_;

class TestOrwellGameItemFlagDetector : public ::testing::Test
{
protected:
	TestOrwellGameItemFlagDetector()
		: m_type("flag")
		, m_name("FLAG")
		, m_colourCode(12)
		, m_teamName("Team Name")
		, m_robotName("Robot Name")
		, m_robotId("robot_id")
		, m_videoPort(42)
		, m_commandPort(43)
		, m_team(m_teamName)
		, m_robot(std::make_shared< orwell::game::Robot >(
				m_fakeSystemProxy,
				m_robotName,
				m_robotId,
				m_team,
				m_videoPort,
				m_commandPort))
		, m_flagDetector(
				m_contactHandler,
				m_robot)
	{
	}

	virtual void SetUp()
	{
		orwell::game::Item::CreateItem(
				m_type,
				m_name,
				m_rfids,
				m_colourCode,
				m_ruleset);
	}

	virtual void TearDown()
	{
	}

	std::string m_type;
	std::string const m_name;
	std::set< std::string > m_rfids;
	int32_t const m_colourCode;
	orwell::game::Ruleset m_ruleset;
	FakeSystemProxy m_fakeSystemProxy;
	std::string const m_teamName;
	std::string const m_robotName;
	std::string const m_robotId;
	uint16_t const m_videoPort;
	uint16_t const m_commandPort;
	orwell::game::Team m_team;
	std::shared_ptr< orwell::game::Robot > m_robot;
	FakeContactHandler m_contactHandler;
	orwell::game::item::FlagDetector m_flagDetector;
};

TEST_F(TestOrwellGameItemFlagDetector, Frontier)
{
	EXPECT_CALL(m_contactHandler, robotIsInContactWith(_, _)).Times(0);
	EXPECT_CALL(m_contactHandler, robotDropsContactWith(_, _)).Times(0);
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
}

TEST_F(TestOrwellGameItemFlagDetector, Frontier_Colour_Frontier_Outside)
{
	EXPECT_CALL(m_contactHandler, robotIsInContactWith(_, _)).Times(1);
	EXPECT_CALL(m_contactHandler, robotDropsContactWith(_, _)).Times(1);
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			m_colourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kNoneColourCode,
			boost::posix_time::microsec_clock::local_time());
}

TEST_F(TestOrwellGameItemFlagDetector, Frontier_Colour_Frontier)
{
	EXPECT_CALL(m_contactHandler, robotIsInContactWith(_, _)).Times(1);
	EXPECT_CALL(m_contactHandler, robotDropsContactWith(_, _)).Times(0);
	m_flagDetector.setColour(
			orwell::game::item::FlagDetector::kFrontierColourCode,
			boost::posix_time::microsec_clock::local_time());
	m_flagDetector.setColour(
			m_colourCode,
			boost::posix_time::microsec_clock::local_time());
}

int main(int argc, char ** argv)
{
	std::string const aName = "test_orwell_game_item_FlagDetector";
	orwell::support::GlobalLogger::Create(aName, aName, true);
	log4cxx::NDC ndc(aName);
	ORWELL_LOG_INFO("Test starts\n");
	::testing::InitGoogleTest(&argc, argv);
	int aResult = RUN_ALL_TESTS();
	orwell::support::GlobalLogger::Clear();
	return aResult;
}
<|endoftext|>


<commit_before>#include <stan/math/mix/scal.hpp>
#include <test/unit/math/rev/scal/fun/util.hpp>
#include <gtest/gtest.h>
#include <vector>

std::vector<double> test_fun(double y) {
  using stan::math::std_normal_lpdf;
  using stan::math::var;

  var y_var = y;
  std::vector<var> x;
  x.push_back(y_var);

  var logp = std_normal_lpdf<false>(y_var);
  std::vector<double> grad;
  logp.grad(x, grad);
  return grad;
}

TEST(ProbAgradDistributionsStdNormal, derivatives) {
  using stan::math::fvar;
  using stan::math::std_normal_lpdf;

  std::vector<double> grad = test_fun(0);

  fvar<double> lp = std_normal_lpdf<false>(0);
  EXPECT_FLOAT_EQ(grad[2], lp.tangent());

  fvar<fvar<double>> y(1.0);
  fvar<double> x(1.0, 2.0);
  EXPECT_NO_THROW(std_normal_lpdf(y));
  EXPECT_FLOAT_EQ(std_normal_lpdf(x).val_, -1.418938533204672669541);
  EXPECT_FLOAT_EQ(std_normal_lpdf(x).d_, -2);
}

TEST(ProbAgradDistributionsStdNormal, FvarVar_1stDeriv) {
  using stan::math::fvar;
  using stan::math::std_normal_lpdf;
  using stan::math::var;

  fvar<var> y_(2, 1);
  fvar<var> logp = std_normal_lpdf(y_);

  AVEC y = createAVEC(y_.val_);
  VEC g;
  logp.val_.grad(y, g);
  EXPECT_FLOAT_EQ(-2, g[0]);
}
<commit_msg>Fix test<commit_after>#include <stan/math/mix/scal.hpp>
#include <test/unit/math/rev/scal/fun/util.hpp>
#include <gtest/gtest.h>
#include <vector>

std::vector<double> test_fun(double y) {
  using stan::math::std_normal_lpdf;
  using stan::math::var;

  var y_var = y;
  std::vector<var> x;
  x.push_back(y_var);

  var logp = std_normal_lpdf<false>(y_var);
  std::vector<double> grad;
  logp.grad(x, grad);
  return grad;
}

TEST(ProbAgradDistributionsStdNormal, derivatives) {
  using stan::math::fvar;
  using stan::math::std_normal_lpdf;

  std::vector<double> grad = test_fun(0);

  fvar<double> lp = std_normal_lpdf<false>(fvar<double>(0));
  EXPECT_FLOAT_EQ(grad[0], lp.tangent());

  fvar<fvar<double>> y(1.0);
  fvar<double> x(1.0, 2.0);
  EXPECT_NO_THROW(std_normal_lpdf(y));
  EXPECT_FLOAT_EQ(std_normal_lpdf(x).val_, -1.418938533204672669541);
  EXPECT_FLOAT_EQ(std_normal_lpdf(x).d_, -2);
}

TEST(ProbAgradDistributionsStdNormal, FvarVar_1stDeriv) {
  using stan::math::fvar;
  using stan::math::std_normal_lpdf;
  using stan::math::var;

  fvar<var> y_(2, 1);
  fvar<var> logp = std_normal_lpdf(y_);

  AVEC y = createAVEC(y_.val_);
  VEC g;
  logp.val_.grad(y, g);
  EXPECT_FLOAT_EQ(-2, g[0]);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of meegotouch-controlpanelapplets.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it 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.
**
****************************************************************************/

#include "ut_offlineapplet.h"
#include <DcpWidgetTypes>
#include <DcpWidget>
#include <MMessageBox>
#include <MDialog>
#include <MApplication>
#include <MInfoBanner>

#include "offlineapplet.h"
#include "offlinebrief.h"

#ifdef HAVE_QMSYSTEM
#  include "qmdevicemode_stub.h"
#endif

#include "signalchecker.h"

#define DEBUG
#include "../../src/debug.h"

static const char *signalValuesChanged = SIGNAL (valuesChanged ());

int   argc = 1;
char *argv[] = {
    (char *) "./ut_offlineapplet",
    NULL };
/******************************************************************************
 * Stub for MMessageBox
 */
static QString mmessageBoxText;
static int mmessageBoxApereance;

MMessageBox::MMessageBox (
    const QString          &title,
    const QString          &text,
    M::StandardButtons      buttons)
{
    SYS_DEBUG ("");
    Q_UNUSED (title);
    Q_UNUSED (buttons);

    mmessageBoxText = text;
}

int
MDialog::result () const
{
    return MDialog::Accepted;
}

void
MDialog::appear (MSceneWindow::DeletionPolicy policy)
{
    Q_UNUSED (policy);

    mmessageBoxApereance = true;
}

/******************************************************************************
 * Stub for MNotification
 */
static QString mbannerSubtitle;

MInfoBanner::MInfoBanner (BannerType type)
{
    Q_UNUSED (type);
}

MInfoBanner::~MInfoBanner ()
{
}

void
MInfoBanner::setBodyText (const QString &text)
{
    mbannerSubtitle = text;
}

/******************************************************************************
 * Ut_offlineApplet implementation.
 */
void
Ut_OfflineApplet::init()
{
    mmessageBoxText = "";
    mmessageBoxApereance = false;
    mbannerSubtitle = "";
}

void
Ut_OfflineApplet::cleanup()
{
}

void
Ut_OfflineApplet::initTestCase()
{
    m_App = new MApplication(argc, argv);
    m_App->setQuitOnLastWindowClosed (false);

    m_Applet = new OfflineApplet;
}

void
Ut_OfflineApplet::cleanupTestCase()
{
    delete m_Applet;
    m_Applet = 0;

    m_App->deleteLater ();
    m_App = 0;
}

void
Ut_OfflineApplet::testTitle ()
{
    QString title = m_Applet->title();
    QVERIFY (title.isEmpty());
}

void
Ut_OfflineApplet::testMenu ()
{
    QVector<MAction *> menu = m_Applet->viewMenuItems();
    QVERIFY (menu.isEmpty());
}

void
Ut_OfflineApplet::testConstructWidget ()
{
    DcpWidget* widget = m_Applet->constructWidget(1);
    QVERIFY (!widget);
}

void
Ut_OfflineApplet::testBriefConstruct ()
{
    #ifdef HAVE_QMSYSTEM
    DcpBrief* widget;

    gQmDeviceModeStub->stubReset ();

    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);
    widget = m_Applet->constructBrief(1);

    QVERIFY (widget);
    QCOMPARE (int(widget->widgetTypeID()), int(DcpWidgetType::Button));
    delete widget;
    #endif
}

void
Ut_OfflineApplet::testCurrentText ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief brief;

    brief.m_LastMode = MeeGo::QmDeviceMode::Normal;
    QCOMPARE (brief.currentText(), qtTrId("qtn_offl_activate"));

    brief.m_LastMode = MeeGo::QmDeviceMode::Flight;
    QCOMPARE (brief.currentText(), qtTrId("qtn_offl_deactivate"));

/*
 * Brief never should be empty!
 *
    brief.m_LastMode = MeeGo::QmDeviceMode::Error;
    QVERIFY (brief.currentText().isEmpty());
 */
    brief.m_LastMode = MeeGo::QmDeviceMode::Error;
    QVERIFY (brief.currentText().isEmpty() == false);
    #endif
}

void
Ut_OfflineApplet::testBriefInit ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();

    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));
    delete brief;

    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Flight);
    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    delete brief;
    #endif
}

void
Ut_OfflineApplet::testBriefValueText ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();
    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));

    SignalChecker m_sChecker(brief);
    m_sChecker.addSignalChecker(signalValuesChanged);

    m_sChecker.increaseSigCounter(signalValuesChanged);
    brief->devModeChanged(MeeGo::QmDeviceMode::Flight);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    m_sChecker.check();

    m_sChecker.increaseSigCounter(signalValuesChanged);
    brief->devModeChanged(MeeGo::QmDeviceMode::Normal);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));
    delete brief;
    #endif
}

void
Ut_OfflineApplet::testBriefSetToggle ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();
    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));

    SignalChecker m_sChecker(brief);
    m_sChecker.addSignalChecker(signalValuesChanged);

    // This should not change the text
    brief->setToggle(true);
    QCOMPARE (mbannerSubtitle, QString ("<p>") + qtTrId("qtn_offl_entering") + "</p>");

    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));
    QCOMPARE (gQmDeviceModeStub->stubCallCount("setMode"), 1);
    QCOMPARE (gQmDeviceModeStub->stubLastParameters<MeeGo::QmDeviceMode::DeviceMode> (0), MeeGo::QmDeviceMode::Flight);

    m_sChecker.increaseSigCounter(signalValuesChanged);
    brief->devModeChanged(MeeGo::QmDeviceMode::Flight);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    m_sChecker.check();

    // This should not change the text nor the QmDeviceMode
    brief->setToggle(true);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    QCOMPARE (gQmDeviceModeStub->stubCallCount("setMode"), 1);
    QCOMPARE (gQmDeviceModeStub->stubLastParameters<MeeGo::QmDeviceMode::DeviceMode> (0), MeeGo::QmDeviceMode::Flight);

    delete brief;
    #endif
}

void
Ut_OfflineApplet::testProcessDialogResult()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();
    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Flight);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));

    SignalChecker m_sChecker(brief);
    m_sChecker.addSignalChecker(signalValuesChanged);

    brief->setToggle(true);
    QCOMPARE(mmessageBoxText, qtTrId("qtn_offl_exiting"));
    QVERIFY(mmessageBoxApereance);
    brief->processDialogResult();
    QCOMPARE (gQmDeviceModeStub->stubCallCount("setMode"), 1);
    QCOMPARE (gQmDeviceModeStub->stubLastParameters<MeeGo::QmDeviceMode::DeviceMode> (0), MeeGo::QmDeviceMode::Normal);

    delete brief;
    #endif
}

QTEST_APPLESS_MAIN(Ut_OfflineApplet)

<commit_msg>Fixes: failing testcase: ut_offlineapplet<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of meegotouch-controlpanelapplets.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it 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.
**
****************************************************************************/
#include "ut_offlineapplet.h"
#include <DcpWidgetTypes>
#include <DcpWidget>
#include <MMessageBox>
#include <MDialog>
#include <MApplication>
#include <MBanner>

#include "offlineapplet.h"
#include "offlinebrief.h"

#ifdef HAVE_QMSYSTEM
#  include "qmdevicemode_stub.h"
#endif

#include "signalchecker.h"

#define DEBUG
#include "../../src/debug.h"

static const char *signalValuesChanged = SIGNAL (valuesChanged ());

int   argc = 1;
char *argv[] = {
    (char *) "./ut_offlineapplet",
    NULL };
/******************************************************************************
 * Stub for MMessageBox
 */
static QString mmessageBoxText;
static int mmessageBoxApereance;

MMessageBox::MMessageBox (
    const QString          &title,
    const QString          &text,
    M::StandardButtons      buttons)
{
    SYS_DEBUG ("");
    Q_UNUSED (title);
    Q_UNUSED (buttons);

    mmessageBoxText = text;
}

int
MDialog::result () const
{
    return MDialog::Accepted;
}

void
MDialog::appear (MSceneWindow::DeletionPolicy policy)
{
    Q_UNUSED (policy);

    mmessageBoxApereance = true;
}

/******************************************************************************
 * Stub for MNotification
 */
static QString mbannerSubtitle;

MBanner::MBanner ()
{
}

MBanner::~MBanner ()
{
}

void
MBanner::setTitle (const QString &text)
{
    mbannerSubtitle = text;
}

/******************************************************************************
 * Ut_offlineApplet implementation.
 */
void
Ut_OfflineApplet::init()
{
    mmessageBoxText = "";
    mmessageBoxApereance = false;
    mbannerSubtitle = "";
}

void
Ut_OfflineApplet::cleanup()
{
}

void
Ut_OfflineApplet::initTestCase()
{
    m_App = new MApplication(argc, argv);
    m_App->setQuitOnLastWindowClosed (false);

    m_Applet = new OfflineApplet;
}

void
Ut_OfflineApplet::cleanupTestCase()
{
    delete m_Applet;
    m_Applet = 0;

    m_App->deleteLater ();
    m_App = 0;
}

void
Ut_OfflineApplet::testTitle ()
{
    QString title = m_Applet->title();
    QVERIFY (title.isEmpty());
}

void
Ut_OfflineApplet::testMenu ()
{
    QVector<MAction *> menu = m_Applet->viewMenuItems();
    QVERIFY (menu.isEmpty());
}

void
Ut_OfflineApplet::testConstructWidget ()
{
    DcpWidget* widget = m_Applet->constructWidget(1);
    QVERIFY (!widget);
}

void
Ut_OfflineApplet::testBriefConstruct ()
{
    #ifdef HAVE_QMSYSTEM
    DcpBrief* widget;

    gQmDeviceModeStub->stubReset ();

    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);
    widget = m_Applet->constructBrief(1);

    QVERIFY (widget);
    QCOMPARE (int(widget->widgetTypeID()), int(DcpWidgetType::Button));
    delete widget;
    #endif
}

void
Ut_OfflineApplet::testCurrentText ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief brief;

    brief.m_LastMode = MeeGo::QmDeviceMode::Normal;
    QCOMPARE (brief.currentText(), qtTrId("qtn_offl_activate"));

    brief.m_LastMode = MeeGo::QmDeviceMode::Flight;
    QCOMPARE (brief.currentText(), qtTrId("qtn_offl_deactivate"));

/*
 * Brief never should be empty!
 *
    brief.m_LastMode = MeeGo::QmDeviceMode::Error;
    QVERIFY (brief.currentText().isEmpty());
 */
    brief.m_LastMode = MeeGo::QmDeviceMode::Error;
    QVERIFY (brief.currentText().isEmpty() == false);
    #endif
}

void
Ut_OfflineApplet::testBriefInit ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();

    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));
    delete brief;

    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Flight);
    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    delete brief;
    #endif
}

void
Ut_OfflineApplet::testBriefValueText ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();
    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));

    SignalChecker m_sChecker(brief);
    m_sChecker.addSignalChecker(signalValuesChanged);

    m_sChecker.increaseSigCounter(signalValuesChanged);
    brief->devModeChanged(MeeGo::QmDeviceMode::Flight);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    m_sChecker.check();

    m_sChecker.increaseSigCounter(signalValuesChanged);
    brief->devModeChanged(MeeGo::QmDeviceMode::Normal);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));
    delete brief;
    #endif
}

void
Ut_OfflineApplet::testBriefSetToggle ()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();
    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Normal);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));

    SignalChecker m_sChecker(brief);
    m_sChecker.addSignalChecker(signalValuesChanged);

    // This should not change the text
    brief->setToggle(true);
    QCOMPARE (mbannerSubtitle, qtTrId("qtn_offl_entering"));

    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_activate"));
    QCOMPARE (gQmDeviceModeStub->stubCallCount("setMode"), 1);
    QCOMPARE (gQmDeviceModeStub->stubLastParameters<MeeGo::QmDeviceMode::DeviceMode> (0), MeeGo::QmDeviceMode::Flight);

    m_sChecker.increaseSigCounter(signalValuesChanged);
    brief->devModeChanged(MeeGo::QmDeviceMode::Flight);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    m_sChecker.check();

    // This should not change the text nor the QmDeviceMode
    brief->setToggle(true);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));
    QCOMPARE (gQmDeviceModeStub->stubCallCount("setMode"), 1);
    QCOMPARE (gQmDeviceModeStub->stubLastParameters<MeeGo::QmDeviceMode::DeviceMode> (0), MeeGo::QmDeviceMode::Flight);

    delete brief;
    #endif
}

void
Ut_OfflineApplet::testProcessDialogResult()
{
    #ifdef HAVE_QMSYSTEM
    OfflineBrief *brief;

    gQmDeviceModeStub->stubReset ();
    gQmDeviceModeStub->stubSetReturnValue<MeeGo::QmDeviceMode::DeviceMode> (
        "getMode", MeeGo::QmDeviceMode::Flight);

    brief = new OfflineBrief();
    QVERIFY (brief);
    QCOMPARE (brief->valueText(), qtTrId("qtn_offl_deactivate"));

    SignalChecker m_sChecker(brief);
    m_sChecker.addSignalChecker(signalValuesChanged);

    brief->setToggle(true);
    QCOMPARE(mmessageBoxText, qtTrId("qtn_offl_exiting"));
    QVERIFY(mmessageBoxApereance);
    brief->processDialogResult();
    QCOMPARE (gQmDeviceModeStub->stubCallCount("setMode"), 1);
    QCOMPARE (gQmDeviceModeStub->stubLastParameters<MeeGo::QmDeviceMode::DeviceMode> (0), MeeGo::QmDeviceMode::Normal);

    delete brief;
    #endif
}

QTEST_APPLESS_MAIN(Ut_OfflineApplet)

<|endoftext|>