<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iomanip>
#include <istream>
#include <sstream>
#include <iostream>
#include <string>

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>

#include <boost/spirit/include/classic_position_iterator.hpp>

#include "parser/SpiritParser.hpp"
#include "lexer/SpiritLexer.hpp"

#include "ast/Program.hpp"

namespace qi = boost::spirit::qi;

using namespace eddic;

template <typename Iterator, typename AttributeT>
struct Rule {
    typedef typename boost::spirit::qi::rule<Iterator, AttributeT> type;
};

template <typename Iterator, typename Lexer>
struct EddiGrammar : qi::grammar<Iterator, ASTProgram()> {
    EddiGrammar(const Lexer& lexer) : EddiGrammar::base_type(program, "EDDI Grammar") {
        value = additiveValue.alias();

        additiveValue %=
                multiplicativeValue
            >>  *(
                    (lexer.addition >> multiplicativeValue)
                |   (lexer.subtraction >> multiplicativeValue)
                );

        multiplicativeValue %=
                unaryValue
            >>  *(
                    (lexer.multiplication >> unaryValue)
                |   (lexer.division >> unaryValue)
                |   (lexer.modulo >> unaryValue)
                );

        //TODO Support + - primaryValue
        unaryValue = primaryValue.alias();

        primaryValue =
                constant
            |   variable
            |   (lexer.left_parenth >> value >> lexer.right_parenth);

        integer %=
                qi::eps
            >>  lexer.integer;

        variable %=
                qi::eps
            >>  lexer.word;

        litteral %=
                qi::eps
            >> lexer.litteral;

        constant %=
                integer
            |   litteral;

        true_ %=
                qi::eps
            >>  lexer.true_;

        false_ %=
                qi::eps
            >>  lexer.false_;

        binary_condition %=
                value
            >>  (
                    lexer.greater_equals
                |   lexer.greater
                |   lexer.less_equals
                |   lexer.less
                |   lexer.not_equals
                |   lexer.equals
                )
            >>  value;

        condition %=
                true_
            |   false_
            |   binary_condition;

        else_if_ %=
                lexer.else_
            >>  lexer.if_
            >>  lexer.left_parenth
            >>  condition
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        else_ %=
                lexer.else_
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        if_ %=
                lexer.if_
            >>  lexer.left_parenth
            >>  condition
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace
            >>  *(else_if_)
            >>  -(else_);

        for_ %=
                lexer.for_
            >>  lexer.left_parenth
            >>  -declaration
            >>  lexer.stop
            >>  -condition
            >>  lexer.stop
            >>  -repeatable_instruction
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  (*instruction)
            >>  lexer.right_brace;

        foreach_ =
                lexer.foreach_
            >>  lexer.left_parenth
            >>  lexer.word
            >>  lexer.word
            >>  lexer.from_
            >>  lexer.integer
            >>  lexer.to_
            >>  lexer.integer
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        while_ %=
                lexer.while_
            >>  lexer.left_parenth
            >>  condition
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        declaration %=
                lexer.word
            >>  lexer.word
            >>  lexer.assign
            >>  value;

        assignment %=
                lexer.word
            >>  lexer.assign
            >>  value;

        globalDeclaration %=
                lexer.word
            >>  lexer.word
            >>  lexer.assign
            >>  constant
            >>  lexer.stop;

        functionCall %=
                lexer.word
            >>  lexer.left_parenth
            >>  -( value >> *( lexer.comma >> value))
            >>  lexer.right_parenth;

        swap %=
                lexer.word
            >>  lexer.swap
            >>  lexer.word;

        instruction %=
                (functionCall > lexer.stop)
            |   (swap > lexer.stop)
            |   (assignment > lexer.stop)
            |   (declaration > lexer.stop)
            |   while_
            |   for_
            |   foreach_
            |   if_;

        repeatable_instruction = assignment | declaration | swap;

        arg %=
                lexer.word
            >>  lexer.word;

        function %=
                lexer.word
            >>  lexer.word
            >>  lexer.left_parenth
            >>  -( arg >> *( lexer.comma >> arg))
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        program %=
                qi::eps
            >>  *(globalDeclaration | function);

        //Name the rules
        globalDeclaration.name("EDDI global variable");
        function.name("EDDI function declaration");
        program.name("EDDI program");
   }

   //Rule<Iterator, Deferred<ASTProgram>()>::type program;

   qi::rule<Iterator, ASTProgram()> program;
   qi::rule<Iterator, GlobalVariableDeclaration()> globalDeclaration;
   qi::rule<Iterator, ASTFunctionDeclaration()> function;
   qi::rule<Iterator, FunctionParameter()> arg;

   qi::rule<Iterator, ASTInstruction()> instruction;
   qi::rule<Iterator, ASTInstruction()> repeatable_instruction;
   qi::rule<Iterator, ASTSwap()> swap;
   qi::rule<Iterator, ASTFunctionCall()> functionCall;
   qi::rule<Iterator, ASTDeclaration()> declaration;
   qi::rule<Iterator, ASTAssignment()> assignment;
   qi::rule<Iterator, ASTWhile()> while_;
   qi::rule<Iterator, ASTFor()> for_;
   qi::rule<Iterator, ASTForeach()> foreach_;
   qi::rule<Iterator, ASTIf()> if_;
   qi::rule<Iterator, ASTElse()> else_;
   qi::rule<Iterator, ASTElseIf()> else_if_;

   qi::rule<Iterator, ASTValue()> value;
   qi::rule<Iterator, ASTValue()> primaryValue;
   qi::rule<Iterator, ASTValue()> unaryValue;
   qi::rule<Iterator, ASTComposedValue()> additiveValue;
   qi::rule<Iterator, ASTComposedValue()> multiplicativeValue;
   qi::rule<Iterator, ASTValue()> constant;
   qi::rule<Iterator, ASTInteger()> integer;
   qi::rule<Iterator, ASTLitteral()> litteral;
   qi::rule<Iterator, ASTVariable()> variable;

   qi::rule<Iterator, ASTCondition()> condition;
   qi::rule<Iterator, ASTTrue()> true_;
   qi::rule<Iterator, ASTFalse()> false_;
   qi::rule<Iterator, ASTBinaryCondition()> binary_condition;
};

bool SpiritParser::parse(const std::string& file, ASTProgram& program){
    std::ifstream in(file.c_str());
    in.unsetf(std::ios::skipws);

    std::string contents;
    std::copy(
            std::istream_iterator<char>(in),
            std::istream_iterator<char>(),
            std::back_inserter(contents));

    pos_iterator_type position_begin(contents.begin(), contents.end(), file);
    pos_iterator_type position_end;

    SimpleLexer<lexer_type> lexer;
    EddiGrammar<lexer_type::iterator_type, SimpleLexer<lexer_type>> grammar(lexer);

    try {
        bool r = lex::tokenize_and_parse(position_begin, position_end, lexer, grammar, program);

        if(r && position_begin == position_end) {
            std::cout << "Parsing passed" << std::endl;

            return true;
        } else {
            std::cout << "Parsing failed" << std::endl;
            const spirit::classic::file_position_base<std::string>& pos = position_begin.get_position();
            std::cout <<
                "Error at file " << pos.file << " line " << pos.line << " column " << pos.column << std::endl <<
                "'" << position_begin.get_currentline() << "'" << std::endl <<
                std::setw(pos.column) << " " << "^- here";

            return false;
        }
    } catch (const qi::expectation_failure<lexer_type::iterator_type>& exception) {
        std::cout << "Parsing failed" << std::endl;

        //TODO Improve to get information from exception
        const spirit::classic::file_position_base<std::string>& pos = position_begin.get_position();

        std::cout <<
            "Error at file " << pos.file << " line " << pos.line << " column " << pos.column << " Expecting " << exception.what_ << std::endl <<
            "'" << position_begin.get_currentline() << "'" << std::endl <<
            std::setw(pos.column) << " " << "^- here" << std::endl;

        return false;
    }
}
<commit_msg>An arg is always composed of a type and a name<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iomanip>
#include <istream>
#include <sstream>
#include <iostream>
#include <string>

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>

#include <boost/spirit/include/classic_position_iterator.hpp>

#include "parser/SpiritParser.hpp"
#include "lexer/SpiritLexer.hpp"

#include "ast/Program.hpp"

namespace qi = boost::spirit::qi;

using namespace eddic;

template <typename Iterator, typename AttributeT>
struct Rule {
    typedef typename boost::spirit::qi::rule<Iterator, AttributeT> type;
};

