<commit_before>/***********************************************
 * Author: Jun Jiang - jiangjun4@sina.com
 * Create: 2017-07-25 16:33
 * Last modified : 2017-07-25 16:33
 * Filename      : Matrix.h
 * Description   : Base Data Structure
 **********************************************/

#include "algebra/Matrix.h"
#include "algebra/MatrixHelper.h"
#include "utils/ParallelOperator.h"
#include <random>
#include <string.h>
#include <iostream>
#include <stdio.h>

using abcdl::utils::ParallelOperator;

namespace abcdl{
namespace algebra{

template<class T>
Matrix<T>::Matrix(){
    _rows = 0;
    _cols = 0;
    _data = nullptr;
}

template<class T>
Matrix<T>::Matrix(const size_t rows, const size_t cols){
    _rows = rows;
    _cols = cols;
    _data = new T[_rows * _cols];
    memset(_data, 0, sizeof(T) * _rows * _cols);
}

template<class T>
Matrix<T>::Matrix(const T& value,
                  const size_t rows,
                  const size_t cols){
    _rows = rows;
    _cols = cols;
    _data = new T[_rows * _cols];
    if(value == 0 || value == static_cast<T>(-1)){
        memset(_data, value, sizeof(T) * _rows * _cols);
    }else{
        auto lamda = [](T* a, const T& b){ *a = b; };
        ParallelOperator po;
        po.parallel_mul2one<T>(_data, get_size(), value, lamda);
    }
}

template<class T>
Matrix<T>::Matrix(const T* data,
                  const size_t rows,
                  const size_t cols){
    _rows = rows;
    _cols = cols;
    _data = new T[_rows * _cols];
    memcpy(_data, data, sizeof(T) * _rows * _cols);
}

template<class T>
Matrix<T>::~Matrix(){
    if(_data != nullptr){
        delete[] _data;
        _data = nullptr;
    }
}

template<class T>
void Matrix<T>::set_shallow_data(T* data,
                                 const size_t rows,
                                 const size_t cols){
    if(_data != nullptr){
        delete[] _data;
    }
    _data = data;
    _rows = rows;
    _cols = cols;
}

template<class T>
Matrix<T> Matrix<T>::get_row(const size_t row_id, const size_t row_size) const{
    Matrix<T> mat;
	get_row(&mat, row_id, row_size);
	return mat;
}

template<class T>
void Matrix<T>::get_row(Matrix<T>* mat,
                        const size_t row_id,
                        const size_t row_size) const{
    CHECK(row_id + row_size <= _rows);
	T* data = new T[row_size * _cols];
	memcpy(data, &_data[row_id * _cols], sizeof(T) * row_size * _cols);
	mat->set_shallow_data(data, row_size, _cols);
}

template<class T>
void Matrix<T>::set_row(const Matrix<T>& mat){
    set_row(0, mat);
}

template<class T>
void Matrix<T>::set_row(const size_t row_id, const Matrix<T>& mat){
    CHECK(_cols == mat.cols());
    CHECK(row_id + mat.rows() <= _rows);
    memcpy(&_data[row_id * _cols], mat.data(), sizeof(T) * mat.get_size());
}

template<class T>
void Matrix<T>::insert_row(const Matrix<T>& mat){
    insert_row(_rows, mat);
}
template<class T>
void Matrix<T>::insert_row(const size_t row_id, const Matrix<T>& mat){

    if(get_size() == 0){
        set_data(mat.data(), mat.rows(), mat.cols());

        return;
    }

    CHECK(_cols == mat.cols());

    T* data = new T[(_rows + mat.rows()) * _cols];

    if(row_id > 0){
        memcpy(data, _data, sizeof(T) * row_id * _cols);
    }
    memcpy(&data[row_id * _cols], mat.data(), sizeof(T) * mat.get_size());
    if(row_id < _rows){
        memcpy(&data[(row_id + mat.rows()) * _cols], &_data[row_id * _cols], sizeof(T) * (_rows - row_id) * _cols);
    }
    set_shallow_data(data, _rows + mat.rows(), _cols);
}

template<class T>
Matrix<T> Matrix<T>::get_col(const size_t col_id, const size_t col_size) const{
    Matrix<T> mat;
	get_col(&mat, col_id, col_size);
    return mat;
}

template<class T>
void Matrix<T>::get_col(Matrix<T>* mat,
                        const size_t col_id,
                        const size_t col_size) const{
    CHECK(col_id + col_size <= _cols);
	T* data = new T[_rows * col_size];
	for(size_t i = 0; i != _rows; i++){
		memcpy(&data[i * col_size], &_data[i * col_size + col_id], sizeof(T) * col_size);
	}
	mat->set_shallow_data(data, _rows, col_size);
}

template<class T>
void Matrix<T>::set_col(const Matrix<T>& mat){
    set_col(0, mat);
}

template<class T>
void Matrix<T>::set_col(const size_t col_id, const Matrix<T>& mat){
    CHECK(mat.rows() == _rows);
    CHECK(col_id + mat.cols() <= _cols);
    T* sub_data   = mat.data();
    size_t sub_cols =  mat.cols();

    for(size_t i = 0; i != _rows; i++){
        memcpy(&_data[i * _cols + col_id], &sub_data[i * sub_cols], sizeof(T) * sub_cols);
    }
}

template<class T>
void Matrix<T>::insert_col(const Matrix<T>& mat){
    set_col(0, mat);
}

template<class T>
void Matrix<T>::insert_col(const size_t col_id, const Matrix<T>& mat){
    CHECK(mat.rows() == _rows);
    CHECK(col_id <= _cols);

    size_t sub_cols = mat.cols();
    size_t new_cols = _cols + sub_cols;
    T* sub_data   = mat.data();

    T* data = new T[_rows * new_cols];
    for(size_t i = 0; i != _rows; i++){
        if(col_id > 0){
            memcpy(&data[i * new_cols], &_data[i * _cols], sizeof(T) * sub_cols);
        }
        memcpy(&data[i * new_cols + sub_cols], &sub_data[i * sub_cols], sizeof(T) * sub_cols);
        if(col_id != _cols){
            memcpy(&data[i * new_cols + col_id + sub_cols], &_data[i * _cols + col_id], sizeof(T) * (_cols - col_id));
        }
    }

    set_shallow_data(data, _rows, new_cols);
}

template<class T>
Matrix<T> Matrix<T>::clone() const{
    return Matrix<T>(_data, _rows, _cols);
}
template<class T>
void Matrix<T>::clone(Matrix<T>& mat) const{
    mat.set_data(_data, _rows, _cols);
}

template<class T>
void Matrix<T>::reset(const T& value){
   reset(value, _rows, _cols);
}

template<class T>
void Matrix<T>::reset(const T& value,
                      const size_t rows,
                      const size_t cols){
    size_t size = rows * cols;
    if(get_size() != size){
        if(_data != nullptr){
            delete[] _data;
        }
        _data = new T[size];
        _rows = rows;
        _cols = cols;
    }

    if(value == 0 || value == static_cast<T>(-1)){
        memset(_data, value, sizeof(T) * size);
    }else{
        auto lamda = [](T* a, const T& b){ *a = b; };
        ParallelOperator po;
        po.parallel_mul2one<T>(_data, size, value, lamda);
    }
}

template<class T>
Matrix<T> Matrix<T>::Ts(){
    MatrixHelper<T> mh;
    Matrix<T> mat;
    mh.transpose(mat, *this);
    return mat;
}

template<class T>
Matrix<T>& Matrix<T>::transpose(){
    MatrixHelper<T> mh;
    mh.transpose(*this, *this);
	return *this;
}

template<class T>
void Matrix<T>::display(const std::string& split) const{
    printf("[%ld*%ld][\n", _rows, _cols);
    for(size_t i = 0; i != _rows; i++){
        printf("row[%ld][", i);
        for(size_t j = 0; j != _cols; j++){
            printf("%s", std::to_string(_data[i * _cols + j]).c_str());
            if(j != this->_cols - 1){
                printf("%s", split.c_str());
            }
        }
        printf("]\n");
    }
    printf("]\n");
}

template<class T>
RandomMatrix<T>::RandomMatrix(size_t rows,
                              size_t cols,
                              const T& mean_value,
                              const T& stddev,
                              const T& min,
                              const T& max) : Matrix<T>(rows, cols){
    _mean_value = mean_value;
    _stddev     = stddev;
    _min        = min;
    _max        = max;

    reset();
}

template<class T>
void RandomMatrix<T>::reset(){
    T scale = _max - _min;
    T min   = _min;
    T max   = _max;

    ParallelOperator po;
    size_t size = this->_rows * this->_cols;
    T* data = this->_data;
    size_t block_size = po.get_block_size(size);
    size_t num_thread = po.get_num_thread(size, block_size);
    std::vector<std::thread> threads(num_thread);
    std::default_random_engine engine(std::chrono::system_clock::now().time_since_epoch().count());
    std::normal_distribution<T> distribution(_mean_value, _stddev);

    for(size_t i = 0; i != num_thread; i++){
        threads[i] = std::thread(
            [&data, max, min, scale, &distribution, &engine](size_t start_idx, size_t end_idx){
                for(size_t ti = start_idx; ti != end_idx; ti++){
                    T value = static_cast<T>(distribution(engine));
                    if(max == min || value == max || value == min){
                        data[ti] = value;
                    }else if(value > max){
                        real step = (value - min)/scale;
                        value = min + (step - (int)step) * scale;
                    }else{
                        real step = (max - value)/scale;
                        value = min + (step - (int)step) * scale;
                    }
                }
            }, i * block_size, std::min(size, (i + 1) * block_size)
        );
    }

    for(auto& thread : threads){
        thread.join();
    }
}

template<class T>
void RandomMatrix<T>::reset(size_t rows,
                            size_t cols,
                            const T& mean_value,
                            const T& stddev,
                            const T& min,
                            const T& max){
    if(rows * cols != this->_rows * this->_cols){
        if(this->_data != nullptr){
            delete[] this->_data;
        }
        this->_data = new T[rows * cols];
    }

    this->_rows = rows;
    this->_cols = cols;
    _mean_value = mean_value;
    _stddev     = stddev;
    _min        = min;
    _max        = max;

    reset();
}

template class Matrix<int>;
template class Matrix<float>;
template class Matrix<double>;
template class Matrix<size_t>;

template class RandomMatrix<float>;
}//namespace algebra
}//namespace abcdl
<commit_msg>add display function parameters<commit_after>/***********************************************
 * Author: Jun Jiang - jiangjun4@sina.com
 * Create: 2017-07-25 16:33
 * Last modified : 2017-07-25 16:33
 * Filename      : Matrix.h
 * Description   : Base Data Structure
 **********************************************/

#include "algebra/Matrix.h"
#include "algebra/MatrixHelper.h"
#include "utils/ParallelOperator.h"
#include <random>
#include <string.h>
#include <iostream>
#include <stdio.h>

using abcdl::utils::ParallelOperator;