template <typename Iterator, typename Lexer>
struct EddiGrammar : qi::grammar<Iterator, ASTProgram()> {
    EddiGrammar(const Lexer& lexer) : EddiGrammar::base_type(program, "EDDI Grammar") {
        value = additiveValue.alias();

        additiveValue %=
                multiplicativeValue
            >>  *(
                    (lexer.addition >> multiplicativeValue)
                |   (lexer.subtraction >> multiplicativeValue)
                );

        multiplicativeValue %=
                unaryValue
            >>  *(
                    (lexer.multiplication >> unaryValue)
                |   (lexer.division >> unaryValue)
                |   (lexer.modulo >> unaryValue)
                );

        //TODO Support + - primaryValue
        unaryValue = primaryValue.alias();

        primaryValue =
                constant
            |   variable
            |   (lexer.left_parenth >> value >> lexer.right_parenth);

        integer %=
                qi::eps
            >>  lexer.integer;

        variable %=
                qi::eps
            >>  lexer.word;

        litteral %=
                qi::eps
            >> lexer.litteral;

        constant %=
                integer
            |   litteral;

        true_ %=
                qi::eps
            >>  lexer.true_;

        false_ %=
                qi::eps
            >>  lexer.false_;

        binary_condition %=
                value
            >>  (
                    lexer.greater_equals
                |   lexer.greater
                |   lexer.less_equals
                |   lexer.less
                |   lexer.not_equals
                |   lexer.equals
                )
            >>  value;

        condition %=
                true_
            |   false_
            |   binary_condition;

        else_if_ %=
                lexer.else_
            >>  lexer.if_
            >>  lexer.left_parenth
            >>  condition
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        else_ %=
                lexer.else_
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        if_ %=
                lexer.if_
            >>  lexer.left_parenth
            >>  condition
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace
            >>  *(else_if_)
            >>  -(else_);

        for_ %=
                lexer.for_
            >>  lexer.left_parenth
            >>  -declaration
            >>  lexer.stop
            >>  -condition
            >>  lexer.stop
            >>  -repeatable_instruction
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  (*instruction)
            >>  lexer.right_brace;

        foreach_ =
                lexer.foreach_
            >>  lexer.left_parenth
            >>  lexer.word
            >>  lexer.word
            >>  lexer.from_
            >>  lexer.integer
            >>  lexer.to_
            >>  lexer.integer
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        while_ %=
                lexer.while_
            >>  lexer.left_parenth
            >>  condition
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        declaration %=
                lexer.word
            >>  lexer.word
            >>  lexer.assign
            >>  value;

        assignment %=
                lexer.word
            >>  lexer.assign
            >>  value;

        globalDeclaration %=
                lexer.word
            >>  lexer.word
            >>  lexer.assign
            >>  constant
            >>  lexer.stop;

        functionCall %=
                lexer.word
            >>  lexer.left_parenth
            >>  -( value >> *( lexer.comma >> value))
            >>  lexer.right_parenth;

        swap %=
                lexer.word
            >>  lexer.swap
            >>  lexer.word;

        instruction %=
                (functionCall > lexer.stop)
            |   (swap > lexer.stop)
            |   (assignment > lexer.stop)
            |   (declaration > lexer.stop)
            |   while_
            |   for_
            |   foreach_
            |   if_;

        repeatable_instruction = assignment | declaration | swap;

        arg %=
                lexer.word
            >   lexer.word;

        function %=
                lexer.word
            >>  lexer.word
            >>  lexer.left_parenth
            >>  -( arg >> *( lexer.comma >> arg))
            >>  lexer.right_parenth
            >>  lexer.left_brace
            >>  *(instruction)
            >>  lexer.right_brace;

        program %=
                qi::eps
            >>  *(globalDeclaration | function);

        //Name the rules
        globalDeclaration.name("EDDI global variable");
        function.name("EDDI function declaration");
        program.name("EDDI program");
   }

   //Rule<Iterator, Deferred<ASTProgram>()>::type program;

   qi::rule<Iterator, ASTProgram()> program;
   qi::rule<Iterator, GlobalVariableDeclaration()> globalDeclaration;
   qi::rule<Iterator, ASTFunctionDeclaration()> function;
   qi::rule<Iterator, FunctionParameter()> arg;

   qi::rule<Iterator, ASTInstruction()> instruction;
   qi::rule<Iterator, ASTInstruction()> repeatable_instruction;
   qi::rule<Iterator, ASTSwap()> swap;
   qi::rule<Iterator, ASTFunctionCall()> functionCall;
   qi::rule<Iterator, ASTDeclaration()> declaration;
   qi::rule<Iterator, ASTAssignment()> assignment;
   qi::rule<Iterator, ASTWhile()> while_;
   qi::rule<Iterator, ASTFor()> for_;
   qi::rule<Iterator, ASTForeach()> foreach_;
   qi::rule<Iterator, ASTIf()> if_;
   qi::rule<Iterator, ASTElse()> else_;
   qi::rule<Iterator, ASTElseIf()> else_if_;

   qi::rule<Iterator, ASTValue()> value;
   qi::rule<Iterator, ASTValue()> primaryValue;
   qi::rule<Iterator, ASTValue()> unaryValue;
   qi::rule<Iterator, ASTComposedValue()> additiveValue;
   qi::rule<Iterator, ASTComposedValue()> multiplicativeValue;
   qi::rule<Iterator, ASTValue()> constant;
   qi::rule<Iterator, ASTInteger()> integer;
   qi::rule<Iterator, ASTLitteral()> litteral;
   qi::rule<Iterator, ASTVariable()> variable;

   qi::rule<Iterator, ASTCondition()> condition;
   qi::rule<Iterator, ASTTrue()> true_;
   qi::rule<Iterator, ASTFalse()> false_;
   qi::rule<Iterator, ASTBinaryCondition()> binary_condition;
};

bool SpiritParser::parse(const std::string& file, ASTProgram& program){
    std::ifstream in(file.c_str());
    in.unsetf(std::ios::skipws);

    std::string contents;
    std::copy(
            std::istream_iterator<char>(in),
            std::istream_iterator<char>(),
            std::back_inserter(contents));

    pos_iterator_type position_begin(contents.begin(), contents.end(), file);
    pos_iterator_type position_end;

    SimpleLexer<lexer_type> lexer;
    EddiGrammar<lexer_type::iterator_type, SimpleLexer<lexer_type>> grammar(lexer);

    try {
        bool r = lex::tokenize_and_parse(position_begin, position_end, lexer, grammar, program);

        if(r && position_begin == position_end) {
            std::cout << "Parsing passed" << std::endl;

            return true;
        } else {
            std::cout << "Parsing failed" << std::endl;
            const spirit::classic::file_position_base<std::string>& pos = position_begin.get_position();
            std::cout <<
                "Error at file " << pos.file << " line " << pos.line << " column " << pos.column << std::endl <<
                "'" << position_begin.get_currentline() << "'" << std::endl <<
                std::setw(pos.column) << " " << "^- here";

            return false;
        }
    } catch (const qi::expectation_failure<lexer_type::iterator_type>& exception) {
        std::cout << "Parsing failed" << std::endl;

        //TODO Improve to get information from exception
        const spirit::classic::file_position_base<std::string>& pos = position_begin.get_position();

        std::cout <<
            "Error at file " << pos.file << " line " << pos.line << " column " << pos.column << " Expecting " << exception.what_ << std::endl <<
            "'" << position_begin.get_currentline() << "'" << std::endl <<
            std::setw(pos.column) << " " << "^- here" << std::endl;

        return false;
    }
}
<|endoftext|>


<commit_before>// Matlab driver main.
//
// Kota Yamaguchi 2013 <kyamagu@cs.stonybrook.edu>

#include "lda.h"
#include "mex/arguments.h"
#include "mex/function.h"
#include "mex/mxarray.h"
#include "mex.h"
#include <numeric>
#include <stdlib.h>
#include <string>
#include <vector>

using namespace std;

using mex::CheckInputArguments;
using mex::CheckOutputArguments;
using mex::MxArray;

// Alias for the mex error function.
#define ERROR(...) mexErrMsgIdAndTxt("lda:error", __VA_ARGS__)

#define CHECK_NOTNULL(pointer) \
  if (pointer == NULL) ERROR("Null pointer exception.")

#define MEX_FLUSH mexEvalString("drawnow")