namespace abcdl{
namespace algebra{

template<class T>
Matrix<T>::Matrix(){
    _rows = 0;
    _cols = 0;
    _data = nullptr;
}

template<class T>
Matrix<T>::Matrix(const size_t rows, const size_t cols){
    _rows = rows;
    _cols = cols;
    _data = new T[_rows * _cols];
    memset(_data, 0, sizeof(T) * _rows * _cols);
}

template<class T>
Matrix<T>::Matrix(const T& value,
                  const size_t rows,
                  const size_t cols){
    _rows = rows;
    _cols = cols;
    _data = new T[_rows * _cols];
    if(value == 0 || value == static_cast<T>(-1)){
        memset(_data, value, sizeof(T) * _rows * _cols);
    }else{
        auto lamda = [](T* a, const T& b){ *a = b; };
        ParallelOperator po;
        po.parallel_mul2one<T>(_data, get_size(), value, lamda);
    }
}

template<class T>
Matrix<T>::Matrix(const T* data,
                  const size_t rows,
                  const size_t cols){
    _rows = rows;
    _cols = cols;
    _data = new T[_rows * _cols];
    memcpy(_data, data, sizeof(T) * _rows * _cols);
}

template<class T>
Matrix<T>::~Matrix(){
    if(_data != nullptr){
        delete[] _data;
        _data = nullptr;
    }
}

template<class T>
void Matrix<T>::set_shallow_data(T* data,
                                 const size_t rows,
                                 const size_t cols){
    if(_data != nullptr){
        delete[] _data;
    }
    _data = data;
    _rows = rows;
    _cols = cols;
}

template<class T>
Matrix<T> Matrix<T>::get_row(const size_t row_id, const size_t row_size) const{
    Matrix<T> mat;
	get_row(&mat, row_id, row_size);
	return mat;
}

template<class T>
void Matrix<T>::get_row(Matrix<T>* mat,
                        const size_t row_id,
                        const size_t row_size) const{
    CHECK(row_id + row_size <= _rows);
	T* data = new T[row_size * _cols];
	memcpy(data, &_data[row_id * _cols], sizeof(T) * row_size * _cols);
	mat->set_shallow_data(data, row_size, _cols);
}

template<class T>
void Matrix<T>::set_row(const Matrix<T>& mat){
    set_row(0, mat);
}

template<class T>
void Matrix<T>::set_row(const size_t row_id, const Matrix<T>& mat){
    CHECK(_cols == mat.cols());
    CHECK(row_id + mat.rows() <= _rows);
    memcpy(&_data[row_id * _cols], mat.data(), sizeof(T) * mat.get_size());
}

template<class T>
void Matrix<T>::insert_row(const Matrix<T>& mat){
    insert_row(_rows, mat);
}
template<class T>
void Matrix<T>::insert_row(const size_t row_id, const Matrix<T>& mat){

    if(get_size() == 0){
        set_data(mat.data(), mat.rows(), mat.cols());

        return;
    }

    CHECK(_cols == mat.cols());

    T* data = new T[(_rows + mat.rows()) * _cols];

    if(row_id > 0){
        memcpy(data, _data, sizeof(T) * row_id * _cols);
    }
    memcpy(&data[row_id * _cols], mat.data(), sizeof(T) * mat.get_size());
    if(row_id < _rows){
        memcpy(&data[(row_id + mat.rows()) * _cols], &_data[row_id * _cols], sizeof(T) * (_rows - row_id) * _cols);
    }
    set_shallow_data(data, _rows + mat.rows(), _cols);
}

template<class T>
Matrix<T> Matrix<T>::get_col(const size_t col_id, const size_t col_size) const{
    Matrix<T> mat;
	get_col(&mat, col_id, col_size);
    return mat;
}

template<class T>
void Matrix<T>::get_col(Matrix<T>* mat,
                        const size_t col_id,
                        const size_t col_size) const{
    CHECK(col_id + col_size <= _cols);
	T* data = new T[_rows * col_size];
	for(size_t i = 0; i != _rows; i++){
		memcpy(&data[i * col_size], &_data[i * col_size + col_id], sizeof(T) * col_size);
	}
	mat->set_shallow_data(data, _rows, col_size);
}

template<class T>
void Matrix<T>::set_col(const Matrix<T>& mat){
    set_col(0, mat);
}

template<class T>
void Matrix<T>::set_col(const size_t col_id, const Matrix<T>& mat){
    CHECK(mat.rows() == _rows);
    CHECK(col_id + mat.cols() <= _cols);
    T* sub_data   = mat.data();
    size_t sub_cols =  mat.cols();

    for(size_t i = 0; i != _rows; i++){
        memcpy(&_data[i * _cols + col_id], &sub_data[i * sub_cols], sizeof(T) * sub_cols);
    }
}

template<class T>
void Matrix<T>::insert_col(const Matrix<T>& mat){
    set_col(0, mat);
}

template<class T>
void Matrix<T>::insert_col(const size_t col_id, const Matrix<T>& mat){
    CHECK(mat.rows() == _rows);
    CHECK(col_id <= _cols);

    size_t sub_cols = mat.cols();
    size_t new_cols = _cols + sub_cols;
    T* sub_data   = mat.data();

    T* data = new T[_rows * new_cols];
    for(size_t i = 0; i != _rows; i++){
        if(col_id > 0){
            memcpy(&data[i * new_cols], &_data[i * _cols], sizeof(T) * sub_cols);
        }
        memcpy(&data[i * new_cols + sub_cols], &sub_data[i * sub_cols], sizeof(T) * sub_cols);
        if(col_id != _cols){
            memcpy(&data[i * new_cols + col_id + sub_cols], &_data[i * _cols + col_id], sizeof(T) * (_cols - col_id));
        }
    }

    set_shallow_data(data, _rows, new_cols);
}

template<class T>
Matrix<T> Matrix<T>::clone() const{
    return Matrix<T>(_data, _rows, _cols);
}
template<class T>
void Matrix<T>::clone(Matrix<T>& mat) const{
    mat.set_data(_data, _rows, _cols);
}

template<class T>
void Matrix<T>::reset(const T& value){
   reset(value, _rows, _cols);
}

template<class T>
void Matrix<T>::reset(const T& value,
                      const size_t rows,
                      const size_t cols){
    size_t size = rows * cols;
    if(get_size() != size){
        if(_data != nullptr){
            delete[] _data;
        }
        _data = new T[size];
        _rows = rows;
        _cols = cols;
    }

    if(value == 0 || value == static_cast<T>(-1)){
        memset(_data, value, sizeof(T) * size);
    }else{
        auto lamda = [](T* a, const T& b){ *a = b; };
        ParallelOperator po;
        po.parallel_mul2one<T>(_data, size, value, lamda);
    }
}

template<class T>
Matrix<T> Matrix<T>::Ts(){
    MatrixHelper<T> mh;
    Matrix<T> mat;
    mh.transpose(mat, *this);
    return mat;
}

template<class T>
Matrix<T>& Matrix<T>::transpose(){
    MatrixHelper<T> mh;
    mh.transpose(*this, *this);
	return *this;
}

template<class T>
void Matrix<T>::display(const std::string& split, const bool with_title) const{
    if(with_title) printf("[%ld*%ld][\n", _rows, _cols);
    for(size_t i = 0; i != _rows; i++){
        if(with_title) printf("row[%ld][", i);
        for(size_t j = 0; j != _cols; j++){
            printf("%s", std::to_string(_data[i * _cols + j]).c_str());
            if(j != this->_cols - 1){
                printf("%s", split.c_str());
            }
        }
        if(with_title) printf("]\n");
    }
    if(with_title) printf("]\n");
}

template<class T>
RandomMatrix<T>::RandomMatrix(size_t rows,
                              size_t cols,
                              const T& mean_value,
                              const T& stddev,
                              const T& min,
                              const T& max) : Matrix<T>(rows, cols){
    _mean_value = mean_value;
    _stddev     = stddev;
    _min        = min;
    _max        = max;

    reset();
}

template<class T>
void RandomMatrix<T>::reset(){
    T scale = _max - _min;
    T min   = _min;
    T max   = _max;

    ParallelOperator po;
    size_t size = this->_rows * this->_cols;
    T* data = this->_data;
    size_t block_size = po.get_block_size(size);
    size_t num_thread = po.get_num_thread(size, block_size);
    std::vector<std::thread> threads(num_thread);
    std::default_random_engine engine(std::chrono::system_clock::now().time_since_epoch().count());
    std::normal_distribution<T> distribution(_mean_value, _stddev);

    for(size_t i = 0; i != num_thread; i++){
        threads[i] = std::thread(
            [&data, max, min, scale, &distribution, &engine](size_t start_idx, size_t end_idx){
                for(size_t ti = start_idx; ti != end_idx; ti++){
                    T value = static_cast<T>(distribution(engine));
                    if(max == min || value == max || value == min){
                        data[ti] = value;
                    }else if(value > max){
                        real step = (value - min)/scale;
                        value = min + (step - (int)step) * scale;
                    }else{
                        real step = (max - value)/scale;
                        value = min + (step - (int)step) * scale;
                    }
                }
            }, i * block_size, std::min(size, (i + 1) * block_size)
        );
    }

    for(auto& thread : threads){
        thread.join();
    }
}

template<class T>
void RandomMatrix<T>::reset(size_t rows,
                            size_t cols,
                            const T& mean_value,
                            const T& stddev,
                            const T& min,
                            const T& max){
    if(rows * cols != this->_rows * this->_cols){
        if(this->_data != nullptr){
            delete[] this->_data;
        }
        this->_data = new T[rows * cols];
    }

    this->_rows = rows;
    this->_cols = cols;
    _mean_value = mean_value;
    _stddev     = stddev;
    _min        = min;
    _max        = max;

    reset();
}

template class Matrix<int>;
template class Matrix<float>;
template class Matrix<double>;
template class Matrix<size_t>;

template class RandomMatrix<float>;
}//namespace algebra
}//namespace abcdl
<|endoftext|>


<commit_before>#include "../ir.h"

TLANG_NAMESPACE_BEGIN