namespace {

// Reset random number.
void ResetRandomNumber() {
  seedMT(get_settings()->RANDOM_SEED);
}

// Read settings from a struct.
void ReadSettings(const mxArray* mxarray) {
  MxArray config(mxarray);
  lda_settings* settings = get_settings();
  if (config.isField("var_max_iter"))
    settings->VAR_MAX_ITER = config.at("var_max_iter").toInt();
  if (config.isField("var_converged"))
    settings->VAR_CONVERGED = config.at("var_converged").toDouble();
  if (config.isField("em_max_iter"))
    settings->EM_MAX_ITER = config.at("em_max_iter").toInt();
  if (config.isField("em_convergence"))
    settings->EM_CONVERGED = config.at("em_convergence").toDouble();
  if (config.isField("estimate_alpha"))
    settings->ESTIMATE_ALPHA = config.at("estimate_alpha").toInt();
  if (config.isField("initial_alpha"))
    settings->INITIAL_ALPHA = config.at("initial_alpha").toDouble();
  if (config.isField("num_topics"))
    settings->NTOPICS = config.at("num_topics").toInt();
  if (config.isField("random_seed"))
    settings->RANDOM_SEED = config.at("random_seed").toInt();
  if (config.isField("verbose"))
    settings->VERBOSE = config.at("verbose").toInt();
}

// Read data into corpus. Call free_data() after use.
lda_corpus* ReadCorpusFromMxArray(const mxArray* input) {
  if (!mxIsSparse(input) || !mxIsDouble(input))
    ERROR("Input data must be a sparse double array.");
  lda_corpus* corpus = (lda_corpus*)malloc(sizeof(corpus));
  CHECK_NOTNULL(corpus);
  // Get values from mxArray.
  vector<vector<pair<int, int> > > data(mxGetM(input));
  mwIndex* row_pointer = mxGetIr(input);
  mwIndex* column_pointer = mxGetJc(input);
  double* data_pointer = mxGetPr(input);
  for (int j = 0; j < mxGetN(input); ++j) {
    int column_elements = column_pointer[j+1] - column_pointer[j];
    for (int i = 0; i < column_elements; ++i) {
      pair<int, int> value(j, static_cast<int>(*data_pointer++));
      data[*row_pointer++].push_back(value);
    }
  }
  // Fill in the corpus.
  corpus->num_docs = data.size();
  corpus->num_terms = mxGetN(input);
  corpus->docs = (document*)malloc(sizeof(document)*data.size());
  for (int i = 0; i < data.size(); ++i) {
    const vector<pair<int, int> >& row = data[i];
    document* doc = &corpus->docs[i];
    doc->length = row.size();
    doc->total = 0;
    doc->words = (int*)malloc(sizeof(int) * row.size());
    doc->counts = (int*)malloc(sizeof(int) * row.size());
    for (int j = 0; j < row.size(); ++j) {
      doc->words[j] = row[j].first;
      doc->counts[j] = row[j].second;
      doc->total += row[j].second;
    }
  }
  return corpus;
}

// Write corpus data into an mxArray.
mxArray* WriteCorpusToMxArray(const lda_corpus* corpus) {
  CHECK_NOTNULL(corpus);
  // Get columns from corpus.
  int num_elements = 0;
  vector<vector<pair<int, int> > > data(corpus->num_terms);
  for (int i = 0; i < corpus->num_docs; ++i) {
    const document& doc = corpus->docs[i];
    for (int j = 0; j < doc.length; ++j) {
      pair<int, int> value(i, doc.counts[j]);
      data[doc.words[j]].push_back(value);
    }
    num_elements += doc.length;
  }
  // Fill in the mxArray.
  mxArray* output = mxCreateSparse(corpus->num_docs,
                                   corpus->num_terms,
                                   num_elements,
                                   mxREAL);
  CHECK_NOTNULL(output);
  mwIndex* row_pointer = mxGetIr(output);
  mwIndex* column_pointer = mxGetJc(output);
  double* data_pointer = mxGetPr(output);
  column_pointer[0] = 0;
  for (int j = 0; j < mxGetN(output); ++j) {
    const vector<pair<int, int> >& column = data[j];
    column_pointer[j+1] = column_pointer[j] + column.size();
    for (int i = 0; i < column.size(); ++i) {
      *row_pointer++ = column[i].first;
      *data_pointer++ = column[i].second;
    }
  }
  return output;
}

// Read LDA model data from mxArray.
lda_model* ReadModelFromMxArray(const mxArray* array) {
  MxArray input(array);
  lda_model* model = new_lda_model(input.at("num_terms").toInt(),
                                   input.at("num_topics").toInt());
  CHECK_NOTNULL(model);
  model->alpha = input.at("alpha").toDouble();
  const double* data = mxGetPr(input.at("beta").get());
  for (int i = 0; i < model->num_topics; ++i)
    for (int j = 0; j < model->num_terms; ++j)
      model->log_prob_w[i][j] = data[i + model->num_topics * j];
  return model;
}

// Write LDA model data into mxArray.
mxArray* WriteModelToMxArray(const lda_model* model) {
  const char* fields[] = {"num_topics", "num_terms", "alpha", "beta"};
  MxArray output = MxArray::Struct(4, fields);
  output.set("num_topics", model->num_topics);
  output.set("num_terms", model->num_terms);
  output.set("alpha", model->alpha);
  mxArray* beta = mxCreateDoubleMatrix(model->num_topics,
                                       model->num_terms,
                                       mxREAL);
  double* data = mxGetPr(beta);
  for (int i = 0; i < model->num_topics; ++i)
    for (int j = 0; j < model->num_terms; ++j)
      data[i + model->num_topics * j] = model->log_prob_w[i][j];
  output.set("beta", beta);
  return output.getMutable();
}

// Write topic gamma into mxArray.
mxArray* WriteGammaToMxArray(const vector<vector<double> >& var_gamma) {
  int rows = var_gamma.size();
  int columns = (var_gamma.empty()) ? 0 : var_gamma[0].size();
  mxArray* output = mxCreateDoubleMatrix(rows, columns, mxREAL);
  CHECK_NOTNULL(output);
  double* data = mxGetPr(output);
  for (int i = 0; i < rows; ++i)
    for (int j = 0; j < columns; ++j)
      data[j + columns * i] = var_gamma[i][j];
  return output;
}

// Initialize LDA model according to the configuration.
void InitializeModel(const mxArray* model_input,
                     lda_corpus* corpus,
                     lda_model** model,
                     lda_suffstats** ss) {
  CHECK_NOTNULL(corpus);
  CHECK_NOTNULL(model);
  CHECK_NOTNULL(ss);
  const lda_settings* settings = get_settings();
  if (mxIsChar(model_input)) {
    string initialization_method = MxArray(model_input).toString();
    if (get_settings()->VERBOSE)
      mexPrintf("Initializing by '%s'", initialization_method.c_str());
    if (initialization_method == "seeded") {
      *model = new_lda_model(corpus->num_terms, settings->NTOPICS);
      *ss = new_lda_suffstats(*model);
      corpus_initialize_ss(*ss, *model, corpus);
      lda_mle(*model, *ss, 0);
      (*model)->alpha = settings->INITIAL_ALPHA;
    }
    else if (initialization_method == "random") {
      *model = new_lda_model(corpus->num_terms, settings->NTOPICS);
      *ss = new_lda_suffstats(*model);
      random_initialize_ss(*ss, *model);
      lda_mle(*model, *ss, 0);
      (*model)->alpha = settings->INITIAL_ALPHA;
    }
    else
      ERROR("Invalid model initialization: %s", initialization_method.c_str());
  }
  else {
    *model = ReadModelFromMxArray(model_input);
    *ss = new_lda_suffstats(*model);
  }
}

// Estimate topics and parameters of the model.
void RunEM(const mxArray* model_input,
           lda_corpus* corpus,
           mxArray** model_output,
           mxArray** gamma) {
  // Allocate variational parameters.
  lda_settings* settings = get_settings();
  vector<vector<double> > var_gamma(corpus->num_docs,
                                    vector<double>(settings->NTOPICS));
  vector<double*> phi(max_corpus_length(corpus));
  for (int i = 0; i < phi.size(); ++i)
    phi[i] = (double*)malloc(sizeof(double) * settings->NTOPICS);
  // Initialize model.
  lda_model *model = NULL;
  lda_suffstats *ss = NULL;
  InitializeModel(model_input, corpus, &model, &ss);
  // EM main loop.
  int i = 0;
  double likelihood, likelihood_old = 0, converged = 1;
  while (((converged < 0) || (converged > settings->EM_CONVERGED) ||
        (i <= 2)) && (i <= settings->EM_MAX_ITER)) {
    i++;
    if (get_settings()->VERBOSE)
      mexPrintf("**** em iteration %d ****\n", i);
    likelihood = 0;
    zero_initialize_ss(ss, model);
    // E-step.
    for (int d = 0; d < corpus->num_docs; ++d) {
      if ((d % 1000) == 0 && get_settings()->VERBOSE)
        mexPrintf("document %d\n", d);
      likelihood += doc_e_step(&(corpus->docs[d]),
                               &var_gamma[d][0],
                               &phi[0],
                               model,
                               ss);
    }
    // M-step.
    lda_mle(model, ss, settings->ESTIMATE_ALPHA);
    // check for convergence.
    converged = (likelihood_old - likelihood) / (likelihood_old);
    if (converged < 0)
      settings->VAR_MAX_ITER = settings->VAR_MAX_ITER * 2;
    likelihood_old = likelihood;
    if (get_settings()->VERBOSE)
      mexPrintf("likelihood = %10.10f converged = %5.5e\n",
                likelihood,
                converged);
    MEX_FLUSH;
  }
  // Prepare output.
  if (model_output != NULL)
    *model_output = WriteModelToMxArray(model);
  if (gamma != NULL)
    *gamma = WriteGammaToMxArray(var_gamma);
  // Cleanup.
  free_lda_model(model);
  free_lda_suffstats(ss);
  for (int i = 0; i < phi.size(); ++i)
    free(phi[i]);
}

// Run inference with a learned model.
void RunInference(const mxArray* model_input,
                  lda_corpus* corpus,
                  mxArray** gamma,
                  mxArray** likelihood_values) {
  lda_model* model = ReadModelFromMxArray(model_input);
  vector<vector<double> > var_gamma(corpus->num_docs,
                                    vector<double>(model->num_topics));
  vector<double> likelihoods(corpus->num_docs);
  for (int d = 0; d < corpus->num_docs; ++d) {
    if (((d % 1000) == 0) && (d > 0) && get_settings()->VERBOSE)
      mexPrintf("document %d\n", d);
    document* doc = &corpus->docs[d];
    vector<double*> phi(doc->length);
    for (int n = 0; n < doc->length; n++)
      phi[n] = (double*)malloc(sizeof(double) * model->num_topics);
    likelihoods[d] = lda_inference(doc, model, &var_gamma[d][0], &phi[0]);
    for (int n = 0; n < doc->length; n++)
      free(phi[n]);
  }
  if (likelihood_values != NULL) {
    *likelihood_values = mxCreateDoubleMatrix(likelihoods.size(), 1, mxREAL);
    copy(likelihoods.begin(), likelihoods.end(), mxGetPr(*likelihood_values));
  }
  if (gamma != NULL)
    *gamma = WriteGammaToMxArray(var_gamma);
}

// Main entry for corpus = load_corpus(filename).
MEX_FUNCTION(load_corpus) (int nlhs,
                           mxArray* plhs[],
                           int nrhs,
                           const mxArray* prhs[]) {
  CheckInputArguments(1, 1, nrhs);
  CheckOutputArguments(0, 1, nlhs);
  lda_corpus* corpus = read_data(MxArray(prhs[0]).toString().c_str());
  plhs[0] = WriteCorpusToMxArray(corpus);
  free_data(corpus);
}

// Main entry for [model, distribution] = estimate(corpus, model, options).
MEX_FUNCTION(estimate) (int nlhs,
                        mxArray* plhs[],
                        int nrhs,
                        const mxArray* prhs[]) {
  CheckInputArguments(3, 3, nrhs);
  CheckOutputArguments(0, 2, nlhs);
  lda_corpus* corpus = ReadCorpusFromMxArray(prhs[0]);
  ReadSettings(prhs[2]);
  ResetRandomNumber();
  RunEM(prhs[1],
        corpus,
        (nlhs < 1) ? NULL : &plhs[0],
        (nlhs < 2) ? NULL : &plhs[1]);
  free_data(corpus);
}

// Main entry for [likelihoods, distribution] = infer(corpus, model, options).
MEX_FUNCTION(infer) (int nlhs,
                     mxArray* plhs[],
                     int nrhs,
                     const mxArray* prhs[]) {
  CheckInputArguments(3, 3, nrhs);
  CheckOutputArguments(0, 2, nlhs);
  lda_corpus* corpus = ReadCorpusFromMxArray(prhs[0]);
  ReadSettings(prhs[2]);
  ResetRandomNumber();
  RunInference(prhs[1],
               corpus,
               (nlhs < 1) ? NULL : &plhs[0],
               (nlhs < 2) ? NULL : &plhs[1]);
  free_data(corpus);
}

} // namespace<commit_msg>Added logging output<commit_after>// Matlab driver main.
//
// Kota Yamaguchi 2013 <kyamagu@cs.stonybrook.edu>

#include "lda.h"
#include "mex/arguments.h"
#include "mex/function.h"
#include "mex/mxarray.h"
#include "mex.h"
#include <numeric>
#include <stdlib.h>
#include <string>
#include <vector>

using namespace std;

using mex::CheckInputArguments;
using mex::CheckOutputArguments;
using mex::MxArray;

// Alias for the mex error function.
#define ERROR(...) mexErrMsgIdAndTxt("lda:error", __VA_ARGS__)

#define CHECK_NOTNULL(pointer) \
  if (pointer == NULL) ERROR("Null pointer exception.")

#define MEX_FLUSH mexEvalString("drawnow")