VecStatement convert_to_range_for(StructForStmt *struct_for) {
  VecStatement ret;
  auto loop_var = ret.push_back<AllocaStmt>(DataType::i32);
  auto lower = ret.push_back<ConstStmt>(TypedConstant(0));
  std::vector<SNode *> snodes;
  auto snode = struct_for->snode;
  int total_bits = 0;
  while (snode->type != SNodeType::root) {
    snodes.push_back(snode);
    total_bits += snode->total_num_bits;
    snode = snode->parent;
  }
  std::reverse(snodes.begin(), snodes.end());
  TC_ASSERT(total_bits <= 31);

  auto upper_bound = 1 << total_bits;
  auto upper = ret.push_back<ConstStmt>(TypedConstant(upper_bound));
  auto body = std::move(struct_for->body);

  auto old_loop_vars = struct_for->loop_vars;
  std::vector<Stmt *> new_loop_vars;

  VecStatement body_header;

  std::vector<int> physical_indices;

  TC_ASSERT(snodes.back()->num_active_indices == (int)old_loop_vars.size());
  for (int i = 0; i < (int)old_loop_vars.size(); i++) {
    new_loop_vars.push_back(body_header.push_back<ConstStmt>(TypedConstant(0)));
    physical_indices.push_back(snodes.back()->physical_index_position[i]);
  }

  auto main_loop_var =
      body_header.push_back<LocalLoadStmt>(LocalAddress(loop_var, 0));

  int offset = total_bits;
  Stmt *test = body_header.push_back<ConstStmt>(TypedConstant(-1));
  bool has_test = false;
  for (int i = 0; i < (int)snodes.size(); i++) {
    auto snode = snodes[i];
    offset -= snode->total_num_bits;
    for (int j = 0; j < (int)physical_indices.size(); j++) {
      auto p = physical_indices[j];
      auto ext = snode->extractors[p];
      Stmt *delta = body_header.push_back<OffsetAndExtractBitsStmt>(
          main_loop_var, ext.acc_offset + offset,
          ext.acc_offset + offset + ext.num_bits, 0);
      auto multiplier =
          body_header.push_back<ConstStmt>(TypedConstant(1 << ext.start));
      delta = body_header.push_back<BinaryOpStmt>(BinaryOpType::mul, delta,
                                                  multiplier);
      new_loop_vars[j] = body_header.push_back<BinaryOpStmt>(
          BinaryOpType::add, new_loop_vars[j], delta);
    }
  }

  for (int i = 0; i < (int)snodes.size(); i++) {
    auto snode = snodes[i];
    for (int j = 0; j < (int)physical_indices.size(); j++) {
      auto p = physical_indices[j];
      auto num_elements = snode->extractors[p].num_elements;
      if (!bit::is_power_of_two(num_elements)) {
        has_test = true;
        auto bound =
            body_header.push_back<ConstStmt>(TypedConstant(num_elements));
        auto cmp = body_header.push_back<BinaryOpStmt>(BinaryOpType::cmp_lt,
                                                       new_loop_vars[j], bound);
        test = body_header.push_back<BinaryOpStmt>(BinaryOpType::bit_and, test,
                                                   cmp);
      }
    }
  }

  for (int i = 0; i < (int)old_loop_vars.size(); i++) {
    auto alloca = body_header.push_back<AllocaStmt>(DataType::i32);
    body_header.push_back<LocalStoreStmt>(alloca, new_loop_vars[i]);
    irpass::replace_all_usages_with(body.get(), old_loop_vars[i], alloca);
  }

  if (has_test) {
    // Createa an If statement
    auto if_stmt = Stmt::make_typed<IfStmt>(test);
    if_stmt->true_statements = std::move(body);
    body = std::make_unique<Block>();
    body->insert(std::move(if_stmt));
  }
  body->insert(std::move(body_header), 0);

  auto range_for = Stmt::make<RangeForStmt>(
      loop_var, lower, upper, std::move(body), struct_for->vectorize,
      struct_for->parallelize, struct_for->block_dim, false);
  ret.push_back(std::move(range_for));

  // TODO: safe guard range
  return ret;
}

namespace irpass {

void demote_dense_struct_fors(IRNode *root) {
  auto *block = dynamic_cast<Block *>(root);
  std::vector<Stmt *> block_body;
  for (int i = 0; i < (int)block->statements.size(); i++) {
    block_body.push_back(block->statements[i].get());
  }
  for (int i = 0; i < (int)block_body.size(); i++) {
    auto s_ = block_body[i];
    if (auto s = s_->cast<StructForStmt>()) {
      auto snode = s->snode->parent;
      bool all_dense = true;
      while (snode->type != SNodeType::root) {
        if (snode->type != SNodeType::dense) {
          all_dense = false;
        }
        snode = snode->parent;
      }
      if (all_dense) {
        s->parent->replace_with(s, convert_to_range_for(s), false);
      }
    }
  }
  irpass::re_id(root);
}

}  // namespace irpass

TLANG_NAMESPACE_END
<commit_msg>do not demote dense struct-for with bitmasks<commit_after>#include "../ir.h"

TLANG_NAMESPACE_BEGIN

VecStatement convert_to_range_for(StructForStmt *struct_for) {
  VecStatement ret;
  auto loop_var = ret.push_back<AllocaStmt>(DataType::i32);
  auto lower = ret.push_back<ConstStmt>(TypedConstant(0));
  std::vector<SNode *> snodes;
  auto snode = struct_for->snode;
  int total_bits = 0;
  while (snode->type != SNodeType::root) {
    snodes.push_back(snode);
    total_bits += snode->total_num_bits;
    snode = snode->parent;
  }
  std::reverse(snodes.begin(), snodes.end());
  TC_ASSERT(total_bits <= 31);

  auto upper_bound = 1 << total_bits;
  auto upper = ret.push_back<ConstStmt>(TypedConstant(upper_bound));
  auto body = std::move(struct_for->body);

  auto old_loop_vars = struct_for->loop_vars;
  std::vector<Stmt *> new_loop_vars;

  VecStatement body_header;

  std::vector<int> physical_indices;

  TC_ASSERT(snodes.back()->num_active_indices == (int)old_loop_vars.size());
  for (int i = 0; i < (int)old_loop_vars.size(); i++) {
    new_loop_vars.push_back(body_header.push_back<ConstStmt>(TypedConstant(0)));
    physical_indices.push_back(snodes.back()->physical_index_position[i]);
  }

  auto main_loop_var =
      body_header.push_back<LocalLoadStmt>(LocalAddress(loop_var, 0));

  int offset = total_bits;
  Stmt *test = body_header.push_back<ConstStmt>(TypedConstant(-1));
  bool has_test = false;
  for (int i = 0; i < (int)snodes.size(); i++) {
    auto snode = snodes[i];
    offset -= snode->total_num_bits;
    for (int j = 0; j < (int)physical_indices.size(); j++) {
      auto p = physical_indices[j];
      auto ext = snode->extractors[p];
      Stmt *delta = body_header.push_back<OffsetAndExtractBitsStmt>(
          main_loop_var, ext.acc_offset + offset,
          ext.acc_offset + offset + ext.num_bits, 0);
      auto multiplier =
          body_header.push_back<ConstStmt>(TypedConstant(1 << ext.start));
      delta = body_header.push_back<BinaryOpStmt>(BinaryOpType::mul, delta,
                                                  multiplier);
      new_loop_vars[j] = body_header.push_back<BinaryOpStmt>(
          BinaryOpType::add, new_loop_vars[j], delta);
    }
  }

  for (int i = 0; i < (int)snodes.size(); i++) {
    auto snode = snodes[i];
    for (int j = 0; j < (int)physical_indices.size(); j++) {
      auto p = physical_indices[j];
      auto num_elements = snode->extractors[p].num_elements;
      if (!bit::is_power_of_two(num_elements)) {
        has_test = true;
        auto bound =
            body_header.push_back<ConstStmt>(TypedConstant(num_elements));
        auto cmp = body_header.push_back<BinaryOpStmt>(BinaryOpType::cmp_lt,
                                                       new_loop_vars[j], bound);
        test = body_header.push_back<BinaryOpStmt>(BinaryOpType::bit_and, test,
                                                   cmp);
      }
    }
  }

  for (int i = 0; i < (int)old_loop_vars.size(); i++) {
    auto alloca = body_header.push_back<AllocaStmt>(DataType::i32);
    body_header.push_back<LocalStoreStmt>(alloca, new_loop_vars[i]);
    irpass::replace_all_usages_with(body.get(), old_loop_vars[i], alloca);
  }

  if (has_test) {
    // Createa an If statement
    auto if_stmt = Stmt::make_typed<IfStmt>(test);
    if_stmt->true_statements = std::move(body);
    body = std::make_unique<Block>();
    body->insert(std::move(if_stmt));
  }
  body->insert(std::move(body_header), 0);

  auto range_for = Stmt::make<RangeForStmt>(
      loop_var, lower, upper, std::move(body), struct_for->vectorize,
      struct_for->parallelize, struct_for->block_dim, false);
  ret.push_back(std::move(range_for));

  // TODO: safe guard range
  return ret;
}

namespace irpass {

void demote_dense_struct_fors(IRNode *root) {
  auto *block = dynamic_cast<Block *>(root);
  std::vector<Stmt *> block_body;
  for (int i = 0; i < (int)block->statements.size(); i++) {
    block_body.push_back(block->statements[i].get());
  }
  for (int i = 0; i < (int)block_body.size(); i++) {
    auto s_ = block_body[i];
    if (auto s = s_->cast<StructForStmt>()) {
      auto snode = s->snode->parent;
      bool all_dense = true;
      while (snode->type != SNodeType::root) {
        if (snode->type != SNodeType::dense) {
          all_dense = false;
        }
        if (snode->type == SNodeType::dense && snode->_bitmasked) {
          all_dense = false;
        }
        snode = snode->parent;
      }
      if (all_dense) {
        s->parent->replace_with(s, convert_to_range_for(s), false);
      }
    }
  }
  irpass::re_id(root);
}

}  // namespace irpass

TLANG_NAMESPACE_END
<|endoftext|>


<commit_before>#include <type/type-checker.hh>
#include <ast/all.hh>

namespace type
{
    TypeChecker::TypeChecker()
    {}

    TypeChecker::~TypeChecker()
    {}

    misc::Error& TypeChecker::error_get()
    {
        return error_;
    }

    void TypeChecker::type_check(ast::Expr* e1, ast::Expr* e2)
    {
        if (!e1->type_get() || !e2->type_get())
            assert(false && "Compiler internal error");

        if (!e1->type_get()->compatible_with(*(e2->type_get())))
        {
            error_ << misc::Error::TYPE
                   << e1->location_get() << ": Type error, excpected "
                   << *(e1->type_get()) << ", got " << *(e2->type_get())
                   << std::endl;
        }
    }

    void TypeChecker::type_set(ast::Expr* e1, ast::Expr* e2)
    {
        e1->type_set(e2->type_get());
    }

    void TypeChecker::operator()(ast::ReturnStmt& ast)
    {
        type::Type* ret_type = &Void::instance();
        ast::FunctionDec* to_type = in_declaration_.top();
        type::Type* fun_type = to_type->type_get()->return_type_get();

        if (ast.ret_value_get())
        {
            ast.ret_value_get()->accept(*this);
            ret_type = ast.ret_value_get()->type_get();
        }

        if (fun_type)
        {
            if (!fun_type->compatible_with(*ret_type))
            {
                error_ << misc::Error::TYPE
                       << ast.location_get() << ": Type error, function has "
                       << "deduced type " << *fun_type << ", but return is "
                       << *ret_type << std::endl;
            }
        }
        else
        {
            to_type->type_get()->return_type_set(ret_type);
        }
    }