namespace {

// Reset random number.
void ResetRandomNumber() {
  seedMT(get_settings()->RANDOM_SEED);
}

// Read settings from a struct.
void ReadSettings(const mxArray* mxarray) {
  MxArray config(mxarray);
  lda_settings* settings = get_settings();
  if (config.isField("var_max_iter"))
    settings->VAR_MAX_ITER = config.at("var_max_iter").toInt();
  if (config.isField("var_converged"))
    settings->VAR_CONVERGED = config.at("var_converged").toDouble();
  if (config.isField("em_max_iter"))
    settings->EM_MAX_ITER = config.at("em_max_iter").toInt();
  if (config.isField("em_convergence"))
    settings->EM_CONVERGED = config.at("em_convergence").toDouble();
  if (config.isField("estimate_alpha"))
    settings->ESTIMATE_ALPHA = config.at("estimate_alpha").toInt();
  if (config.isField("initial_alpha"))
    settings->INITIAL_ALPHA = config.at("initial_alpha").toDouble();
  if (config.isField("num_topics"))
    settings->NTOPICS = config.at("num_topics").toInt();
  if (config.isField("random_seed"))
    settings->RANDOM_SEED = config.at("random_seed").toInt();
  if (config.isField("verbose"))
    settings->VERBOSE = config.at("verbose").toInt();
}

// Read data into corpus. Call free_data() after use.
lda_corpus* ReadCorpusFromMxArray(const mxArray* input) {
  if (!mxIsSparse(input) || !mxIsDouble(input))
    ERROR("Input data must be a sparse double array.");
  lda_corpus* corpus = (lda_corpus*)malloc(sizeof(corpus));
  CHECK_NOTNULL(corpus);
  // Get values from mxArray.
  vector<vector<pair<int, int> > > data(mxGetM(input));
  mwIndex* row_pointer = mxGetIr(input);
  mwIndex* column_pointer = mxGetJc(input);
  double* data_pointer = mxGetPr(input);
  for (int j = 0; j < mxGetN(input); ++j) {
    int column_elements = column_pointer[j+1] - column_pointer[j];
    for (int i = 0; i < column_elements; ++i) {
      pair<int, int> value(j, static_cast<int>(*data_pointer++));
      data[*row_pointer++].push_back(value);
    }
  }
  // Fill in the corpus.
  corpus->num_docs = data.size();
  corpus->num_terms = mxGetN(input);
  corpus->docs = (document*)malloc(sizeof(document)*data.size());
  for (int i = 0; i < data.size(); ++i) {
    const vector<pair<int, int> >& row = data[i];
    document* doc = &corpus->docs[i];
    doc->length = row.size();
    doc->total = 0;
    doc->words = (int*)malloc(sizeof(int) * row.size());
    doc->counts = (int*)malloc(sizeof(int) * row.size());
    for (int j = 0; j < row.size(); ++j) {
      doc->words[j] = row[j].first;
      doc->counts[j] = row[j].second;
      doc->total += row[j].second;
    }
  }
  return corpus;
}

// Write corpus data into an mxArray.
mxArray* WriteCorpusToMxArray(const lda_corpus* corpus) {
  CHECK_NOTNULL(corpus);
  // Get columns from corpus.
  int num_elements = 0;
  vector<vector<pair<int, int> > > data(corpus->num_terms);
  for (int i = 0; i < corpus->num_docs; ++i) {
    const document& doc = corpus->docs[i];
    for (int j = 0; j < doc.length; ++j) {
      pair<int, int> value(i, doc.counts[j]);
      data[doc.words[j]].push_back(value);
    }
    num_elements += doc.length;
  }
  // Fill in the mxArray.
  mxArray* output = mxCreateSparse(corpus->num_docs,
                                   corpus->num_terms,
                                   num_elements,
                                   mxREAL);
  CHECK_NOTNULL(output);
  mwIndex* row_pointer = mxGetIr(output);
  mwIndex* column_pointer = mxGetJc(output);
  double* data_pointer = mxGetPr(output);
  column_pointer[0] = 0;
  for (int j = 0; j < mxGetN(output); ++j) {
    const vector<pair<int, int> >& column = data[j];
    column_pointer[j+1] = column_pointer[j] + column.size();
    for (int i = 0; i < column.size(); ++i) {
      *row_pointer++ = column[i].first;
      *data_pointer++ = column[i].second;
    }
  }
  return output;
}

// Read LDA model data from mxArray.
lda_model* ReadModelFromMxArray(const mxArray* array) {
  MxArray input(array);
  lda_model* model = new_lda_model(input.at("num_terms").toInt(),
                                   input.at("num_topics").toInt());
  CHECK_NOTNULL(model);
  model->alpha = input.at("alpha").toDouble();
  const double* data = mxGetPr(input.at("beta").get());
  for (int i = 0; i < model->num_topics; ++i)
    for (int j = 0; j < model->num_terms; ++j)
      model->log_prob_w[i][j] = data[i + model->num_topics * j];
  return model;
}

// Write LDA model data into mxArray.
mxArray* WriteModelToMxArray(const lda_model* model) {
  const char* fields[] = {"num_topics", "num_terms", "alpha", "beta"};
  MxArray output = MxArray::Struct(4, fields);
  output.set("num_topics", model->num_topics);
  output.set("num_terms", model->num_terms);
  output.set("alpha", model->alpha);
  mxArray* beta = mxCreateDoubleMatrix(model->num_topics,
                                       model->num_terms,
                                       mxREAL);
  double* data = mxGetPr(beta);
  for (int i = 0; i < model->num_topics; ++i)
    for (int j = 0; j < model->num_terms; ++j)
      data[i + model->num_topics * j] = model->log_prob_w[i][j];
  output.set("beta", beta);
  return output.getMutable();
}

// Write topic gamma into mxArray.
mxArray* WriteGammaToMxArray(const vector<vector<double> >& var_gamma) {
  int rows = var_gamma.size();
  int columns = (var_gamma.empty()) ? 0 : var_gamma[0].size();
  mxArray* output = mxCreateDoubleMatrix(rows, columns, mxREAL);
  CHECK_NOTNULL(output);
  double* data = mxGetPr(output);
  for (int i = 0; i < rows; ++i)
    for (int j = 0; j < columns; ++j)
      data[j + columns * i] = var_gamma[i][j];
  return output;
}

// Initialize LDA model according to the configuration.
void InitializeModel(const mxArray* model_input,
                     lda_corpus* corpus,
                     lda_model** model,
                     lda_suffstats** ss) {
  CHECK_NOTNULL(corpus);
  CHECK_NOTNULL(model);
  CHECK_NOTNULL(ss);
  const lda_settings* settings = get_settings();
  if (mxIsChar(model_input)) {
    string initialization_method = MxArray(model_input).toString();
    if (get_settings()->VERBOSE)
      mexPrintf("%s initialization\n", initialization_method.c_str());
    if (initialization_method == "seeded") {
      *model = new_lda_model(corpus->num_terms, settings->NTOPICS);
      *ss = new_lda_suffstats(*model);
      corpus_initialize_ss(*ss, *model, corpus);
      lda_mle(*model, *ss, 0);
      (*model)->alpha = settings->INITIAL_ALPHA;
    }
    else if (initialization_method == "random") {
      *model = new_lda_model(corpus->num_terms, settings->NTOPICS);
      *ss = new_lda_suffstats(*model);
      random_initialize_ss(*ss, *model);
      lda_mle(*model, *ss, 0);
      (*model)->alpha = settings->INITIAL_ALPHA;
    }
    else
      ERROR("Invalid model initialization: %s", initialization_method.c_str());
  }
  else {
    *model = ReadModelFromMxArray(model_input);
    *ss = new_lda_suffstats(*model);
  }
}

// Estimate topics and parameters of the model.
void RunEM(const mxArray* model_input,
           lda_corpus* corpus,
           mxArray** model_output,
           mxArray** gamma) {
  // Allocate variational parameters.
  lda_settings* settings = get_settings();
  vector<vector<double> > var_gamma(corpus->num_docs,
                                    vector<double>(settings->NTOPICS));
  vector<double*> phi(max_corpus_length(corpus));
  for (int i = 0; i < phi.size(); ++i)
    phi[i] = (double*)malloc(sizeof(double) * settings->NTOPICS);
  // Initialize model.
  lda_model *model = NULL;
  lda_suffstats *ss = NULL;
  InitializeModel(model_input, corpus, &model, &ss);
  // EM main loop.
  int i = 0;
  double likelihood, likelihood_old = 0, converged = 1;
  while (((converged < 0) || (converged > settings->EM_CONVERGED) ||
        (i <= 2)) && (i <= settings->EM_MAX_ITER)) {
    i++;
    if (get_settings()->VERBOSE)
      mexPrintf("**** em iteration %d ****\n", i);
    likelihood = 0;
    zero_initialize_ss(ss, model);
    // E-step.
    for (int d = 0; d < corpus->num_docs; ++d) {
      if ((d % 1000) == 0 && get_settings()->VERBOSE)
        mexPrintf("document %d\n", d);
      likelihood += doc_e_step(&(corpus->docs[d]),
                               &var_gamma[d][0],
                               &phi[0],
                               model,
                               ss);
    }
    // M-step.
    lda_mle(model, ss, settings->ESTIMATE_ALPHA);
    // check for convergence.
    converged = (likelihood_old - likelihood) / (likelihood_old);
    if (converged < 0)
      settings->VAR_MAX_ITER = settings->VAR_MAX_ITER * 2;
    likelihood_old = likelihood;
    if (get_settings()->VERBOSE)
      mexPrintf("likelihood = %10.10f converged = %5.5e\n",
                likelihood,
                converged);
    MEX_FLUSH;
  }
  // Prepare output.
  if (model_output != NULL)
    *model_output = WriteModelToMxArray(model);
  if (gamma != NULL)
    *gamma = WriteGammaToMxArray(var_gamma);
  // Cleanup.
  free_lda_model(model);
  free_lda_suffstats(ss);
  for (int i = 0; i < phi.size(); ++i)
    free(phi[i]);
}

// Run inference with a learned model.
void RunInference(const mxArray* model_input,
                  lda_corpus* corpus,
                  mxArray** gamma,
                  mxArray** likelihood_values) {
  lda_model* model = ReadModelFromMxArray(model_input);
  vector<vector<double> > var_gamma(corpus->num_docs,
                                    vector<double>(model->num_topics));
  vector<double> likelihoods(corpus->num_docs);
  for (int d = 0; d < corpus->num_docs; ++d) {
    if (((d % 1000) == 0) && (d > 0) && get_settings()->VERBOSE)
      mexPrintf("document %d\n", d);
    document* doc = &corpus->docs[d];
    vector<double*> phi(doc->length);
    for (int n = 0; n < doc->length; n++)
      phi[n] = (double*)malloc(sizeof(double) * model->num_topics);
    likelihoods[d] = lda_inference(doc, model, &var_gamma[d][0], &phi[0]);
    for (int n = 0; n < doc->length; n++)
      free(phi[n]);
  }
  if (likelihood_values != NULL) {
    *likelihood_values = mxCreateDoubleMatrix(likelihoods.size(), 1, mxREAL);
    copy(likelihoods.begin(), likelihoods.end(), mxGetPr(*likelihood_values));
  }
  if (gamma != NULL)
    *gamma = WriteGammaToMxArray(var_gamma);
}

// Main entry for corpus = load_corpus(filename).
MEX_FUNCTION(load_corpus) (int nlhs,
                           mxArray* plhs[],
                           int nrhs,
                           const mxArray* prhs[]) {
  CheckInputArguments(1, 1, nrhs);
  CheckOutputArguments(0, 1, nlhs);
  lda_corpus* corpus = read_data(MxArray(prhs[0]).toString().c_str());
  plhs[0] = WriteCorpusToMxArray(corpus);
  free_data(corpus);
}

// Main entry for [model, distribution] = estimate(corpus, model, options).
MEX_FUNCTION(estimate) (int nlhs,
                        mxArray* plhs[],
                        int nrhs,
                        const mxArray* prhs[]) {
  CheckInputArguments(3, 3, nrhs);
  CheckOutputArguments(0, 2, nlhs);
  lda_corpus* corpus = ReadCorpusFromMxArray(prhs[0]);
  ReadSettings(prhs[2]);
  ResetRandomNumber();
  RunEM(prhs[1],
        corpus,
        (nlhs < 1) ? NULL : &plhs[0],
        (nlhs < 2) ? NULL : &plhs[1]);
  free_data(corpus);
}

// Main entry for [likelihoods, distribution] = infer(corpus, model, options).
MEX_FUNCTION(infer) (int nlhs,
                     mxArray* plhs[],
                     int nrhs,
                     const mxArray* prhs[]) {
  CheckInputArguments(3, 3, nrhs);
  CheckOutputArguments(0, 2, nlhs);
  lda_corpus* corpus = ReadCorpusFromMxArray(prhs[0]);
  ReadSettings(prhs[2]);
  ResetRandomNumber();
  RunInference(prhs[1],
               corpus,
               (nlhs < 1) ? NULL : &plhs[0],
               (nlhs < 2) ? NULL : &plhs[1]);
  free_data(corpus);
}

} // namespace
<|endoftext|>


<commit_before>#include "../include/cxx.h"
#include <cassert>
#include <cstring>
#include <exception>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <vector>

extern "C" {
const char *cxxbridge05$cxx_string$data(const std::string &s) noexcept {
  return s.data();
}

size_t cxxbridge05$cxx_string$length(const std::string &s) noexcept {
  return s.length();
}

// rust::String
void cxxbridge05$string$new(rust::String *self) noexcept;
void cxxbridge05$string$clone(rust::String *self,
                              const rust::String &other) noexcept;
bool cxxbridge05$string$from(rust::String *self, const char *ptr,
                             size_t len) noexcept;
void cxxbridge05$string$drop(rust::String *self) noexcept;
const char *cxxbridge05$string$ptr(const rust::String *self) noexcept;
size_t cxxbridge05$string$len(const rust::String *self) noexcept;

// rust::Str
bool cxxbridge05$str$valid(const char *ptr, size_t len) noexcept;
} // extern "C"

namespace rust {
inline namespace cxxbridge05 {

template <typename Exception>
void panic [[noreturn]] (const char *msg) {
#if defined(RUST_CXX_NO_EXCEPTIONS)
  std::cerr << "Error: " << msg << ". Aborting." << std::endl;
  std::terminate();
#else
  throw Exception(msg);
#endif
}

template void panic<std::out_of_range>[[noreturn]] (const char *msg);

String::String() noexcept { cxxbridge05$string$new(this); }

String::String(const String &other) noexcept {
  cxxbridge05$string$clone(this, other);
}

String::String(String &&other) noexcept {
  this->repr = other.repr;
  cxxbridge05$string$new(&other);
}

String::~String() noexcept { cxxbridge05$string$drop(this); }

static void initString(String *self, const char *s, size_t len) {
  if (!cxxbridge05$string$from(self, s, len)) {
    panic<std::invalid_argument>("data for rust::String is not utf-8");
  }
}

String::String(const std::string &s) { initString(this, s.data(), s.length()); }

String::String(const char *s) {
  assert(s != nullptr);
  initString(this, s, std::strlen(s));
}

String::String(const char *s, size_t len) {
  assert(s != nullptr || len == 0);
  initString(this,
             s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
             len);
}

String &String::operator=(const String &other) noexcept {
  if (this != &other) {
    cxxbridge05$string$drop(this);
    cxxbridge05$string$clone(this, other);
  }
  return *this;
}

String &String::operator=(String &&other) noexcept {
  if (this != &other) {
    cxxbridge05$string$drop(this);
    this->repr = other.repr;
    cxxbridge05$string$new(&other);
  }
  return *this;
}

String::operator std::string() const {
  return std::string(this->data(), this->size());
}

const char *String::data() const noexcept {
  return cxxbridge05$string$ptr(this);
}

size_t String::size() const noexcept { return cxxbridge05$string$len(this); }

size_t String::length() const noexcept { return cxxbridge05$string$len(this); }

String::String(unsafe_bitcopy_t, const String &bits) noexcept
    : repr(bits.repr) {}

std::ostream &operator<<(std::ostream &os, const String &s) {
  os.write(s.data(), s.size());
  return os;
}

Str::Str() noexcept : repr(Repr{reinterpret_cast<const char *>(1), 0}) {}

static void initStr(Str::Repr repr) {
  if (!cxxbridge05$str$valid(repr.ptr, repr.len)) {
    panic<std::invalid_argument>("data for rust::Str is not utf-8");
  }
}

Str::Str(const std::string &s) : repr(Repr{s.data(), s.length()}) {
  initStr(this->repr);
}

Str::Str(const char *s) : repr(Repr{s, std::strlen(s)}) {
  assert(s != nullptr);
  initStr(this->repr);
}

Str::Str(const char *s, size_t len)
    : repr(
          Repr{s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
               len}) {
  assert(s != nullptr || len == 0);
  initStr(this->repr);
}

Str &Str::operator=(Str other) noexcept {
  this->repr = other.repr;
  return *this;
}

Str::operator std::string() const {
  return std::string(this->data(), this->size());
}

const char *Str::data() const noexcept { return this->repr.ptr; }

size_t Str::size() const noexcept { return this->repr.len; }

size_t Str::length() const noexcept { return this->repr.len; }

Str::Str(Repr repr_) noexcept : repr(repr_) {}

Str::operator Repr() const noexcept { return this->repr; }

std::ostream &operator<<(std::ostream &os, const Str &s) {
  os.write(s.data(), s.size());
  return os;
}

extern "C" {
const char *cxxbridge05$error(const char *ptr, size_t len) {
  char *copy = new char[len];
  std::strncpy(copy, ptr, len);
  return copy;
}
} // extern "C"

Error::Error(const Error &other)
    : msg(cxxbridge05$error(other.msg, other.len)), len(other.len) {}

Error::Error(Error &&other) noexcept : msg(other.msg), len(other.len) {
  other.msg = nullptr;
  other.len = 0;
}

Error::~Error() noexcept { delete[] this->msg; }

const char *Error::what() const noexcept { return this->msg; }

} // namespace cxxbridge05
} // namespace rust

extern "C" {
void cxxbridge05$unique_ptr$std$string$null(
    std::unique_ptr<std::string> *ptr) noexcept {
  new (ptr) std::unique_ptr<std::string>();
}
void cxxbridge05$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
                                           std::string *raw) noexcept {
  new (ptr) std::unique_ptr<std::string>(raw);
}
const std::string *cxxbridge05$unique_ptr$std$string$get(
    const std::unique_ptr<std::string> &ptr) noexcept {
  return ptr.get();
}
std::string *cxxbridge05$unique_ptr$std$string$release(
    std::unique_ptr<std::string> &ptr) noexcept {
  return ptr.release();
}
void cxxbridge05$unique_ptr$std$string$drop(
    std::unique_ptr<std::string> *ptr) noexcept {
  ptr->~unique_ptr();
}
} // extern "C"