    void TypeChecker::operator()(ast::FunctionDec& s)
    {
        s.type_set(new Function());

        if (s.args_get())
        {
            for (auto arg : s.args_get()->list_get())
            {
                ast::IdVar* var = dynamic_cast<ast::IdVar*> (arg);

                if (var)
                {
                    var->type_set(&Polymorphic::instance());
                    s.type_get()->args_type_add(&Polymorphic::instance());
                }
                else
                {
                    arg->accept(*this);
                    s.type_get()->args_type_add(arg->type_get());
                }
            }
        }

        in_declaration_.push(&s);
        s.body_get()->accept(*this);
        in_declaration_.pop();
    }

    void TypeChecker::operator()(ast::FunctionVar&)
    {

    }

    void TypeChecker::operator()(ast::OpExpr& ast)
    {
        ast.left_expr_get()->accept(*this);
        ast.right_expr_get()->accept(*this);

        type_check(ast.left_expr_get(), ast.right_expr_get());

        // So far if there is no error it does not really matter if the opexpr
        // has right expr of left expr type since they are the same due to
        // strong type of python
        type_set(&ast, ast.left_expr_get());
    }

    void TypeChecker::operator()(ast::IdVar& ast)
    {
        ast::Expr* e = dynamic_cast<ast::Expr*> (ast.def_get());

        if (e)
            type_set(&ast, e);
        else if (ast.def_get())
            assert(false && "Compiler internal error");
    }

    void TypeChecker::operator()(ast::AssignExpr& e)
    {
        e.rvalue_get()->accept(*this);
        e.lvalue_get()->accept(*this);

        type_set(e.lvalue_get(), e.rvalue_get());
        type_set(&e, e.rvalue_get());
    }

    void TypeChecker::operator()(ast::NumeralExpr& ast)
    {
        ast.type_set(&Int::instance());
    }

    void TypeChecker::operator()(ast::StringExpr& ast)
    {
        ast.type_set(&String::instance());
    }
} // namespace type
<commit_msg>Function with no return as default type void<commit_after>#include <type/type-checker.hh>
#include <ast/all.hh>

namespace type
{
    TypeChecker::TypeChecker()
    {}

    TypeChecker::~TypeChecker()
    {}

    misc::Error& TypeChecker::error_get()
    {
        return error_;
    }

    void TypeChecker::type_check(ast::Expr* e1, ast::Expr* e2)
    {
        if (!e1->type_get() || !e2->type_get())
            assert(false && "Compiler internal error");

        if (!e1->type_get()->compatible_with(*(e2->type_get())))
        {
            error_ << misc::Error::TYPE
                   << e1->location_get() << ": Type error, excpected "
                   << *(e1->type_get()) << ", got " << *(e2->type_get())
                   << std::endl;
        }
    }

    void TypeChecker::type_set(ast::Expr* e1, ast::Expr* e2)
    {
        e1->type_set(e2->type_get());
    }

    void TypeChecker::operator()(ast::ReturnStmt& ast)
    {
        type::Type* ret_type = &Void::instance();
        ast::FunctionDec* to_type = in_declaration_.top();
        type::Type* fun_type = to_type->type_get()->return_type_get();

        if (ast.ret_value_get())
        {
            ast.ret_value_get()->accept(*this);
            ret_type = ast.ret_value_get()->type_get();
        }

        if (fun_type)
        {
            if (!fun_type->compatible_with(*ret_type))
            {
                error_ << misc::Error::TYPE
                       << ast.location_get() << ": Type error, function has "
                       << "deduced type " << *fun_type << ", but return is "
                       << *ret_type << std::endl;
            }
        }
        else
        {
            to_type->type_get()->return_type_set(ret_type);
        }
    }

    void TypeChecker::operator()(ast::FunctionDec& s)
    {
        s.type_set(new Function());

        if (s.args_get())
        {
            for (auto arg : s.args_get()->list_get())
            {
                ast::IdVar* var = dynamic_cast<ast::IdVar*> (arg);

                if (var)
                {
                    var->type_set(&Polymorphic::instance());
                    s.type_get()->args_type_add(&Polymorphic::instance());
                }
                else
                {
                    arg->accept(*this);
                    s.type_get()->args_type_add(arg->type_get());
                }
            }
        }

        in_declaration_.push(&s);
        s.body_get()->accept(*this);
        in_declaration_.pop();

        if (!s.type_get()->return_type_get())
            s.type_get()->return_type_set(&Void::instance());
    }

    void TypeChecker::operator()(ast::FunctionVar&)
    {

    }

    void TypeChecker::operator()(ast::OpExpr& ast)
    {
        ast.left_expr_get()->accept(*this);
        ast.right_expr_get()->accept(*this);

        type_check(ast.left_expr_get(), ast.right_expr_get());

        // So far if there is no error it does not really matter if the opexpr
        // has right expr of left expr type since they are the same due to
        // strong type of python
        type_set(&ast, ast.left_expr_get());
    }

    void TypeChecker::operator()(ast::IdVar& ast)
    {
        ast::Expr* e = dynamic_cast<ast::Expr*> (ast.def_get());

        if (e)
            type_set(&ast, e);
        else if (ast.def_get())
            assert(false && "Compiler internal error");
    }

    void TypeChecker::operator()(ast::AssignExpr& e)
    {
        e.rvalue_get()->accept(*this);
        e.lvalue_get()->accept(*this);

        type_set(e.lvalue_get(), e.rvalue_get());
        type_set(&e, e.rvalue_get());
    }

    void TypeChecker::operator()(ast::NumeralExpr& ast)
    {
        ast.type_set(&Int::instance());
    }

    void TypeChecker::operator()(ast::StringExpr& ast)
    {
        ast.type_set(&String::instance());
    }
} // namespace type
<|endoftext|>


<commit_before>#include "extproc/example.hpp"

#include <sys/types.h>
#include <sys/socket.h>

#include <cstring>              // strerror

#include <v8.h>

#include "errors.hpp"
#include <boost/bind.hpp>

#include "arch/runtime/starter.hpp"
#include "arch/runtime/thread_pool.hpp"
#include "clustering/administration/issues/local.hpp"
#include "clustering/administration/logger.hpp"
#include "containers/archive/socket_stream.hpp"
#include "extproc/job.hpp"
#include "extproc/pool.hpp"
#include "extproc/spawner.hpp"
#include "rpc/serialize_macros.hpp"

class js_eval_job_t :
    public extproc::auto_job_t<js_eval_job_t>
{
  public:
    js_eval_job_t() {}
    explicit js_eval_job_t(std::string src) : js_src(src) {}

    struct result_t {
        bool success;
        std::string message;
        RDB_MAKE_ME_SERIALIZABLE_2(success, message);
    };

  private:
    void eval(control_t *control, v8::Handle<v8::Context> cx, result_t *result) {
        v8::Context::Scope cx_scope(cx);
        v8::HandleScope handle_scope;
        v8::Handle<v8::String> src = v8::String::New(js_src.c_str());

        v8::TryCatch try_catch;

        // Compile the script immediately.
        v8::Handle<v8::Script> script = v8::Script::Compile(src);

        // Wait for a signal to actually run the script.
        char c;
        guarantee_err(1 == control->read(&c, 1), "couldn't read signal");
        guarantee(c == '\0', "bad signal value");

        // We need to do this after receiving the signal, otherwise we could get
        // out of sync with the other end and data could be corrupted.
        if (script.IsEmpty()) {
            result->message = "script compilation failed";
            return;
        }

        v8::Handle<v8::Value> value = script->Run();
        if (value.IsEmpty()) {
            result->message = "script execution failed";
            return;
        }

        v8::String::Utf8Value str(value);
        if (!*str) {
            result->message = "string conversion of result failed";
            return;
        }

        result->success = true;
        result->message = std::string(*str);
    }

  public:
    virtual void run_job(control_t *control) {
        control->log("Running js_eval_job_t, src=%s", js_src.c_str());

        result_t res;
        res.success = false;
        res.message = "";

        // Evaluate the script
        v8::Persistent<v8::Context> cx = v8::Context::New();
        eval(control, cx, &res);
        cx.Dispose();

        // Send back the result.
        write_message_t msg;
        msg << res;
        if (send_write_message(control, &msg)) {
            control->log("js_eval_job_t: Could not send back evaluated JS.");
        }
    }

  private:
    std::string js_src;

  public:
    RDB_MAKE_ME_SERIALIZABLE_1(js_src);
};

void run_rethinkdb_js(extproc::spawner_t::info_t *info, bool *result) {
    struct killer_message_t : linux_thread_message_t {
        virtual void on_thread_switch() {
            // NB. This is a terrible way to handle shut-down, and is only for
            // example purposes (in particular, a clean shutdown would require
            // killing worker processes by destructing pool_group).
            fprintf(stderr, "SIGINT received, exiting...\n");
            abort();
        }
    } msg;
    linux_thread_pool_t::thread_pool->set_interrupt_message(&msg);

    fprintf(stderr, "ENGINE PROC: %d\n", getpid());

    extproc::pool_group_t pool_group(info, extproc::pool_group_t::DEFAULTS);
    extproc::pool_t *pool = pool_group.get();

    local_issue_tracker_t tracker;
    log_writer_t writer("example-log", &tracker);

    // Shell loop.
    char *line = NULL;
    size_t line_sz = 0;

    for (;;) {
        // Prompt for some javascript to evaluate.
        printf("> ");
        ssize_t res = getline(&line, &line_sz, stdin);
        if (res == -1) {
            printf("\n!! could not get line\n");
            break;
        }

        const char *cmd = line;
        size_t cmdlen = strlen(cmd);

        // Look for command modifiers.
        bool interrupt = false, badsignal = false;
        const size_t nmods = 2;
        bool *(mod_ptrs[]) = {&interrupt, &badsignal};
        const char *mod_names[] = {"interrupt ", "badsignal "};

        size_t i;
        do {
            for (i = 0; i < nmods; ++i) {
                const char *name = mod_names[i];
                size_t len = strlen(name);
                if (len <= cmdlen && 0 == memcmp(cmd, name, len)) {
                    *(mod_ptrs[i]) = true;
                    cmd += len;
                    cmdlen -= len;
                    break;
                }
            }
        } while (i < nmods);

        // Send a job that evaluates the javascript.
        extproc::job_handle_t handle;
        if(-1 == pool->spawn_job(js_eval_job_t(cmd), &handle)) {
            printf("!! could not spawn job\n");
            break;
        }

        // Send the signal to complete the job. (Send a bad signal if
        // requested.)
        guarantee_err(1 == handle.write(badsignal ? "x" : "\0", 1),
                      "could not send signal to job");

        // Interrupt the job if requested.
        if (interrupt) {
            handle.interrupt();
            printf("interrupting job and trying again\n");
            continue;
        }

        // Read back the result.
        printf("waiting for result...\n");
        js_eval_job_t::result_t result;
        archive_result_t ares = deserialize(&handle, &result);
        if (ARCHIVE_SUCCESS != ares) {
            printf("!! could not deserialize result: %s\n",
                   ares == ARCHIVE_SOCK_ERROR ? "socket error" :
                   ares == ARCHIVE_SOCK_EOF ? "EOF" :
                   ares == ARCHIVE_RANGE_ERROR ? "range error" :
                   "unknown error");
            break;
        }

        // Done with the job now.
        handle.release();

        // Print the result.
        printf(result.success ? "success!\nresult: %s\n" : "failure! :(\nreason: %s\n",
               result.message.c_str());
    }

    *result = -1;
    printf("run_rethinkdb_js exiting\n");
}