#define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE)                                    \
  size_t cxxbridge05$std$vector$##RUST_TYPE##$size(                            \
      const std::vector<CXX_TYPE> &s) noexcept {                               \
    return s.size();                                                           \
  }                                                                            \
  const CXX_TYPE *cxxbridge05$std$vector$##RUST_TYPE##$get_unchecked(          \
      const std::vector<CXX_TYPE> &s, size_t pos) noexcept {                   \
    return &s[pos];                                                            \
  }                                                                            \
  void cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$null(                   \
      std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>();                        \
  }                                                                            \
  void cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$raw(                    \
      std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \
      std::vector<CXX_TYPE> *raw) noexcept {                                   \
    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw);                     \
  }                                                                            \
  const std::vector<CXX_TYPE>                                                  \
      *cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$get(                    \
          const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {        \
    return ptr.get();                                                          \
  }                                                                            \
  std::vector<CXX_TYPE>                                                        \
      *cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$release(                \
          std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {              \
    return ptr.release();                                                      \
  }                                                                            \
  void cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$drop(                   \
      std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
    ptr->~unique_ptr();                                                        \
  }

#define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \
  void cxxbridge05$rust_vec$##RUST_TYPE##$new(                                 \
      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
  void cxxbridge05$rust_vec$##RUST_TYPE##$drop(                                \
      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
  size_t cxxbridge05$rust_vec$##RUST_TYPE##$len(                               \
      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
  const CXX_TYPE *cxxbridge05$rust_vec$##RUST_TYPE##$data(                     \
      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
  size_t cxxbridge05$rust_vec$##RUST_TYPE##$stride() noexcept;

#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \
  template <>                                                                  \
  Vec<CXX_TYPE>::Vec() noexcept {                                              \
    cxxbridge05$rust_vec$##RUST_TYPE##$new(this);                              \
  }                                                                            \
  template <>                                                                  \
  void Vec<CXX_TYPE>::drop() noexcept {                                        \
    return cxxbridge05$rust_vec$##RUST_TYPE##$drop(this);                      \
  }                                                                            \
  template <>                                                                  \
  size_t Vec<CXX_TYPE>::size() const noexcept {                                \
    return cxxbridge05$rust_vec$##RUST_TYPE##$len(this);                       \
  }                                                                            \
  template <>                                                                  \
  const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept {                       \
    return cxxbridge05$rust_vec$##RUST_TYPE##$data(this);                      \
  }                                                                            \
  template <>                                                                  \
  size_t Vec<CXX_TYPE>::stride() noexcept {                                    \
    return cxxbridge05$rust_vec$##RUST_TYPE##$stride();                        \
  }

// Usize and isize are the same type as one of the below.
#define FOR_EACH_NUMERIC(MACRO)                                                \
  MACRO(u8, uint8_t)                                                           \
  MACRO(u16, uint16_t)                                                         \
  MACRO(u32, uint32_t)                                                         \
  MACRO(u64, uint64_t)                                                         \
  MACRO(i8, int8_t)                                                            \
  MACRO(i16, int16_t)                                                          \
  MACRO(i32, int32_t)                                                          \
  MACRO(i64, int64_t)                                                          \
  MACRO(f32, float)                                                            \
  MACRO(f64, double)

#define FOR_EACH_STD_VECTOR(MACRO)                                             \
  FOR_EACH_NUMERIC(MACRO)                                                      \
  MACRO(usize, size_t)                                                         \
  MACRO(isize, rust::isize)                                                    \
  MACRO(string, std::string)

#define FOR_EACH_RUST_VEC(MACRO)                                               \
  FOR_EACH_NUMERIC(MACRO)                                                      \
  MACRO(bool, bool)                                                            \
  MACRO(string, rust::String)

extern "C" {
FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
} // extern "C"

namespace rust {
inline namespace cxxbridge05 {
FOR_EACH_RUST_VEC(RUST_VEC_OPS)
} // namespace cxxbridge05
} // namespace rust
<commit_msg>Fill in Error base class constructor calls<commit_after>#include "../include/cxx.h"
#include <cassert>
#include <cstring>
#include <exception>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <vector>

extern "C" {
const char *cxxbridge05$cxx_string$data(const std::string &s) noexcept {
  return s.data();
}

size_t cxxbridge05$cxx_string$length(const std::string &s) noexcept {
  return s.length();
}

// rust::String
void cxxbridge05$string$new(rust::String *self) noexcept;
void cxxbridge05$string$clone(rust::String *self,
                              const rust::String &other) noexcept;
bool cxxbridge05$string$from(rust::String *self, const char *ptr,
                             size_t len) noexcept;
void cxxbridge05$string$drop(rust::String *self) noexcept;
const char *cxxbridge05$string$ptr(const rust::String *self) noexcept;
size_t cxxbridge05$string$len(const rust::String *self) noexcept;

// rust::Str
bool cxxbridge05$str$valid(const char *ptr, size_t len) noexcept;
} // extern "C"

namespace rust {
inline namespace cxxbridge05 {

template <typename Exception>
void panic [[noreturn]] (const char *msg) {
#if defined(RUST_CXX_NO_EXCEPTIONS)
  std::cerr << "Error: " << msg << ". Aborting." << std::endl;
  std::terminate();
#else
  throw Exception(msg);
#endif
}

template void panic<std::out_of_range>[[noreturn]] (const char *msg);

String::String() noexcept { cxxbridge05$string$new(this); }

String::String(const String &other) noexcept {
  cxxbridge05$string$clone(this, other);
}

String::String(String &&other) noexcept {
  this->repr = other.repr;
  cxxbridge05$string$new(&other);
}

String::~String() noexcept { cxxbridge05$string$drop(this); }

static void initString(String *self, const char *s, size_t len) {
  if (!cxxbridge05$string$from(self, s, len)) {
    panic<std::invalid_argument>("data for rust::String is not utf-8");
  }
}

String::String(const std::string &s) { initString(this, s.data(), s.length()); }

String::String(const char *s) {
  assert(s != nullptr);
  initString(this, s, std::strlen(s));
}

String::String(const char *s, size_t len) {
  assert(s != nullptr || len == 0);
  initString(this,
             s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
             len);
}

String &String::operator=(const String &other) noexcept {
  if (this != &other) {
    cxxbridge05$string$drop(this);
    cxxbridge05$string$clone(this, other);
  }
  return *this;
}

String &String::operator=(String &&other) noexcept {
  if (this != &other) {
    cxxbridge05$string$drop(this);
    this->repr = other.repr;
    cxxbridge05$string$new(&other);
  }
  return *this;
}

String::operator std::string() const {
  return std::string(this->data(), this->size());
}

const char *String::data() const noexcept {
  return cxxbridge05$string$ptr(this);
}

size_t String::size() const noexcept { return cxxbridge05$string$len(this); }

size_t String::length() const noexcept { return cxxbridge05$string$len(this); }

String::String(unsafe_bitcopy_t, const String &bits) noexcept
    : repr(bits.repr) {}

std::ostream &operator<<(std::ostream &os, const String &s) {
  os.write(s.data(), s.size());
  return os;
}

Str::Str() noexcept : repr(Repr{reinterpret_cast<const char *>(1), 0}) {}

static void initStr(Str::Repr repr) {
  if (!cxxbridge05$str$valid(repr.ptr, repr.len)) {
    panic<std::invalid_argument>("data for rust::Str is not utf-8");
  }
}

Str::Str(const std::string &s) : repr(Repr{s.data(), s.length()}) {
  initStr(this->repr);
}

Str::Str(const char *s) : repr(Repr{s, std::strlen(s)}) {
  assert(s != nullptr);
  initStr(this->repr);
}

Str::Str(const char *s, size_t len)
    : repr(
          Repr{s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
               len}) {
  assert(s != nullptr || len == 0);
  initStr(this->repr);
}

Str &Str::operator=(Str other) noexcept {
  this->repr = other.repr;
  return *this;
}

Str::operator std::string() const {
  return std::string(this->data(), this->size());
}

const char *Str::data() const noexcept { return this->repr.ptr; }

size_t Str::size() const noexcept { return this->repr.len; }

size_t Str::length() const noexcept { return this->repr.len; }

Str::Str(Repr repr_) noexcept : repr(repr_) {}

Str::operator Repr() const noexcept { return this->repr; }

std::ostream &operator<<(std::ostream &os, const Str &s) {
  os.write(s.data(), s.size());
  return os;
}

extern "C" {
const char *cxxbridge05$error(const char *ptr, size_t len) {
  char *copy = new char[len];
  std::strncpy(copy, ptr, len);
  return copy;
}
} // extern "C"

Error::Error(const Error &other)
    : std::exception(other), msg(cxxbridge05$error(other.msg, other.len)),
      len(other.len) {}

Error::Error(Error &&other) noexcept
    : std::exception(std::move(other)), msg(other.msg), len(other.len) {
  other.msg = nullptr;
  other.len = 0;
}

Error::~Error() noexcept { delete[] this->msg; }

const char *Error::what() const noexcept { return this->msg; }

} // namespace cxxbridge05
} // namespace rust

extern "C" {
void cxxbridge05$unique_ptr$std$string$null(
    std::unique_ptr<std::string> *ptr) noexcept {
  new (ptr) std::unique_ptr<std::string>();
}
void cxxbridge05$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
                                           std::string *raw) noexcept {
  new (ptr) std::unique_ptr<std::string>(raw);
}
const std::string *cxxbridge05$unique_ptr$std$string$get(
    const std::unique_ptr<std::string> &ptr) noexcept {
  return ptr.get();
}
std::string *cxxbridge05$unique_ptr$std$string$release(
    std::unique_ptr<std::string> &ptr) noexcept {
  return ptr.release();
}
void cxxbridge05$unique_ptr$std$string$drop(
    std::unique_ptr<std::string> *ptr) noexcept {
  ptr->~unique_ptr();
}
} // extern "C"

#define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE)                                    \
  size_t cxxbridge05$std$vector$##RUST_TYPE##$size(                            \
      const std::vector<CXX_TYPE> &s) noexcept {                               \
    return s.size();                                                           \
  }                                                                            \
  const CXX_TYPE *cxxbridge05$std$vector$##RUST_TYPE##$get_unchecked(          \
      const std::vector<CXX_TYPE> &s, size_t pos) noexcept {                   \
    return &s[pos];                                                            \
  }                                                                            \
  void cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$null(                   \
      std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>();                        \
  }                                                                            \
  void cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$raw(                    \
      std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \
      std::vector<CXX_TYPE> *raw) noexcept {                                   \
    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw);                     \
  }                                                                            \
  const std::vector<CXX_TYPE>                                                  \
      *cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$get(                    \
          const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {        \
    return ptr.get();                                                          \
  }                                                                            \
  std::vector<CXX_TYPE>                                                        \
      *cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$release(                \
          std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {              \
    return ptr.release();                                                      \
  }                                                                            \
  void cxxbridge05$unique_ptr$std$vector$##RUST_TYPE##$drop(                   \
      std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
    ptr->~unique_ptr();                                                        \
  }

#define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \
  void cxxbridge05$rust_vec$##RUST_TYPE##$new(                                 \
      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
  void cxxbridge05$rust_vec$##RUST_TYPE##$drop(                                \
      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
  size_t cxxbridge05$rust_vec$##RUST_TYPE##$len(                               \
      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
  const CXX_TYPE *cxxbridge05$rust_vec$##RUST_TYPE##$data(                     \
      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
  size_t cxxbridge05$rust_vec$##RUST_TYPE##$stride() noexcept;

#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \
  template <>                                                                  \
  Vec<CXX_TYPE>::Vec() noexcept {                                              \
    cxxbridge05$rust_vec$##RUST_TYPE##$new(this);                              \
  }                                                                            \
  template <>                                                                  \
  void Vec<CXX_TYPE>::drop() noexcept {                                        \
    return cxxbridge05$rust_vec$##RUST_TYPE##$drop(this);                      \
  }                                                                            \
  template <>                                                                  \
  size_t Vec<CXX_TYPE>::size() const noexcept {                                \
    return cxxbridge05$rust_vec$##RUST_TYPE##$len(this);                       \
  }                                                                            \
  template <>                                                                  \
  const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept {                       \
    return cxxbridge05$rust_vec$##RUST_TYPE##$data(this);                      \
  }                                                                            \
  template <>                                                                  \
  size_t Vec<CXX_TYPE>::stride() noexcept {                                    \
    return cxxbridge05$rust_vec$##RUST_TYPE##$stride();                        \
  }

// Usize and isize are the same type as one of the below.
#define FOR_EACH_NUMERIC(MACRO)                                                \
  MACRO(u8, uint8_t)                                                           \
  MACRO(u16, uint16_t)                                                         \
  MACRO(u32, uint32_t)                                                         \
  MACRO(u64, uint64_t)                                                         \
  MACRO(i8, int8_t)                                                            \
  MACRO(i16, int16_t)                                                          \
  MACRO(i32, int32_t)                                                          \
  MACRO(i64, int64_t)                                                          \
  MACRO(f32, float)                                                            \
  MACRO(f64, double)

#define FOR_EACH_STD_VECTOR(MACRO)                                             \
  FOR_EACH_NUMERIC(MACRO)                                                      \
  MACRO(usize, size_t)                                                         \
  MACRO(isize, rust::isize)                                                    \
  MACRO(string, std::string)

#define FOR_EACH_RUST_VEC(MACRO)                                               \
  FOR_EACH_NUMERIC(MACRO)                                                      \
  MACRO(bool, bool)                                                            \
  MACRO(string, rust::String)

extern "C" {
FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
} // extern "C"

namespace rust {
inline namespace cxxbridge05 {
FOR_EACH_RUST_VEC(RUST_VEC_OPS)
} // namespace cxxbridge05
} // namespace rust
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	カラー管理クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  カラー構造
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct color {

		// http://www.rapidtables.com/web/color/RGB_Color.htm
		//　@brief  カラー属性
		enum class type : uint8_t {
			black,			///< 黒
			white,			///< 白
			red,			///< 赤
			lime,			///< ライム
			blue,			///< ブルー
			yellow,			///< イエロー
			cyan,			///< シアン
			aqua = cyan,	///< アクア（シアン）
			magenta,		///< マジェンタ
			fuchsia = magenta,
			silver,			///< シルバー
			gray,			///< グレー（５０％）
			maroon,			///< マルーン
			olive,			///< オリーブ
			green,			///< グリーン
			purple,			///< パープル
			teal,			///< teal
			navy,			///< ネービー
		};

		uint8_t	r;  ///< Red
		uint8_t	g;  ///< Green
		uint8_t	b;  ///< Blue
		uint8_t a;  ///< Alpha

		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	r	赤
			@param[in]	g	緑
			@param[in]	b	青
			@param[in]	a	透明度（０で最大の透明度）
		*/
		//-----------------------------------------------------------------//
		color(uint8_t rr = 0, uint8_t gg = 0, uint8_t bb = 0, uint8_t aa = 255) :
			r(rr), g(gg), b(bb), a(aa) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	t	カラー属性
			@param[in]	a	透明度（０で最大の透明度）
		*/
		//-----------------------------------------------------------------//
		color(type t, uint8_t aa) { set(t, aa); }

		//-----------------------------------------------------------------//
		/*!
			@brief  カラー属性での設定
			@param[in]	t	カラー属性
			@param[in]	a	透明度（０で最大の透明度）
		*/
		//-----------------------------------------------------------------//
		void set(type t, uint8_t aa = 255)
		{
			switch(t) {
			case type::black:   r = 0x00; g = 0x00; b = 0x00; break;
			case type::white:   r = 0xFF; g = 0xFF; b = 0xFF; break;
			case type::red:     r = 0xFF; g = 0x00; b = 0x00; break;
			case type::lime:    r = 0x00; g = 0xFF; b = 0x00; break;
			case type::blue:    r = 0x00; g = 0x00; b = 0xFF; break;
			case type::yellow:  r = 0xFF; g = 0xFF; b = 0x00; break;
			case type::cyan:    r = 0x00; g = 0xFF; b = 0xFF; break;
			case type::magenta: r = 0xFF; g = 0x00; b = 0xFF; break;
			case type::silver: 	r = 0xC0; g = 0xC0; b = 0xC0; break;
			case type::gray: 	r = 0x80; g = 0x80; b = 0x80; break;
			case type::maroon: 	r = 0x80; g = 0x00; b = 0x00; break;
			case type::olive: 	r = 0x80; g = 0x80; b = 0x00; break;
			case type::green: 	r = 0x00; g = 0x80; b = 0x00; break;
			case type::purple: 	r = 0x80; g = 0x00; b = 0x80; break;
			case type::teal: 	r = 0x00; g = 0x80; b = 0x80; break;
			case type::navy: 	r = 0x00; g = 0x00; b = 0x80; break;
			}
			a = aa;
		}
	};
}
<commit_msg>remove: move a file<commit_after><|endoftext|>


<commit_before>#ifndef HGUARD_OGRE_SPHERICAL_HPP__
#define HGUARD_OGRE_SPHERICAL_HPP__

#include <OgreMath.h>
#include <OgreVector3.h>
#include <OgreQuaternion.h>

namespace Ogre {

	/** Spherical coordinates vector, used for spherical coordinates and transformations.
		Some example values:
			( radius = 1.0, theta = 0.0deg  , phi = 0.0deg  ) <=> Y unit vector in cartesian space
			( radius = 1.0, theta = 90.0deg , phi = 0.0deg  ) <=> Z unit vector in cartesian space
			( radius = 1.0, theta = 90.0deg , phi = 90.0deg ) <=> X unit vector in cartesian space
	*/
	struct SphereVector
	{
		Real   radius; ///< Rho or Radius is the distance from the center of the sphere.
		Radian theta;  ///< Theta is the angle around the x axis (latitude angle counterclockwise), values range from 0 to PI.
		Radian phi;    ///< Phi is the angle around the y axis (longitude angle counterclockwise), values range from 0 to 2PI.

		// NOTE: if you need to expose these constants through a shared library api, add the export/import macro before each of
		// the following lines.
		static const SphereVector ZERO;
		static const SphereVector UNIT_X;
		static const SphereVector UNIT_Y;
		static const SphereVector UNIT_Z;
		static const SphereVector NEGATIVE_UNIT_X;
		static const SphereVector NEGATIVE_UNIT_Y;
		static const SphereVector NEGATIVE_UNIT_Z;

		/// Default Constructor: no initialization of the values is performed.
		SphereVector() {}

		SphereVector( Real radius, Radian theta, Radian phi )
			: radius( std::move(radius) ), theta( std::move(theta) ), phi( std::move(phi) )
		{}

		/** Construction from a cartesian vector: the spherical vector will have the same relative position
			but in spherical coordinates.
			@see from_cartesian()
		*/
		explicit SphereVector( const Vector3& cartesian_vec )
		{
			*this = from_cartesian( cartesian_vec );
		}

		/** @return a relative Cartesian vector coordinate from this relative spherical coordinate. */
		Vector3 to_cartesian() const
		{
			Vector3 result;
			result.x = radius * Math::Cos( phi ) * Math::Sin( theta );
			result.z = radius * Math::Sin( phi ) * Math::Sin( theta );
			result.y = radius * Math::Cos( theta );
			return result;
		}

		/** @return a relative spherical coordinate from a cartesian vector. */
		/** @return a relative spherical coordinate from a cartesian vector. */
		static SphereVector from_cartesian( const Ogre::Vector3& cartesian )
		{
			using namespace Ogre;
			SphereVector result;
			result.radius = cartesian.length();
			result.phi    = cartesian.x   > Real(0) || cartesian.x   < Real(0) ? Math::ATan( cartesian.z / cartesian.x )   : Math::ATan( 0 );
			result.theta  = result.radius > Real(0) || result.radius < Real(0) ? Math::ACos( cartesian.y / result.radius ) : Math::ACos( 0 );
			return result;
		}

		/** @return a relative rotation from the provided axis to the axis corresponding to this relative spherical vector. */
		Quaternion rotation_from( const Vector3& axis ) const
		{
			const auto relative_direction = to_cartesian();
			return axis.getRotationTo( relative_direction );
		}

		friend SphereVector operator-( const SphereVector& value )
		{
			SphereVector result;
			result.radius = -value.radius;
			result.theta  = -value.theta;
			result.phi    = -value.phi;
			return result;
		}

		friend SphereVector operator+( const SphereVector& left, const SphereVector& right )
		{
			SphereVector result;
			result.radius = left.radius + right.radius;
			result.theta  = left.theta + right.theta;
			result.phi    = left.phi + right.phi;
			return result;
		}

		friend SphereVector operator-( const SphereVector& left, const SphereVector& right )
		{
			return left + (-right);
		}

		SphereVector& operator+=( const SphereVector& other )
		{
			*this = *this + other;
			return *this;
		}

		SphereVector& operator-=( const SphereVector& other )
		{
			*this = *this - other;
			return *this;
		}

		/// Rotation of the position around the relative center of the sphere.
		friend SphereVector operator*( const SphereVector& sv, const Quaternion& rotation )
		{
			auto cartesian = sv.to_cartesian();
			cartesian = rotation * cartesian;
			return SphereVector::from_cartesian( cartesian );
		}

		/// Rotation of the position around the relative center of the sphere.
		friend SphereVector operator*( const Quaternion& rotation, const SphereVector& sv ) { return sv * rotation; }

		/// Rotation of the position around the relative center of the sphere.
		SphereVector& operator*=( const Quaternion& rotation )
		{
			*this = *this * rotation;
			return *this;
		}

		friend bool operator==( const SphereVector& left, const SphereVector& right )
		{
			return left.radius == right.radius
				&& left.phi == right.phi
				&& left.theta == right.theta
				;
		}

		friend bool operator!=( const SphereVector& left, const SphereVector& right )
		{
			return !( left == right );
		}

	};

}