int main_rethinkdb_js(int argc, char *argv[]) {
    (void) argc;
    (void) argv;

    extproc::spawner_t::info_t spawner_info;
    extproc::spawner_t::create(&spawner_info);

    bool result;
    run_in_thread_pool(boost::bind(&run_rethinkdb_js, &spawner_info, &result), 1);
    printf("main_rethinkdb_js exiting\n");
    return result ? 0 : 1;
}
<commit_msg>fix example.cc<commit_after>#include "extproc/example.hpp"

#include <v8.h>

#include "errors.hpp"
#include <boost/bind.hpp>

#include "arch/runtime/starter.hpp"
#include "arch/runtime/thread_pool.hpp"
#include "clustering/administration/issues/local.hpp"
#include "clustering/administration/logger.hpp"
#include "containers/archive/archive.hpp"
#include "extproc/job.hpp"
#include "extproc/pool.hpp"
#include "extproc/spawner.hpp"
#include "rpc/serialize_macros.hpp"

class js_eval_job_t :
    public extproc::auto_job_t<js_eval_job_t>
{
  public:
    js_eval_job_t() {}
    explicit js_eval_job_t(std::string src) : js_src(src) {}

    struct result_t {
        bool success;
        std::string message;
        RDB_MAKE_ME_SERIALIZABLE_2(success, message);
    };

  private:
    void eval(control_t *control, v8::Handle<v8::Context> cx, result_t *result) {
        v8::Context::Scope cx_scope(cx);
        v8::HandleScope handle_scope;
        v8::Handle<v8::String> src = v8::String::New(js_src.c_str());

        v8::TryCatch try_catch;

        // Compile the script immediately.
        v8::Handle<v8::Script> script = v8::Script::Compile(src);

        // Wait for a signal to actually run the script.
        char c;
        guarantee_err(1 == force_read(control, &c, 1), "couldn't read signal");
        guarantee(c == '\0', "bad signal value");

        // We need to do this after receiving the signal, otherwise we could get
        // out of sync with the other end and data could be corrupted.
        if (script.IsEmpty()) {
            result->message = "script compilation failed";
            return;
        }

        v8::Handle<v8::Value> value = script->Run();
        if (value.IsEmpty()) {
            result->message = "script execution failed";
            return;
        }

        v8::String::Utf8Value str(value);
        if (!*str) {
            result->message = "string conversion of result failed";
            return;
        }

        result->success = true;
        result->message = std::string(*str);
    }

  public:
    virtual void run_job(control_t *control) {
        control->log("Running js_eval_job_t, src=%s", js_src.c_str());

        result_t res;
        res.success = false;
        res.message = "";

        // Evaluate the script
        v8::Persistent<v8::Context> cx = v8::Context::New();
        eval(control, cx, &res);
        cx.Dispose();

        // Send back the result.
        write_message_t msg;
        msg << res;
        if (send_write_message(control, &msg)) {
            control->log("js_eval_job_t: Could not send back evaluated JS.");
        }
    }

  private:
    std::string js_src;

  public:
    RDB_MAKE_ME_SERIALIZABLE_1(js_src);
};

void run_rethinkdb_js(extproc::spawner_t::info_t *info, bool *result) {
    struct killer_message_t : linux_thread_message_t {
        virtual void on_thread_switch() {
            // NB. This is a terrible way to handle shut-down, and is only for
            // example purposes (in particular, a clean shutdown would require
            // killing worker processes by destructing pool_group).
            fprintf(stderr, "SIGINT received, exiting...\n");
            abort();
        }
    } msg;
    linux_thread_pool_t::thread_pool->set_interrupt_message(&msg);

    fprintf(stderr, "ENGINE PROC: %d\n", getpid());

    extproc::pool_group_t pool_group(info, extproc::pool_group_t::DEFAULTS);
    extproc::pool_t *pool = pool_group.get();

    local_issue_tracker_t tracker;
    log_writer_t writer("example-log", &tracker);

    // Shell loop.
    char *line = NULL;
    size_t line_sz = 0;

    for (;;) {
        // Prompt for some javascript to evaluate.
        printf("> ");
        ssize_t res = getline(&line, &line_sz, stdin);
        if (res == -1) {
            printf("\n!! could not get line\n");
            break;
        }

        const char *cmd = line;
        size_t cmdlen = strlen(cmd);

        // Look for command modifiers.
        bool interrupt = false, badsignal = false;
        const size_t nmods = 2;
        bool *(mod_ptrs[]) = {&interrupt, &badsignal};
        const char *mod_names[] = {"interrupt ", "badsignal "};

        size_t i;
        do {
            for (i = 0; i < nmods; ++i) {
                const char *name = mod_names[i];
                size_t len = strlen(name);
                if (len <= cmdlen && 0 == memcmp(cmd, name, len)) {
                    *(mod_ptrs[i]) = true;
                    cmd += len;
                    cmdlen -= len;
                    break;
                }
            }
        } while (i < nmods);

        // Send a job that evaluates the javascript.
        extproc::job_handle_t handle;
        if(-1 == pool->spawn_job(&handle, js_eval_job_t(cmd))) {
            printf("!! could not spawn job\n");
            break;
        }

        // Send the signal to complete the job. (Send a bad signal if
        // requested.)
        guarantee_err(1 == handle.write(badsignal ? "x" : "\0", 1),
                      "could not send signal to job");

        // Interrupt the job if requested.
        if (interrupt) {
            handle.interrupt();
            printf("interrupting job and trying again\n");
            continue;
        }

        // Read back the result.
        printf("waiting for result...\n");
        js_eval_job_t::result_t result;
        archive_result_t ares = deserialize(&handle, &result);
        if (ARCHIVE_SUCCESS != ares) {
            printf("!! could not deserialize result: %s\n",
                   ares == ARCHIVE_SOCK_ERROR ? "socket error" :
                   ares == ARCHIVE_SOCK_EOF ? "EOF" :
                   ares == ARCHIVE_RANGE_ERROR ? "range error" :
                   "unknown error");
            break;
        }

        // Done with the job now.
        handle.release();

        // Print the result.
        printf(result.success ? "success!\nresult: %s\n" : "failure! :(\nreason: %s\n",
               result.message.c_str());
    }

    *result = -1;
    printf("run_rethinkdb_js exiting\n");
}

int main_rethinkdb_js(int argc, char *argv[]) {
    (void) argc;
    (void) argv;

    extproc::spawner_t::info_t spawner_info;
    extproc::spawner_t::create(&spawner_info);

    bool result;
    run_in_thread_pool(boost::bind(&run_rethinkdb_js, &spawner_info, &result), 1);
    printf("main_rethinkdb_js exiting\n");
    return result ? 0 : 1;
}
<|endoftext|>


<commit_before>// $Id$
// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "elem.h"
#include "fe.h"
#include "fe_macro.h"