#endif
<commit_msg>Fixed from_cartesian using atan2.<commit_after>#ifndef HGUARD_OGRE_SPHERICAL_HPP__
#define HGUARD_OGRE_SPHERICAL_HPP__

#include <OgreMath.h>
#include <OgreVector3.h>
#include <OgreQuaternion.h>

namespace Ogre {

	/** Spherical coordinates vector, used for spherical coordinates and transformations.
		Some example values:
			( radius = 1.0, theta = 0.0deg  , phi = 0.0deg  ) <=> Y unit vector in cartesian space
			( radius = 1.0, theta = 90.0deg , phi = 0.0deg  ) <=> Z unit vector in cartesian space
			( radius = 1.0, theta = 90.0deg , phi = 90.0deg ) <=> X unit vector in cartesian space
	*/
	struct SphereVector
	{
		Real   radius; ///< Rho or Radius is the distance from the center of the sphere.
		Radian theta;  ///< Theta is the angle around the x axis (latitude angle counterclockwise), values range from 0 to PI.
		Radian phi;    ///< Phi is the angle around the y axis (longitude angle counterclockwise), values range from 0 to 2PI.

		// NOTE: if you need to expose these constants through a shared library api, add the export/import macro before each of
		// the following lines.
		static const SphereVector ZERO;
		static const SphereVector UNIT_X;
		static const SphereVector UNIT_Y;
		static const SphereVector UNIT_Z;
		static const SphereVector NEGATIVE_UNIT_X;
		static const SphereVector NEGATIVE_UNIT_Y;
		static const SphereVector NEGATIVE_UNIT_Z;

		/// Default Constructor: no initialization of the values is performed.
		SphereVector() {}

		SphereVector( Real radius, Radian theta, Radian phi )
			: radius( std::move(radius) ), theta( std::move(theta) ), phi( std::move(phi) )
		{}

		/** Construction from a cartesian vector: the spherical vector will have the same relative position
			but in spherical coordinates.
			@see from_cartesian()
		*/
		explicit SphereVector( const Vector3& cartesian_vec )
		{
			*this = from_cartesian( cartesian_vec );
		}

		/** @return a relative Cartesian vector coordinate from this relative spherical coordinate. */
		Vector3 to_cartesian() const
		{
			Vector3 result;
			result.x = radius * Math::Cos( phi ) * Math::Sin( theta );
			result.z = radius * Math::Sin( phi ) * Math::Sin( theta );
			result.y = radius * Math::Cos( theta );
			return result;
		}

		/** @return a relative spherical coordinate from a cartesian vector. */
		/** @return a relative spherical coordinate from a cartesian vector. */
		static SphereVector from_cartesian( const Ogre::Vector3& cartesian )
		{
			SphereVector result = SphereVector::ZERO;
			result.radius = cartesian.length();
			if( result.radius == 0 )
				return result;
			result.phi    = Math::ATan2( cartesian.x, cartesian.z );
			result.theta  = Math::ATan2( Math::Sqrt( Math::Sqr( cartesian.x ) + Math::Sqr( cartesian.z ) ), cartesian.y );
			return result;
		}

		/** @return a relative rotation from the provided axis to the axis corresponding to this relative spherical vector. */
		Quaternion rotation_from( const Vector3& axis ) const
		{
			const auto relative_direction = to_cartesian();
			return axis.getRotationTo( relative_direction );
		}

		friend SphereVector operator-( const SphereVector& value )
		{
			SphereVector result;
			result.radius = -value.radius;
			result.theta  = -value.theta;
			result.phi    = -value.phi;
			return result;
		}

		friend SphereVector operator+( const SphereVector& left, const SphereVector& right )
		{
			SphereVector result;
			result.radius = left.radius + right.radius;
			result.theta  = left.theta + right.theta;
			result.phi    = left.phi + right.phi;
			return result;
		}

		friend SphereVector operator-( const SphereVector& left, const SphereVector& right )
		{
			return left + (-right);
		}

		SphereVector& operator+=( const SphereVector& other )
		{
			*this = *this + other;
			return *this;
		}

		SphereVector& operator-=( const SphereVector& other )
		{
			*this = *this - other;
			return *this;
		}

		/// Rotation of the position around the relative center of the sphere.
		friend SphereVector operator*( const SphereVector& sv, const Quaternion& rotation )
		{
			auto cartesian = sv.to_cartesian();
			cartesian = rotation * cartesian;
			return SphereVector::from_cartesian( cartesian );
		}

		/// Rotation of the position around the relative center of the sphere.
		friend SphereVector operator*( const Quaternion& rotation, const SphereVector& sv ) { return sv * rotation; }

		/// Rotation of the position around the relative center of the sphere.
		SphereVector& operator*=( const Quaternion& rotation )
		{
			*this = *this * rotation;
			return *this;
		}

		friend bool operator==( const SphereVector& left, const SphereVector& right )
		{
			return left.radius == right.radius
				&& left.phi == right.phi
				&& left.theta == right.theta
				;
		}

		friend bool operator!=( const SphereVector& left, const SphereVector& right )
		{
			return !( left == right );
		}

	};

}

#endif
<|endoftext|>


<commit_before>/* -*- mode:linux -*- */
/**
 * \file main.cc
 *
 *
 *
 * \author Ethan Burns
 * \date 2008-10-08
 */

#include <iostream>

#include <stdlib.h>

#include "grid/grid_world.h"

using namespace std;

int main(void)
{
	GridWorld g(NULL, cin);

	g.print(cout);

	return EXIT_SUCCESS;
}
<commit_msg>Do not print the GridWorld.<commit_after>/* -*- mode:linux -*- */
/**
 * \file main.cc
 *
 *
 *
 * \author Ethan Burns
 * \date 2008-10-08
 */

#include <iostream>

#include <stdlib.h>

#include "grid/grid_world.h"

using namespace std;

int main(void)
{
	GridWorld g(NULL, cin);

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <boost/utility/string_ref.hpp>
#include "../ast/ast_printer.h"
#include "../ast/decl.h"
#include "../parser/parser.hpp"
#include "../sema/typecheck.h"
#include "../cgen/codegen.h"

extern FILE* yyin;
int yyparse();
extern std::vector<Decl> globalAST;

/// If `args` contains `flag`, removes it and returns true, otherwise returns false.
bool checkFlag(boost::string_ref flag, std::vector<boost::string_ref>& args) {
    const auto it = std::find(args.begin(), args.end(), flag);
    const bool contains = it != args.end();
    if (contains) args.erase(it);
    return contains;
}

int main(int argc, char** argv) {
    if (argc == 1) {
        std::cout << "error: no input files" << std::endl;
        return 1;
    }

    std::vector<boost::string_ref> args(argv + 1, argv + argc);
    const bool syntaxOnly = checkFlag("-fsyntax-only", args);
    const bool compileOnly = checkFlag("-c", args);
    const bool printAST = checkFlag("-print-ast", args);
    const bool outputToStdout = checkFlag("-o=stdout", args);

    for (boost::string_ref filePath : args) {
        yyin = fopen(filePath.data(), "rb");

        if (!yyin) {
            std::cout << "error: no such file: '"  << filePath << "'" << std::endl;
            return 1;
        }

        int result = yyparse();
        if (result != 0) return result;

        typecheck(globalAST);

        if (printAST) {
            std::cout << globalAST;
        } else if (!syntaxOnly) {
            cgen::compile(globalAST, outputToStdout ? "stdout" : (std::string(filePath) + ".c"));
        }
        globalAST.clear();
    }

    if (!syntaxOnly && !printAST && !compileOnly) {
        // Compile and link C output.
        std::string command = "cc -Werror -Wno-parentheses-equality";
        for (boost::string_ref filePath : args) {
            command.append(" ");
            command.append(filePath.data(), filePath.size());
            command.append(".c");
        }
        if (!outputToStdout) std::cout << command << '\n';
        const int ccExitStatus = system(command.c_str());

        for (boost::string_ref filePath : args) {
            std::remove((std::string(filePath) + ".c").c_str());
        }

        if (ccExitStatus != 0) exit(ccExitStatus);
    }
}
<commit_msg>don't print cc invocation<commit_after>#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <boost/utility/string_ref.hpp>
#include "../ast/ast_printer.h"
#include "../ast/decl.h"
#include "../parser/parser.hpp"
#include "../sema/typecheck.h"
#include "../cgen/codegen.h"

extern FILE* yyin;
int yyparse();
extern std::vector<Decl> globalAST;

/// If `args` contains `flag`, removes it and returns true, otherwise returns false.
bool checkFlag(boost::string_ref flag, std::vector<boost::string_ref>& args) {
    const auto it = std::find(args.begin(), args.end(), flag);
    const bool contains = it != args.end();
    if (contains) args.erase(it);
    return contains;
}

int main(int argc, char** argv) {
    if (argc == 1) {
        std::cout << "error: no input files" << std::endl;
        return 1;
    }

    std::vector<boost::string_ref> args(argv + 1, argv + argc);
    const bool syntaxOnly = checkFlag("-fsyntax-only", args);
    const bool compileOnly = checkFlag("-c", args);
    const bool printAST = checkFlag("-print-ast", args);
    const bool outputToStdout = checkFlag("-o=stdout", args);

    for (boost::string_ref filePath : args) {
        yyin = fopen(filePath.data(), "rb");

        if (!yyin) {
            std::cout << "error: no such file: '"  << filePath << "'" << std::endl;
            return 1;
        }

        int result = yyparse();
        if (result != 0) return result;

        typecheck(globalAST);

        if (printAST) {
            std::cout << globalAST;
        } else if (!syntaxOnly) {
            cgen::compile(globalAST, outputToStdout ? "stdout" : (std::string(filePath) + ".c"));
        }
        globalAST.clear();
    }

    if (!syntaxOnly && !printAST && !compileOnly) {
        // Compile and link C output.
        std::string command = "cc -Werror -Wno-parentheses-equality";
        for (boost::string_ref filePath : args) {
            command.append(" ");
            command.append(filePath.data(), filePath.size());
            command.append(".c");
        }
        const int ccExitStatus = system(command.c_str());

        for (boost::string_ref filePath : args) {
            std::remove((std::string(filePath) + ".c").c_str());
        }

        if (ccExitStatus != 0) exit(ccExitStatus);
    }
}
<|endoftext|>