namespace libMesh
{

// ------------------------------------------------------------
// Hierarchic-specific implementations
template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::nodal_soln(const Elem* elem,
			   const Order order,
			   const std::vector<Number>& elem_soln,
			   std::vector<Number>&       nodal_soln)
{
  const unsigned int n_nodes = elem->n_nodes();

  const ElemType type = elem->type();

  nodal_soln.resize(n_nodes);

  const Order totalorder = static_cast<Order>(order + elem->p_level());

  switch (totalorder)
    {
      // Constant shape functions
    case CONSTANT:
      {
	libmesh_assert (elem_soln.size() == 1);

	const Number val = elem_soln[0];

	for (unsigned int n=0; n<n_nodes; n++)
	  nodal_soln[n] = val;

	return;
      }

      // For other bases do interpolation at the nodes
      // explicitly.
    default:
      {

	const unsigned int n_sf =
	  FE<Dim,T>::n_shape_functions(type, totalorder);

	for (unsigned int n=0; n<n_nodes; n++)
	  {
	    const Point mapped_point = FE<Dim,T>::inverse_map(elem,
							      elem->point(n));

	    libmesh_assert (elem_soln.size() == n_sf);

	    // Zero before summation
	    nodal_soln[n] = 0;

	    // u_i = Sum (alpha_i phi_i)
	    for (unsigned int i=0; i<n_sf; i++)
	      nodal_soln[n] += elem_soln[i]*FE<Dim,T>::shape(elem,
							     order,
							     i,
							     mapped_point);
	  }

	return;
      }
    }
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs(const ElemType t, const Order o)
{
  libmesh_assert (o > 0);
  switch (t)
    {
    case NODEELEM:
      return 1;
    case EDGE2:
    case EDGE3:
      return (o+1);
    case QUAD4:
      libmesh_assert(o < 2);
    case QUAD8:
    case QUAD9:
      return ((o+1)*(o+1));
    case HEX8:
      libmesh_assert(o < 2);
    case HEX20:
      libmesh_assert(o < 2);
    case HEX27:
      return ((o+1)*(o+1)*(o+1));
    case TRI6:
      return ((o+1)*(o+2)/2);
    default:
      libmesh_error();
    }

  libmesh_error();
  return 0;
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs_at_node(const ElemType t,
				       const Order o,
				       const unsigned int n)
{
  libmesh_assert (o > 0);
  switch (t)
    {
    case NODEELEM:
      return 1;
    case EDGE2:
    case EDGE3:
      switch (n)
        {
	case 0:
	case 1:
	  return 1;
        // Internal DoFs are associated with the elem, not its nodes
	case 2:
	  return 0;
	default:
	  libmesh_error();
	}
    case TRI6:
      switch (n)
	{
	case 0:
	case 1:
	case 2:
	  return 1;

	case 3:
	case 4:
	case 5:
	  return (o-1);

        // Internal DoFs are associated with the elem, not its nodes
	default:
	  libmesh_error();
	}
    case QUAD4:
      libmesh_assert (n < 4);
      libmesh_assert (o < 2);
    case QUAD8:
    case QUAD9:
      switch (n)
	{
	case 0:
	case 1:
	case 2:
	case 3:
	  return 1;

	case 4:
	case 5:
	case 6:
	case 7:
	  return (o-1);

        // Internal DoFs are associated with the elem, not its nodes
	case 8:
          return 0;

	default:
	  libmesh_error();
	}
    case HEX8:
      libmesh_assert (n < 8);
      libmesh_assert (o < 2);
    case HEX20:
      libmesh_assert (n < 20);
      libmesh_assert (o < 2);
    case HEX27:
      switch (n)
	{
	case 0:
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	  return 1;

	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	case 13:
	case 14:
	case 15:
	case 16:
	case 17:
	case 18:
	case 19:
	  return (o-1);

	case 20:
	case 21:
	case 22:
	case 23:
	case 24:
	case 25:
	  return ((o-1)*(o-1));

        // Internal DoFs are associated with the elem, not its nodes
	case 26:
	  return 0;
	default:
	  libmesh_error();
        }
    default:
#ifdef DEBUG
      libMesh::err << "ERROR: Bad ElemType = " << t
		    << std::endl;
#endif
      libmesh_error();
    }

  libmesh_error();

  return 0;
}

template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_dofs_per_elem(const ElemType t,
					const Order o)
{
  libmesh_assert (o > 0);
  switch (t)
    {
    case NODEELEM:
      return 0;
    case EDGE2:
    case EDGE3:
      return (o-1);
    case TRI3:
    case QUAD4:
      return 0;
    case TRI6:
      return ((o-1)*(o-2)/2);
    case QUAD8:
    case QUAD9:
      return ((o-1)*(o-1));
    case HEX8:
    case HEX20:
      libmesh_assert(o < 2);
      return 0;
    case HEX27:
      return ((o-1)*(o-1)*(o-1));
    default:
#ifdef DEBUG
      libMesh::err << "ERROR: Bad ElemType = " << t
		    << std::endl;
#endif
      libmesh_error();
    }

  // Will never get here...
  libmesh_error();
  return 0;
}

template <unsigned int Dim, FEFamily T>
FEContinuity FE<Dim,T>::get_continuity() const
{
  return C_ZERO;
}

template <unsigned int Dim, FEFamily T>
bool FE<Dim,T>::is_hierarchic() const
{
  return true;
}

#ifdef LIBMESH_ENABLE_AMR
template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::compute_constraints (DofConstraints &constraints,
				     DofMap &dof_map,
				     const unsigned int variable_number,
				     const Elem* elem)
{
  compute_proj_constraints(constraints, dof_map, variable_number, elem);
}
#endif // #ifdef LIBMESH_ENABLE_AMR

template <unsigned int Dim, FEFamily T>
bool FE<Dim,T>::shapes_need_reinit() const
{
  return true;
}

//--------------------------------------------------------------
// Explicit instantiation of member functions
INSTANTIATE_MBRF(0,HIERARCHIC);
INSTANTIATE_MBRF(1,HIERARCHIC);
INSTANTIATE_MBRF(2,HIERARCHIC);
INSTANTIATE_MBRF(3,HIERARCHIC);

#ifdef LIBMESH_ENABLE_AMR
template void FE<2,HIERARCHIC>::compute_constraints(DofConstraints&, DofMap&,
						    const unsigned int,
						    const Elem*);
template void FE<3,HIERARCHIC>::compute_constraints(DofConstraints&, DofMap&,
						    const unsigned int,
						    const Elem*);
#endif // #ifdef LIBMESH_ENABLE_AMR

} // namespace libMesh
<commit_msg>Refactoring fe_hierarchic.C functions to use specialization instead of instantiation.<commit_after>// $Id$
// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "elem.h"
#include "fe.h"
#include "fe_macro.h"
#include "fe_interface.h"

namespace libMesh
{

  // ------------------------------------------------------------
  // Hierarchic-specific implementations

  // Anonymous namespace for local helper functions
  namespace {

    void hierarchic_nodal_soln(const Elem* elem,
			       const Order order,
			       const std::vector<Number>& elem_soln,
			       std::vector<Number>&       nodal_soln,
			       unsigned Dim)
    {
      const unsigned int n_nodes = elem->n_nodes();

      const ElemType elem_type = elem->type();

      nodal_soln.resize(n_nodes);

      const Order totalorder = static_cast<Order>(order + elem->p_level());

      // FEType object to be passed to various FEInterface functions below.
      FEType fe_type(totalorder, HIERARCHIC);

      switch (totalorder)
	{
	  // Constant shape functions
	case CONSTANT:
	  {
	    libmesh_assert (elem_soln.size() == 1);

	    const Number val = elem_soln[0];

	    for (unsigned int n=0; n<n_nodes; n++)
	      nodal_soln[n] = val;

	    return;
	  }

	  // For other orders do interpolation at the nodes
	  // explicitly.
	default:
	  {

	    const unsigned int n_sf =
	      // FE<Dim,T>::n_shape_functions(elem_type, totalorder);
	      FEInterface::n_shape_functions(Dim, fe_type, elem_type);

	    for (unsigned int n=0; n<n_nodes; n++)
	      {
		const Point mapped_point =
		  // FE<Dim,T>::inverse_map(elem, elem->point(n));
		  FEInterface::inverse_map(Dim, fe_type, elem, elem->point(n));

		libmesh_assert (elem_soln.size() == n_sf);

		// Zero before summation
		nodal_soln[n] = 0;

		// u_i = Sum (alpha_i phi_i)
		for (unsigned int i=0; i<n_sf; i++)
		  nodal_soln[n] += elem_soln[i] *
		    // FE<Dim,T>::shape(elem, order, i, mapped_point);
		    FEInterface::shape(Dim, fe_type, elem, i, mapped_point);
	      }

	    return;
	  }
	}
    } // hierarchic_nodal_soln()

    unsigned int hierarchic_n_dofs(const ElemType t, const Order o)
    {
      libmesh_assert (o > 0);
      switch (t)
	{
	case NODEELEM:
	  return 1;
	case EDGE2:
	case EDGE3:
	  return (o+1);
	case QUAD4:
	  libmesh_assert(o < 2);
	case QUAD8:
	case QUAD9:
	  return ((o+1)*(o+1));
	case HEX8:
	  libmesh_assert(o < 2);
	case HEX20:
	  libmesh_assert(o < 2);
	case HEX27:
	  return ((o+1)*(o+1)*(o+1));
	case TRI6:
	  return ((o+1)*(o+2)/2);
	default:
	  libmesh_error();
	}

      libmesh_error();
      return 0;
    } // hierarchic_n_dofs()

    unsigned int hierarchic_n_dofs_at_node(const ElemType t,
					   const Order o,
					   const unsigned int n)
    {
      libmesh_assert (o > 0);
      switch (t)
	{
	case NODEELEM:
	  return 1;
	case EDGE2:
	case EDGE3:
	  switch (n)
	    {
	    case 0:
	    case 1:
	      return 1;
	      // Internal DoFs are associated with the elem, not its nodes
	    case 2:
	      return 0;
	    default:
	      libmesh_error();
	    }
	case TRI6:
	  switch (n)
	    {
	    case 0:
	    case 1:
	    case 2:
	      return 1;

	    case 3:
	    case 4:
	    case 5:
	      return (o-1);

	      // Internal DoFs are associated with the elem, not its nodes
	    default:
	      libmesh_error();
	    }
	case QUAD4:
	  libmesh_assert (n < 4);
	  libmesh_assert (o < 2);
	case QUAD8:
	case QUAD9:
	  switch (n)
	    {
	    case 0:
	    case 1:
	    case 2:
	    case 3:
	      return 1;

	    case 4:
	    case 5:
	    case 6:
	    case 7:
	      return (o-1);

	      // Internal DoFs are associated with the elem, not its nodes
	    case 8:
	      return 0;

	    default:
	      libmesh_error();
	    }
	case HEX8:
	  libmesh_assert (n < 8);
	  libmesh_assert (o < 2);
	case HEX20:
	  libmesh_assert (n < 20);
	  libmesh_assert (o < 2);
	case HEX27:
	  switch (n)
	    {
	    case 0:
	    case 1:
	    case 2:
	    case 3:
	    case 4:
	    case 5:
	    case 6:
	    case 7:
	      return 1;

	    case 8:
	    case 9:
	    case 10:
	    case 11:
	    case 12:
	    case 13:
	    case 14:
	    case 15:
	    case 16:
	    case 17:
	    case 18:
	    case 19:
	      return (o-1);

	    case 20:
	    case 21:
	    case 22:
	    case 23:
	    case 24:
	    case 25:
	      return ((o-1)*(o-1));

	      // Internal DoFs are associated with the elem, not its nodes
	    case 26:
	      return 0;
	    default:
	      libmesh_error();
	    }
	default:
#ifdef DEBUG
	  libMesh::err << "ERROR: Bad ElemType = " << t
		       << std::endl;
#endif
	  libmesh_error();
	}

      libmesh_error();

      return 0;
    } // hierarchic_n_dofs_at_node()

    unsigned int hierarchic_n_dofs_per_elem(const ElemType t,
					    const Order o)
    {
      libmesh_assert (o > 0);
      switch (t)
	{
	case NODEELEM:
	  return 0;
	case EDGE2:
	case EDGE3:
	  return (o-1);
	case TRI3:
	case QUAD4:
	  return 0;
	case TRI6:
	  return ((o-1)*(o-2)/2);
	case QUAD8:
	case QUAD9:
	  return ((o-1)*(o-1));
	case HEX8:
	case HEX20:
	  libmesh_assert(o < 2);
	  return 0;
	case HEX27:
	  return ((o-1)*(o-1)*(o-1));
	default:
#ifdef DEBUG
	  libMesh::err << "ERROR: Bad ElemType = " << t
		       << std::endl;
#endif
	  libmesh_error();
	}

      // Will never get here...
      libmesh_error();
      return 0;
    } // hierarchic_n_dofs_per_elem()

  } // anonymous namespace

  // Do full-specialization of nodal_soln() function for every
  // dimension, instead of explicit instantiation at the end of this
  // file.
  // This could be macro-ified so that it fits on one line...
  template <>
  void FE<0,HIERARCHIC>::nodal_soln(const Elem* elem,
				  const Order order,
				  const std::vector<Number>& elem_soln,
				  std::vector<Number>& nodal_soln)
  { hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); }

  template <>
  void FE<1,HIERARCHIC>::nodal_soln(const Elem* elem,
				  const Order order,
				  const std::vector<Number>& elem_soln,
				  std::vector<Number>& nodal_soln)
  { hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); }

  template <>
  void FE<2,HIERARCHIC>::nodal_soln(const Elem* elem,
				  const Order order,
				  const std::vector<Number>& elem_soln,
				  std::vector<Number>& nodal_soln)
  { hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); }

  template <>
  void FE<3,HIERARCHIC>::nodal_soln(const Elem* elem,
				  const Order order,
				  const std::vector<Number>& elem_soln,
				  std::vector<Number>& nodal_soln)
  { hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); }

  // Full specialization of n_dofs() function for every dimension
  template <> unsigned int FE<0,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
  template <> unsigned int FE<1,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
  template <> unsigned int FE<2,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }
  template <> unsigned int FE<3,HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return hierarchic_n_dofs(t, o); }

  // Full specialization of n_dofs_at_node() function for every dimension.
  template <> unsigned int FE<0,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
  template <> unsigned int FE<1,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
  template <> unsigned int FE<2,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }
  template <> unsigned int FE<3,HIERARCHIC>::n_dofs_at_node(const ElemType t, const Order o, const unsigned int n) { return hierarchic_n_dofs_at_node(t, o, n); }

  // Full specialization of n_dofs_per_elem() function for every dimension.
  template <> unsigned int FE<0,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
  template <> unsigned int FE<1,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
  template <> unsigned int FE<2,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }
  template <> unsigned int FE<3,HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return hierarchic_n_dofs_per_elem(t, o); }

  // Hierarchic FEMs are C^0 continuous
  template <> FEContinuity FE<0,HIERARCHIC>::get_continuity() const { return C_ZERO; }
  template <> FEContinuity FE<1,HIERARCHIC>::get_continuity() const { return C_ZERO; }
  template <> FEContinuity FE<2,HIERARCHIC>::get_continuity() const { return C_ZERO; }
  template <> FEContinuity FE<3,HIERARCHIC>::get_continuity() const { return C_ZERO; }

  // Hierarchic FEMs are hierarchic (duh!)
  template <> bool FE<0,HIERARCHIC>::is_hierarchic() const { return true; }
  template <> bool FE<1,HIERARCHIC>::is_hierarchic() const { return true; }
  template <> bool FE<2,HIERARCHIC>::is_hierarchic() const { return true; }
  template <> bool FE<3,HIERARCHIC>::is_hierarchic() const { return true; }

#ifdef LIBMESH_ENABLE_AMR
  // compute_constraints() specializations are only needed for 2 and 3D
  template <>
  void FE<2,HIERARCHIC>::compute_constraints (DofConstraints &constraints,
					      DofMap &dof_map,
					      const unsigned int variable_number,
					      const Elem* elem)
  { compute_proj_constraints(constraints, dof_map, variable_number, elem); }

  template <>
  void FE<3,HIERARCHIC>::compute_constraints (DofConstraints &constraints,
					      DofMap &dof_map,
					      const unsigned int variable_number,
					      const Elem* elem)
  { compute_proj_constraints(constraints, dof_map, variable_number, elem); }
#endif // #ifdef LIBMESH_ENABLE_AMR

  // Hierarchic FEM shapes need reinit
  template <> bool FE<0,HIERARCHIC>::shapes_need_reinit() const { return true; }
  template <> bool FE<1,HIERARCHIC>::shapes_need_reinit() const { return true; }
  template <> bool FE<2,HIERARCHIC>::shapes_need_reinit() const { return true; }
  template <> bool FE<3,HIERARCHIC>::shapes_need_reinit() const { return true; }

} // namespace libMesh
<|endoftext|>


<commit_before>#include "../include/carta.h"
#include "../include/to_string.h"

#define CARD_WIDTH 125
#define CARD_HEIGHT 164

using namespace std;

Carta::Carta(){}

Carta::Carta(int num, SDL_Renderer* renderer){
	string dir = "../textures/cards/";
	int i = (num-1)/13;
	this->value = num-13*i;
	this->suit = 65+i;
	dir.append(to_string(this->value));
	dir.push_back(this->suit);
	dir.append(".png");
	this->gTexture = Textura(dir, renderer, 0, 0, CARD_WIDTH, CARD_HEIGHT);
}

void Carta::setPosition(SDL_Point coord){
	SDL_Log("%d", coord.y);
	this->gTexture.setPosition(coord);
}

void Carta::render() {
	this->gTexture.render();
}

int Carta::getValue(){
	return this->value;
}

char Carta::getSuit(){
	return this->suit;
}
<commit_msg>Log resolvido<commit_after>#include "../include/carta.h"
#include "../include/to_string.h"

#define CARD_WIDTH 125
#define CARD_HEIGHT 164

using namespace std;

Carta::Carta(){}

Carta::Carta(int num, SDL_Renderer* renderer){
	string dir = "../textures/cards/";
	int i = (num-1)/13;
	this->value = num-13*i;
	this->suit = 65+i;
	dir.append(to_string(this->value));
	dir.push_back(this->suit);
	dir.append(".png");
	this->gTexture = Textura(dir, renderer, 0, 0, CARD_WIDTH, CARD_HEIGHT);
}

void Carta::setPosition(SDL_Point coord){
	this->gTexture.setPosition(coord);
}

void Carta::render() {
	this->gTexture.render();
}

int Carta::getValue(){
	return this->value;
}

char Carta::getSuit(){
	return this->suit;
}
<|endoftext|>


<commit_before>#include <tianchi/file/tcmsexcel.h>
#include <tianchi/core/tccommon.h>
#include <tianchi/core/tcutils.h>

#include <QList>

#if defined(Q_OS_WIN)
#include <ActiveQt/QAxObject>
#endif // Q_OS_WIN

class TcMSExcelPrivate
{
    Q_DECLARE_PUBLIC(TcMSExcel)
public:
    explicit TcMSExcelPrivate(TcMSExcel* qptr);
    ~TcMSExcelPrivate();

    void construct();
    void destory();

    TcMSExcel* const q_ptr;

#if defined(Q_OS_WIN)
    QAxObject*  excel;
    QAxObject*  books;
    QAxObject*  book;
    QAxObject*  sheets;
    QAxObject*  sheet;
#endif
    QString     filename;
    QString     sheetName;
};

TcMSExcelPrivate::TcMSExcelPrivate(TcMSExcel *qptr)
    : q_ptr(qptr)
#if defined(Q_OS_WIN)
    , excel(NULL)
    , books(NULL)
    , book(NULL)
    , sheets(NULL)
    , sheet(NULL)
#endif // Q_OS_WIN
{
}

TcMSExcelPrivate::~TcMSExcelPrivate()
{
#if defined(Q_OS_WIN)
    if (!excel->isNull())
    {
        excel->dynamicCall("Quit()");
    }
    TC_FREE(sheet );
    TC_FREE(sheets);
    TC_FREE(book  );
    TC_FREE(books );
    TC_FREE(excel );
#endif // Q_OS_WIN
}

void TcMSExcelPrivate::construct()
{
#if defined(Q_OS_WIN)
    destory();
    excel->setControl("Excel.Application");
    if (excel->isNull())
    {
        excel->setControl("ET.Application");
    }
    if (!excel->isNull())
    {
        books = excel->querySubObject("Workbooks");
    }
#endif // Q_OS_WIN
}

void TcMSExcelPrivate::destory()
{
#if defined(Q_OS_WIN)
    TC_FREE(sheet );
    TC_FREE(sheets);
    if (book != NULL && ! book->isNull())
    {
        book->dynamicCall("Close(Boolean)", false);
    }
    TC_FREE(book );
    TC_FREE(books);
    if (excel != NULL && ! excel->isNull())
    {
        excel->dynamicCall("Quit()");
    }
    TC_FREE(excel);
    filename  = "";
    sheetName = "";
#endif // Q_OS_WIN
}

TcMSExcel::TcMSExcel()
    : d_ptr(new TcMSExcelPrivate(this))
{
}

TcMSExcel::~TcMSExcel()
{
    close();
    delete d_ptr;
}

bool TcMSExcel::create(const QString& filename)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    d->construct();
    if (d->books != NULL && ! d->books->isNull())
    {
        d->books->dynamicCall("Add");
        d->book   = d->excel->querySubObject("ActiveWorkBook");
        d->sheets = d->book ->querySubObject("WorkSheets"    );
        currentSheet();
        d->filename = filename;
        ret = true;
    }
#else
    Q_UNUSED(filename)
#endif // Q_OS_WIN
    return ret;
}

bool TcMSExcel::open(const QString& filename)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    d->construct();
    if ( d->books != NULL && ! d->books->isNull() )
    {
        d->book = d->books->querySubObject("Open(QString, QVariant)", filename, 0);
        ret = d->book != NULL && ! d->book->isNull();
        if ( ret )
        {
            d->sheets = d->book->querySubObject("WorkSheets");
            d->filename = filename;
            currentSheet();
        }
    }
#else
    Q_UNUSED(filename)
#endif // Q_OS_WIN
    return ret;
}

void TcMSExcel::save(const QString& filename)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if ( d->books != NULL && ! d->books->isNull() )
    {
        d->filename = filename;
        d->books->dynamicCall("SaveAs(const QString&)", d->filename);
    }
#else
    Q_UNUSED(filename)
#endif // Q_OS_WIN
}

void TcMSExcel::close()
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    d->destory();
#endif // Q_OS_WIN
}

void TcMSExcel::kick()
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);

    if (d->excel != NULL && !d->excel->isNull())
    {
        d->excel->setProperty("Visible", true);
    }
    TC_FREE(d->sheet );
    TC_FREE(d->sheets);
    TC_FREE(d->book  );
    TC_FREE(d->books );
    TC_FREE(d->excel );
    d->destory();
#endif // Q_OS_WIN
}

QStringList TcMSExcel::sheetNames()
{
    QStringList ret;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheets != NULL && !d->sheets->isNull())
    {
        int sheetCount = d->sheets->property("Count").toInt();
        for (int i = 1; i <= sheetCount; i++)
        {
            QAxObject* sheet = d->sheets->querySubObject("Item(int)", i);
            ret.append(sheet->property("Name").toString());
        }
    }
#endif // Q_OS_WIN
    return ret;
}

QString TcMSExcel::currentSheetName()
{
    Q_D(TcMSExcel);
    return d->sheetName;
}

void TcMSExcel::setVisible(bool value)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->excel != NULL && !d->excel->isNull())
    {
        d->excel->setProperty("Visible", value);
    }
#else
    Q_UNUSED(value)
#endif // Q_OS_WIN
}

void TcMSExcel::setCaption(const QString& value)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->excel != NULL && !d->excel->isNull())
    {
        d->excel->setProperty("Caption", value);
    }
#else
    Q_UNUSED(value)
#endif // Q_OS_WIN
}

bool TcMSExcel::addBook()
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->excel != NULL && !d->excel->isNull())
    {
        TC_FREE(d->sheet );
        TC_FREE(d->sheets);
        TC_FREE(d->book  );
        TC_FREE(d->books );
        d->books = d->excel->querySubObject("WorkBooks");
        ret = d->books != NULL && !d->books->isNull();
    }
#endif // Q_OS_WIN
    return ret;
}

bool TcMSExcel::currentSheet()
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    TC_FREE(d->sheet);
    if (d->excel != NULL && !d->excel->isNull())
    {
        TC_FREE(d->sheet);
        d->sheet = d->excel->querySubObject("ActiveWorkBook");
        ret = d->sheet != NULL && !d->sheet->isNull();
        d->sheetName = ret ? d->sheet->property("Name").toString() : "";
    }
#endif // Q_OS_WIN
    return ret;
}

bool TcMSExcel::setCurrentSheet(int index)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheets != NULL && !d->sheets->isNull())
    {
        TC_FREE(d->sheet);
        d->sheet = d->sheets->querySubObject("Item(int)", index);
        ret = d->sheet != NULL && ! d->sheet->isNull();
        d->sheetName = ret ? d->sheet->property("Name").toString() : "";
    }
#else
    Q_UNUSED(index)
#endif // Q_OS_WIN
    return ret;
}

int TcMSExcel::sheetCount()
{
    int ret = 0;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheets != NULL && ! d->sheets->isNull())
    {
        ret = d->sheets->property("Count").toInt();
    }
#endif // Q_OS_WIN
    return ret;
}

void TcMSExcel::cellFormat(int row, int col, const QString& format)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        range->setProperty("NumberFormatLocal", format);
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
    Q_UNUSED(format)
#endif // Q_OS_WIN
}

void TcMSExcel::cellAlign(int row, int col, Alignment hAlign, Alignment vAlign)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && !d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        range->setProperty("HorizontalAlignment", hAlign);
        range->setProperty("VerticalAlignment",   vAlign);
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
    Q_UNUSED(hAlign)
    Q_UNUSED(vAlign)
#endif // Q_OS_WIN
}

QVariant TcMSExcel::read(int row, int col)
{
    QVariant ret;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        //ret = range->property("Value");
        ret = range->dynamicCall("Value()");
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
#endif // Q_OS_WIN
    return ret;
}

void TcMSExcel::write(int row, int col, const QVariant& value)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        range->setProperty("Value", value);
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
    Q_UNUSED(value)
#endif // Q_OS_WIN
}

bool TcMSExcel::usedRange(int& rowStart, int& colStart, int& rowEnd, int& colEnd)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* urange  = d->sheet->querySubObject("UsedRange");
        rowStart = urange->property("Row"   ).toInt();
        colStart = urange->property("Column").toInt();
        rowEnd   = urange->querySubObject("Rows"   )->property("Count").toInt();
        colEnd   = urange->querySubObject("Columns")->property("Count").toInt();
        delete urange;
        ret = true;
    }
#else
    Q_UNUSED(rowStart)
    Q_UNUSED(colStart)
    Q_UNUSED(rowEnd)
    Q_UNUSED(colEnd)
#endif // Q_OS_WIN
    return ret;
}
<commit_msg>fix a tcmsexcel.cpp's books->SaveAs call's error<commit_after>#include <tianchi/file/tcmsexcel.h>
#include <tianchi/core/tccommon.h>
#include <tianchi/core/tcutils.h>

#include <QList>

#if defined(Q_OS_WIN)
#include <ActiveQt/QAxObject>
#endif // Q_OS_WIN

class TcMSExcelPrivate
{
    Q_DECLARE_PUBLIC(TcMSExcel)
public:
    explicit TcMSExcelPrivate(TcMSExcel* qptr);
    ~TcMSExcelPrivate();

    void construct();
    void destory();

    TcMSExcel* const q_ptr;

#if defined(Q_OS_WIN)
    QAxObject*  excel;
    QAxObject*  books;
    QAxObject*  book;
    QAxObject*  sheets;
    QAxObject*  sheet;
#endif
    QString     filename;
    QString     sheetName;
};

TcMSExcelPrivate::TcMSExcelPrivate(TcMSExcel *qptr)
    : q_ptr(qptr)
#if defined(Q_OS_WIN)
    , excel(NULL)
    , books(NULL)
    , book(NULL)
    , sheets(NULL)
    , sheet(NULL)
#endif // Q_OS_WIN
{
}

TcMSExcelPrivate::~TcMSExcelPrivate()
{
#if defined(Q_OS_WIN)
    if (!excel->isNull())
    {
        excel->dynamicCall("Quit()");
    }
    TC_FREE(sheet );
    TC_FREE(sheets);
    TC_FREE(book  );
    TC_FREE(books );
    TC_FREE(excel );
#endif // Q_OS_WIN
}

void TcMSExcelPrivate::construct()
{
#if defined(Q_OS_WIN)
    destory();
    excel->setControl("Excel.Application");
    if (excel->isNull())
    {
        excel->setControl("ET.Application");
    }
    if (!excel->isNull())
    {
        books = excel->querySubObject("Workbooks");
    }
#endif // Q_OS_WIN
}

void TcMSExcelPrivate::destory()
{
#if defined(Q_OS_WIN)
    TC_FREE(sheet );
    TC_FREE(sheets);
    if (book != NULL && ! book->isNull())
    {
        book->dynamicCall("Close(Boolean)", false);
    }
    TC_FREE(book );
    TC_FREE(books);
    if (excel != NULL && ! excel->isNull())
    {
        excel->dynamicCall("Quit()");
    }
    TC_FREE(excel);
    filename  = "";
    sheetName = "";
#endif // Q_OS_WIN
}

TcMSExcel::TcMSExcel()
    : d_ptr(new TcMSExcelPrivate(this))
{
}

TcMSExcel::~TcMSExcel()
{
    close();
    delete d_ptr;
}

bool TcMSExcel::create(const QString& filename)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    d->construct();
    if (d->books != NULL && ! d->books->isNull())
    {
        d->books->dynamicCall("Add");
        d->book   = d->excel->querySubObject("ActiveWorkBook");
        d->sheets = d->book ->querySubObject("WorkSheets"    );
        currentSheet();
        d->filename = filename;
        ret = true;
    }
#else
    Q_UNUSED(filename)
#endif // Q_OS_WIN
    return ret;
}

bool TcMSExcel::open(const QString& filename)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    d->construct();
    if ( d->books != NULL && ! d->books->isNull() )
    {
        d->book = d->books->querySubObject("Open(QString, QVariant)", filename, 0);
        ret = d->book != NULL && ! d->book->isNull();
        if ( ret )
        {
            d->sheets = d->book->querySubObject("WorkSheets");
            d->filename = filename;
            currentSheet();
        }
    }
#else
    Q_UNUSED(filename)
#endif // Q_OS_WIN
    return ret;
}

void TcMSExcel::save(const QString& filename)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->book != NULL && !d->book->isNull())
    {
        d->filename = filename;
        d->book->dynamicCall("SaveAs(const QString&)", d->filename);
    }
#else
    Q_UNUSED(filename)
#endif // Q_OS_WIN
}

void TcMSExcel::close()
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    d->destory();
#endif // Q_OS_WIN
}

void TcMSExcel::kick()
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);

    if (d->excel != NULL && !d->excel->isNull())
    {
        d->excel->setProperty("Visible", true);
    }
    TC_FREE(d->sheet );
    TC_FREE(d->sheets);
    TC_FREE(d->book  );
    TC_FREE(d->books );
    TC_FREE(d->excel );
    d->destory();
#endif // Q_OS_WIN
}

QStringList TcMSExcel::sheetNames()
{
    QStringList ret;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheets != NULL && !d->sheets->isNull())
    {
        int sheetCount = d->sheets->property("Count").toInt();
        for (int i = 1; i <= sheetCount; i++)
        {
            QAxObject* sheet = d->sheets->querySubObject("Item(int)", i);
            ret.append(sheet->property("Name").toString());
        }
    }
#endif // Q_OS_WIN
    return ret;
}

QString TcMSExcel::currentSheetName()
{
    Q_D(TcMSExcel);
    return d->sheetName;
}

void TcMSExcel::setVisible(bool value)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->excel != NULL && !d->excel->isNull())
    {
        d->excel->setProperty("Visible", value);
    }
#else
    Q_UNUSED(value)
#endif // Q_OS_WIN
}

void TcMSExcel::setCaption(const QString& value)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->excel != NULL && !d->excel->isNull())
    {
        d->excel->setProperty("Caption", value);
    }
#else
    Q_UNUSED(value)
#endif // Q_OS_WIN
}

bool TcMSExcel::addBook()
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->excel != NULL && !d->excel->isNull())
    {
        TC_FREE(d->sheet );
        TC_FREE(d->sheets);
        TC_FREE(d->book  );
        TC_FREE(d->books );
        d->books = d->excel->querySubObject("WorkBooks");
        ret = d->books != NULL && !d->books->isNull();
    }
#endif // Q_OS_WIN
    return ret;
}

bool TcMSExcel::currentSheet()
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    TC_FREE(d->sheet);
    if (d->excel != NULL && !d->excel->isNull())
    {
        TC_FREE(d->sheet);
        d->sheet = d->excel->querySubObject("ActiveWorkBook");
        ret = d->sheet != NULL && !d->sheet->isNull();
        d->sheetName = ret ? d->sheet->property("Name").toString() : "";
    }
#endif // Q_OS_WIN
    return ret;
}

bool TcMSExcel::setCurrentSheet(int index)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheets != NULL && !d->sheets->isNull())
    {
        TC_FREE(d->sheet);
        d->sheet = d->sheets->querySubObject("Item(int)", index);
        ret = d->sheet != NULL && ! d->sheet->isNull();
        d->sheetName = ret ? d->sheet->property("Name").toString() : "";
    }
#else
    Q_UNUSED(index)
#endif // Q_OS_WIN
    return ret;
}

int TcMSExcel::sheetCount()
{
    int ret = 0;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheets != NULL && ! d->sheets->isNull())
    {
        ret = d->sheets->property("Count").toInt();
    }
#endif // Q_OS_WIN
    return ret;
}

void TcMSExcel::cellFormat(int row, int col, const QString& format)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        range->setProperty("NumberFormatLocal", format);
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
    Q_UNUSED(format)
#endif // Q_OS_WIN
}

void TcMSExcel::cellAlign(int row, int col, Alignment hAlign, Alignment vAlign)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && !d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        range->setProperty("HorizontalAlignment", hAlign);
        range->setProperty("VerticalAlignment",   vAlign);
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
    Q_UNUSED(hAlign)
    Q_UNUSED(vAlign)
#endif // Q_OS_WIN
}

QVariant TcMSExcel::read(int row, int col)
{
    QVariant ret;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        //ret = range->property("Value");
        ret = range->dynamicCall("Value()");
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
#endif // Q_OS_WIN
    return ret;
}

void TcMSExcel::write(int row, int col, const QVariant& value)
{
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* range = d->sheet->querySubObject("Cells(int, int)", row, col);
        range->setProperty("Value", value);
        delete range;
    }
#else
    Q_UNUSED(row)
    Q_UNUSED(col)
    Q_UNUSED(value)
#endif // Q_OS_WIN
}

bool TcMSExcel::usedRange(int& rowStart, int& colStart, int& rowEnd, int& colEnd)
{
    bool ret = false;
#if defined(Q_OS_WIN)
    Q_D(TcMSExcel);
    if (d->sheet != NULL && ! d->sheet->isNull())
    {
        QAxObject* urange  = d->sheet->querySubObject("UsedRange");
        rowStart = urange->property("Row"   ).toInt();
        colStart = urange->property("Column").toInt();
        rowEnd   = urange->querySubObject("Rows"   )->property("Count").toInt();
        colEnd   = urange->querySubObject("Columns")->property("Count").toInt();
        delete urange;
        ret = true;
    }
#else
    Q_UNUSED(rowStart)
    Q_UNUSED(colStart)
    Q_UNUSED(rowEnd)
    Q_UNUSED(colEnd)
#endif // Q_OS_WIN
    return ret;
}
<|endoftext|>


<commit_before><commit_msg>Catch attempts to open /assets files read-write. Improve debugging output<commit_after><|endoftext|>