<commit_before>// This file is part of fteproxy.
//
// fteproxy is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// fteproxy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fteproxy.  If not, see <http://www.gnu.org/licenses/>.

#include <rank_unrank.h>

#include "re2/re2.h"
#include "re2/regexp.h"
#include "re2/prog.h"

/*
 * Please see rank_unrank.h for a detailed explantion of the
 * methods in this file and their purpose.
 */

// Helper fuction. Given a string and a token, performs a python .split()
// Returns a list of string delimnated on the token
array_type_string_t1 tokenize( std::string line, char delim ) {
    array_type_string_t1 retval;

    std::istringstream iss(line);
    std::string fragment;
    while(std::getline(iss, fragment, delim))
        retval.push_back(fragment);

    return retval;
}

// Exceptions
static class _invalid_fst_format: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid FST format.";
    }
} invalid_fst_format;

static class _invalid_fst_exception_state_name: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid DFA format: DFA has N states, and a state that is not in the range 0,1,...,N-1.";
    }
} invalid_fst_exception_state_name;

static class _invalid_fst_exception_symbol_name: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid DFA format: DFA has symbol that is not in the range 0,1,...,255.";
    }
} invalid_fst_exception_symbol_name;

static class _invalid_input_exception_not_in_final_states: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Please verify your input, the string does not result in an accepting path in the DFA.";
    }
} invalid_input_exception_not_in_final_states;

static class _symbol_not_in_sigma: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Please verify your input, it contains a symbol not in the sigma of the DFA.";
    }
} symbol_not_in_sigma;

/*
 * Parameters:
 *   dfa_str: a minimized ATT FST formatted DFA, see: http://www2.research.att.com/~fsmtools/fsm/man4/fsm.5.html
 *   max_len: the maxium length to compute DFA::buildTable
 */
DFA::DFA(const std::string dfa_str, const uint32_t max_len)
    : _fixed_slice(max_len),
      _start_state(0),
      _num_states(0),
      _num_symbols(0)
{
    // construct the _start_state, _final_states and symbols/states of our DFA
    bool startStateIsntSet = true;
    std::string line;
    std::istringstream my_str_stream(dfa_str);
    while ( getline (my_str_stream,line) )
    {
        if (line.empty()) break;

        array_type_string_t1 split_vec = tokenize( line, '\t' );
        if (split_vec.size() == 4) {
            uint32_t current_state = strtol(split_vec.at(0).c_str(),NULL,10);
            uint32_t symbol = strtol(split_vec.at(2).c_str(),NULL,10);
            if (find(_states.begin(), _states.end(), current_state)==_states.end()) {
                _states.push_back( current_state );
            }

            if (find(_symbols.begin(), _symbols.end(), symbol)==_symbols.end()) {
                _symbols.push_back( symbol );
            }

            if ( startStateIsntSet ) {
                _start_state = current_state;
                startStateIsntSet = false;
            }
        } else if (split_vec.size()==1) {
            uint32_t final_state = strtol(split_vec.at(0).c_str(),NULL,10);
            if (find(_final_states.begin(), _final_states.end(), final_state)==_final_states.end()) {
                _final_states.push_back( final_state );
            }
            if (find(_states.begin(), _states.end(), final_state)==_states.end()) {
                _states.push_back( final_state );
            }
        } else {
            throw invalid_fst_format;
        }

    }
    _states.push_back( _states.size() ); // extra for the "dead" state

    _num_symbols = _symbols.size();
    _num_states = _states.size();

    // build up our sigma/sigma_reverse tables which enable mappings between
    // bytes/integers
    uint32_t j, k;
    for (j=0; j<_num_symbols; j++) {
        _sigma.insert( std::pair<uint32_t,char>( j, (char)(_symbols.at(j))) );
        _sigma_reverse.insert( std::pair<char,uint32_t>((char)(_symbols.at(j)), j) );
    }

    // intialize all transitions in our DFA to our dead state
    _delta.resize(_num_states);
    for (j=0; j<_num_states; j++) {
        _delta.at(j).resize(_num_symbols);
        for (k=0; k < _num_symbols; k++) {
            _delta.at(j).at(k) = _num_states - 1;
        }
    }

    // fill our our transition function delta
    std::istringstream my_str_stream2(dfa_str);
    while ( getline (my_str_stream2,line) )
    {
        array_type_string_t1 split_vec = tokenize( line, '\t' );
        if (split_vec.size() == 4) {
            uint32_t current_state = strtol(split_vec.at(0).c_str(),NULL,10);
            uint32_t symbol = strtol(split_vec.at(2).c_str(),NULL,10);
            uint32_t new_state = strtol(split_vec.at(1).c_str(),NULL,10);

            symbol = _sigma_reverse.at(symbol);

            _delta.at(current_state).at(symbol) = new_state;
        }
    }

    _delta_dense.resize(_num_states);
    uint32_t q, a;
    for (q=0; q < _num_states; q++ ) {
        _delta_dense.at(q) = true;
        for (a=1; a < _num_symbols; a++) {
            if (_delta.at(q).at(a-1) != _delta.at(q).at(a)) {
                _delta_dense.at(q) = false;
                break;
            }
        }
    }

    DFA::_validate();

    // perform our precalculation to speed up (un)ranking
    DFA::_buildTable();
}

void DFA::_validate() {
    // ensure DFA has at least one state
    assert(_states.length()>0);

    // ensure DFA has at least one symbol
    assert(_sigma.length()>0);
    assert(_sigma_reverse.length()>0);

    // ensure we have N states, labeled 0,1,..N-1
    array_type_uint32_t1::iterator state;
    for (state=_states.begin(); state!=_states.end(); state++) {
        if (*state >= _states.size()) {
            throw invalid_fst_exception_state_name;
        }
    }

    // ensure all symbols are in the range 0,1,...,255
    for (uint32_t i = 0; i < _symbols.size(); i++) {
        if (_symbols.at(i) > 256 || _symbols.at(i) < 0) {
            throw invalid_fst_exception_symbol_name;
        }
    }
}

void DFA::_buildTable() {
    uint32_t i;
    uint32_t q;
    uint32_t a;

    // ensure our table _T is the correct size
    _T.resize(_num_states);
    for (q=0; q<_num_states; q++) {
        _T.at(q).resize(_fixed_slice+1);
        for (i=0; i<=_fixed_slice; i++) {
            _T.at(q).at(i) = 0;
        }
    }

    // set all _T.at(q).at(0) = 1 for all states in _final_states
    array_type_uint32_t1::iterator state;
    for (state=_final_states.begin(); state!=_final_states.end(); state++) {
        _T.at(*state).at(0) = 1;
    }

    // walk through our table _T
    // we want each entry _T.at(q).at(i) to contain the number of strings that start
    // from state q, terminate in a final state, and are of length i
    for (i=1; i<=_fixed_slice; i++) {
        for (q=0; q<_delta.size(); q++) {
            for (a=0; a<_delta.at(0).size(); a++) {
                uint32_t state = _delta.at(q).at(a);
                _T.at(q).at(i) += _T.at(state).at(i-1);
            }
        }
    }
}

std::string DFA::unrank( const mpz_class c_in ) {
    std::string retval;

    // throw exception if input integer is not in range of pre-computed value
    mpz_class words_in_slice = getNumWordsInLanguage( _fixed_slice, _fixed_slice );
    assert( c_in < words_in_slice );

    // walk the DFA subtracting values from c until we have our n symbols
    mpz_class c = c_in;
    uint32_t n = _fixed_slice;
    uint32_t i, q = _start_state;
    uint32_t chars_left, char_cursor, state_cursor;
    uint32_t sigma_zero = _sigma.at(0);
    mpz_class char_index;
    for (i=1; i<=n; i++) {
        chars_left = n-i;
        if (_delta_dense.at(q)) {
            // our optimized version, when _delta[q][i] is equal to n for all symbols i
            q = _delta.at(q).at(0);
            if (_T.at(q).at(chars_left)!=0) {
                char_index = (c / _T.at(q).at(chars_left));
                char_cursor = char_index.get_ui();
                retval = retval + _sigma.at(char_cursor);
                c = c % _T.at(q).at(chars_left);
            } else {
                retval += sigma_zero;
            }
        } else {
            // traditional goldberg-sipser ranking
            char_cursor = 0;
            state_cursor = _delta.at(q).at(char_cursor);
            while (c >= _T.at(state_cursor).at(chars_left)) {
                c -= _T.at(state_cursor).at(chars_left);
                char_cursor += 1;
                state_cursor =_delta.at(q).at(char_cursor);
            }
            retval += _sigma.at(char_cursor);
            q = state_cursor;
        }
    }

    // bail if our last state q is not in _final_states
    if (find(_final_states.begin(),
             _final_states.end(), q)==_final_states.end()) {
        throw invalid_input_exception_not_in_final_states;
    }

    return retval;
}

mpz_class DFA::rank( const std::string X_in ) {
    mpz_class retval = 0;

    // verify len(X) == _fixe_slice
    assert(X_in.length()==_fixed_slice);

    // walk the DFA, adding values from _T to c
    uint32_t i;
    uint32_t j;
    uint32_t n = X_in.size();
    uint32_t symbol_as_int;
    uint32_t q = _start_state;
    uint32_t state;
    for (i=1; i<=n; i++) {
        try {
            symbol_as_int = _sigma_reverse.at(X_in.at(i-1));
        } catch (int e) {
            throw symbol_not_in_sigma;
        }

        if (_delta_dense.at(q)) {
            // our optimized version, when _delta[q][i] is equal to n for all symbols i
            state = _delta.at(q).at(0);
            retval += (_T.at(state).at(n-i) * symbol_as_int);
        } else {
            // traditional goldberg-sipser ranking
            for (j=1; j<=symbol_as_int; j++) {
                state = _delta.at(q).at(j-1);
                retval += _T.at(state).at(n-i);
            }
        }
        q = _delta.at(q).at(symbol_as_int);
    }

    // bail if our last state q is not in _final_states
    if (find(_final_states.begin(),
             _final_states.end(), q)==_final_states.end()) {
        throw invalid_input_exception_not_in_final_states;
    }

    return retval;
}

mpz_class DFA::getNumWordsInLanguage( const uint32_t min_word_length,
                                      const uint32_t max_word_length )
{
    // verify min_word_length <= max_word_length <= _fixed_slice
    assert(0<=min_word_length);
    assert(min_word_length<=max_word_length);
    assert(max_word_length<=_fixed_slice);

    // count the number of words in the language of length
    // at least min_word_length and no greater than max_word_length
    mpz_class num_words = 0;
    for (uint32_t word_length = min_word_length;
            word_length <= max_word_length;
            word_length++) {
        num_words += _T.at(_start_state).at(word_length);
    }
    return num_words;
}

std::string attFstFromRegex( const std::string regex )
{
    std::string retval;

    // specify compile flags for re2
    re2::Regexp::ParseFlags re_flags;
    re_flags = re2::Regexp::ClassNL;
    re_flags = re_flags | re2::Regexp::OneLine;
    re_flags = re_flags | re2::Regexp::PerlClasses;
    re_flags = re_flags | re2::Regexp::PerlB;
    re_flags = re_flags | re2::Regexp::PerlX;
    re_flags = re_flags | re2::Regexp::Latin1;

    re2::RegexpStatus status;

    // compile regex to DFA
    re2::Regexp* re = NULL;
    re2::Prog* prog = NULL;

    try {
        RE2::Options opt;
        re2::Regexp* re = re2::Regexp::Parse( regex, re_flags, &status );
        re2::Prog* prog = re->CompileToProg( opt.max_mem() );
        retval = prog->PrintEntireDFA( re2::Prog::kFullMatch );
    } catch (int e) {
        // do nothing, we return the empty string
    }

    // cleanup
    if (prog!=NULL)
        delete prog;
    if (re!=NULL)
        re->Decref();

    return retval;
}
<commit_msg>Issue #24: Change asserts to if-then-exception<commit_after>// This file is part of fteproxy.
//
// fteproxy is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// fteproxy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with fteproxy.  If not, see <http://www.gnu.org/licenses/>.

#include <rank_unrank.h>

#include "re2/re2.h"
#include "re2/regexp.h"
#include "re2/prog.h"

/*
 * Please see rank_unrank.h for a detailed explantion of the
 * methods in this file and their purpose.
 */

// Helper fuction. Given a string and a token, performs a python .split()
// Returns a list of string delimnated on the token
array_type_string_t1 tokenize( std::string line, char delim ) {
    array_type_string_t1 retval;

    std::istringstream iss(line);
    std::string fragment;
    while(std::getline(iss, fragment, delim))
        retval.push_back(fragment);

    return retval;
}

// Exceptions
static class _invalid_rank_input: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid rank input: ensure integer is within the correct range.";
    }
} invalid_rank_input;

static class _invalid_unrank_input: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid unrank input: ensure string is exactly fixed length sizee.";
    }
} invalid_unrank_input;

static class _invalid_fst_format: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid FST format.";
    }
} invalid_fst_format;

static class _invalid_fst_exception_state_name: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid DFA format: DFA has N states, and a state that is not in the range 0,1,...,N-1.";
    }
} invalid_fst_exception_state_name;

static class _invalid_fst_exception_symbol_name: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Invalid DFA format: DFA has symbol that is not in the range 0,1,...,255.";
    }
} invalid_fst_exception_symbol_name;

static class _invalid_input_exception_not_in_final_states: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Please verify your input, the string does not result in an accepting path in the DFA.";
    }
} invalid_input_exception_not_in_final_states;

static class _symbol_not_in_sigma: public std::exception
{
    virtual const char* what() const throw()
    {
        return "Please verify your input, it contains a symbol not in the sigma of the DFA.";
    }
} symbol_not_in_sigma;

/*
 * Parameters:
 *   dfa_str: a minimized ATT FST formatted DFA, see: http://www2.research.att.com/~fsmtools/fsm/man4/fsm.5.html
 *   max_len: the maxium length to compute DFA::buildTable
 */
DFA::DFA(const std::string dfa_str, const uint32_t max_len)
    : _fixed_slice(max_len),
      _start_state(0),
      _num_states(0),
      _num_symbols(0)
{
    // construct the _start_state, _final_states and symbols/states of our DFA
    bool startStateIsntSet = true;
    std::string line;
    std::istringstream my_str_stream(dfa_str);
    while ( getline (my_str_stream,line) )
    {
        if (line.empty()) break;

        array_type_string_t1 split_vec = tokenize( line, '\t' );
        if (split_vec.size() == 4) {
            uint32_t current_state = strtol(split_vec.at(0).c_str(),NULL,10);
            uint32_t symbol = strtol(split_vec.at(2).c_str(),NULL,10);
            if (find(_states.begin(), _states.end(), current_state)==_states.end()) {
                _states.push_back( current_state );
            }

            if (find(_symbols.begin(), _symbols.end(), symbol)==_symbols.end()) {
                _symbols.push_back( symbol );
            }

            if ( startStateIsntSet ) {
                _start_state = current_state;
                startStateIsntSet = false;
            }
        } else if (split_vec.size()==1) {
            uint32_t final_state = strtol(split_vec.at(0).c_str(),NULL,10);
            if (find(_final_states.begin(), _final_states.end(), final_state)==_final_states.end()) {
                _final_states.push_back( final_state );
            }
            if (find(_states.begin(), _states.end(), final_state)==_states.end()) {
                _states.push_back( final_state );
            }
        } else {
            throw invalid_fst_format;
        }

    }
    _states.push_back( _states.size() ); // extra for the "dead" state

    _num_symbols = _symbols.size();
    _num_states = _states.size();

    // build up our sigma/sigma_reverse tables which enable mappings between
    // bytes/integers
    uint32_t j, k;
    for (j=0; j<_num_symbols; j++) {
        _sigma.insert( std::pair<uint32_t,char>( j, (char)(_symbols.at(j))) );
        _sigma_reverse.insert( std::pair<char,uint32_t>((char)(_symbols.at(j)), j) );
    }

    // intialize all transitions in our DFA to our dead state
    _delta.resize(_num_states);
    for (j=0; j<_num_states; j++) {
        _delta.at(j).resize(_num_symbols);
        for (k=0; k < _num_symbols; k++) {
            _delta.at(j).at(k) = _num_states - 1;
        }
    }

    // fill our our transition function delta
    std::istringstream my_str_stream2(dfa_str);
    while ( getline (my_str_stream2,line) )
    {
        array_type_string_t1 split_vec = tokenize( line, '\t' );
        if (split_vec.size() == 4) {
            uint32_t current_state = strtol(split_vec.at(0).c_str(),NULL,10);
            uint32_t symbol = strtol(split_vec.at(2).c_str(),NULL,10);
            uint32_t new_state = strtol(split_vec.at(1).c_str(),NULL,10);

            symbol = _sigma_reverse.at(symbol);

            _delta.at(current_state).at(symbol) = new_state;
        }
    }

    _delta_dense.resize(_num_states);
    uint32_t q, a;
    for (q=0; q < _num_states; q++ ) {
        _delta_dense.at(q) = true;
        for (a=1; a < _num_symbols; a++) {
            if (_delta.at(q).at(a-1) != _delta.at(q).at(a)) {
                _delta_dense.at(q) = false;
                break;
            }
        }
    }

    DFA::_validate();

    // perform our precalculation to speed up (un)ranking
    DFA::_buildTable();
}

void DFA::_validate() {
    // ensure DFA has at least one state
    if (_states.length()==0)
        throw invalid_fst_format;

    // ensure DFA has at least one symbol
    if (_sigma.length()==0)
        throw invalid_fst_format;
    if (_sigma_reverse.length()>0)
        throw invalid_fst_format;

    // ensure we have N states, labeled 0,1,..N-1
    array_type_uint32_t1::iterator state;
    for (state=_states.begin(); state!=_states.end(); state++) {
        if (*state >= _states.size()) {
            throw invalid_fst_exception_state_name;
        }
    }

    // ensure all symbols are in the range 0,1,...,255
    for (uint32_t i = 0; i < _symbols.size(); i++) {
        if (_symbols.at(i) > 256 || _symbols.at(i) < 0) {
            throw invalid_fst_exception_symbol_name;
        }
    }
}

void DFA::_buildTable() {
    uint32_t i;
    uint32_t q;
    uint32_t a;

    // ensure our table _T is the correct size
    _T.resize(_num_states);
    for (q=0; q<_num_states; q++) {
        _T.at(q).resize(_fixed_slice+1);
        for (i=0; i<=_fixed_slice; i++) {
            _T.at(q).at(i) = 0;
        }
    }

    // set all _T.at(q).at(0) = 1 for all states in _final_states
    array_type_uint32_t1::iterator state;
    for (state=_final_states.begin(); state!=_final_states.end(); state++) {
        _T.at(*state).at(0) = 1;
    }

    // walk through our table _T
    // we want each entry _T.at(q).at(i) to contain the number of strings that start
    // from state q, terminate in a final state, and are of length i
    for (i=1; i<=_fixed_slice; i++) {
        for (q=0; q<_delta.size(); q++) {
            for (a=0; a<_delta.at(0).size(); a++) {
                uint32_t state = _delta.at(q).at(a);
                _T.at(q).at(i) += _T.at(state).at(i-1);
            }
        }
    }
}

std::string DFA::unrank( const mpz_class c_in ) {
    std::string retval;

    // throw exception if input integer is not in range of pre-computed value
    mpz_class words_in_slice = getNumWordsInLanguage( _fixed_slice, _fixed_slice );
    if ( c_in > words_in_slice )
        throw invalid_unrank_input;

    // walk the DFA subtracting values from c until we have our n symbols
    mpz_class c = c_in;
    uint32_t n = _fixed_slice;
    uint32_t i, q = _start_state;
    uint32_t chars_left, char_cursor, state_cursor;
    uint32_t sigma_zero = _sigma.at(0);
    mpz_class char_index;
    for (i=1; i<=n; i++) {
        chars_left = n-i;
        if (_delta_dense.at(q)) {
            // our optimized version, when _delta[q][i] is equal to n for all symbols i
            q = _delta.at(q).at(0);
            if (_T.at(q).at(chars_left)!=0) {
                char_index = (c / _T.at(q).at(chars_left));
                char_cursor = char_index.get_ui();
                retval = retval + _sigma.at(char_cursor);
                c = c % _T.at(q).at(chars_left);
            } else {
                retval += sigma_zero;
            }
        } else {
            // traditional goldberg-sipser ranking
            char_cursor = 0;
            state_cursor = _delta.at(q).at(char_cursor);
            while (c >= _T.at(state_cursor).at(chars_left)) {
                c -= _T.at(state_cursor).at(chars_left);
                char_cursor += 1;
                state_cursor =_delta.at(q).at(char_cursor);
            }
            retval += _sigma.at(char_cursor);
            q = state_cursor;
        }
    }

    // bail if our last state q is not in _final_states
    if (find(_final_states.begin(),
             _final_states.end(), q)==_final_states.end()) {
        throw invalid_input_exception_not_in_final_states;
    }

    return retval;
}

mpz_class DFA::rank( const std::string X_in ) {
    mpz_class retval = 0;

    // verify len(X) == _fixe_slice
    if (X_in.length()!=_fixed_slice);
        throw invalid_rank_input;

    // walk the DFA, adding values from _T to c
    uint32_t i;
    uint32_t j;
    uint32_t n = X_in.size();
    uint32_t symbol_as_int;
    uint32_t q = _start_state;
    uint32_t state;
    for (i=1; i<=n; i++) {
        try {
            symbol_as_int = _sigma_reverse.at(X_in.at(i-1));
        } catch (int e) {
            throw symbol_not_in_sigma;
        }

        if (_delta_dense.at(q)) {
            // our optimized version, when _delta[q][i] is equal to n for all symbols i
            state = _delta.at(q).at(0);
            retval += (_T.at(state).at(n-i) * symbol_as_int);
        } else {
            // traditional goldberg-sipser ranking
            for (j=1; j<=symbol_as_int; j++) {
                state = _delta.at(q).at(j-1);
                retval += _T.at(state).at(n-i);
            }
        }
        q = _delta.at(q).at(symbol_as_int);
    }

    // bail if our last state q is not in _final_states
    if (find(_final_states.begin(),
             _final_states.end(), q)==_final_states.end()) {
        throw invalid_input_exception_not_in_final_states;
    }

    return retval;
}

mpz_class DFA::getNumWordsInLanguage( const uint32_t min_word_length,
                                      const uint32_t max_word_length )
{
    // verify min_word_length <= max_word_length <= _fixed_slice
    assert(0<=min_word_length);
    assert(min_word_length<=max_word_length);
    assert(max_word_length<=_fixed_slice);

    // count the number of words in the language of length
    // at least min_word_length and no greater than max_word_length
    mpz_class num_words = 0;
    for (uint32_t word_length = min_word_length;
            word_length <= max_word_length;
            word_length++) {
        num_words += _T.at(_start_state).at(word_length);
    }
    return num_words;
}

std::string attFstFromRegex( const std::string regex )
{
    std::string retval;

    // specify compile flags for re2
    re2::Regexp::ParseFlags re_flags;
    re_flags = re2::Regexp::ClassNL;
    re_flags = re_flags | re2::Regexp::OneLine;
    re_flags = re_flags | re2::Regexp::PerlClasses;
    re_flags = re_flags | re2::Regexp::PerlB;
    re_flags = re_flags | re2::Regexp::PerlX;
    re_flags = re_flags | re2::Regexp::Latin1;

    re2::RegexpStatus status;

    // compile regex to DFA
    re2::Regexp* re = NULL;
    re2::Prog* prog = NULL;

    try {
        RE2::Options opt;
        re2::Regexp* re = re2::Regexp::Parse( regex, re_flags, &status );
        re2::Prog* prog = re->CompileToProg( opt.max_mem() );
        retval = prog->PrintEntireDFA( re2::Prog::kFullMatch );
    } catch (int e) {
        // do nothing, we return the empty string
    }

    // cleanup
    if (prog!=NULL)
        delete prog;
    if (re!=NULL)
        re->Decref();

    return retval;
}
<|endoftext|>


<commit_before>#ifndef BOOST_TEST_DYN_LINK
#define BOOST_TEST_DYN_LINK
#endif

#include <boost/test/unit_test.hpp>

#include <stdlib.h>
#include <time.h>

#include <boost/make_shared.hpp>

#include "../simulation/world.hpp"
#include "../simulation/worldGenerator.hpp"
#include "../simulation/anthill.hpp"
#include "../simulation/ant.hpp"

namespace WorldGeneratorTest
{

struct Fixture
{
    Fixture() { srand(time(NULL)); }
    World world;
};

BOOST_FIXTURE_TEST_CASE(test_placeAnthill_shouldBeAnthill, Fixture)
{
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Anthill>().size(), 0);
    AnthillParams params;
    params.quantity = 1;
    WorldGenerator::placeAnthill(&world, params);
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Anthill>().size(), 1);
    BOOST_CHECK_EQUAL(world.getEntityPtrs().size(), 1);
}

BOOST_FIXTURE_TEST_CASE(test_placeAnts_shouldBeAnts, Fixture)
{
    WorldGenerator::placeAnthill(&world);

    BOOST_CHECK_EQUAL(world.getSimulationObjects<Creature>().size(), 0);
    AntsParams params;
    params.quantity = 10;
    params.min_dist_from_anthill = 2;
    params.max_dist_from_anthill = 5;
    WorldGenerator::placeAnts(&world, params);
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Creature>().size(), 10);
    BOOST_CHECK_EQUAL(world.getEntityPtrs().size(), 11); // (+ anthill)
}

BOOST_FIXTURE_TEST_CASE(test_placeObstacles_shouldBeObstacles, Fixture)
{
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Obstacle>().size(), 0);
    ObstaclesParams params;
    params.quantity = 5;
    WorldGenerator::placeObstacles(&world, params);
    BOOST_CHECK(world.getSimulationObjects<Obstacle>().size() > 0);
    BOOST_CHECK(world.getEntityPtrs().size() > 0);
}

BOOST_FIXTURE_TEST_CASE(test_placeFoods_shouldBeFoods, Fixture)
{
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Food>().size(), 0);
    FoodsParams params;
    params.quantity = 5;
    WorldGenerator::placeFoods(&world, params);
    BOOST_CHECK(world.getSimulationObjects<Food>().size() > 0);
    BOOST_CHECK(world.getEntityPtrs().size() > 0);
}

} // namespace WorldGeneratorTest<commit_msg>fixed world generator tests<commit_after>#ifndef BOOST_TEST_DYN_LINK
#define BOOST_TEST_DYN_LINK
#endif

#include <boost/test/unit_test.hpp>

#include <stdlib.h>
#include <time.h>

#include <boost/make_shared.hpp>

#include "../simulation/world.hpp"
#include "../simulation/worldGenerator.hpp"
#include "../simulation/anthill.hpp"
#include "../simulation/ant.hpp"

namespace WorldGeneratorTest
{

struct Fixture
{
    Fixture() { srand(time(NULL)); }
    World world;
};

BOOST_FIXTURE_TEST_CASE(test_placeAnthill_shouldBeAnthill, Fixture)
{
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Anthill>().size(), 0);
    AnthillParams params;
    params.quantity = 1;
    WorldGenerator::placeAnthill(&world, params);
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Anthill>().size(), 1);
    BOOST_CHECK_EQUAL(world.getEntityPtrs().size(), 1);
}

BOOST_FIXTURE_TEST_CASE(test_placeAnts_shouldBeAnts, Fixture)
{
    WorldGenerator::placeAnthill(&world);

    BOOST_CHECK_EQUAL(world.getSimulationObjects<Creature>().size(), 0);
    AntsParams params;
    params.quantity = 10;
    params.min_dist_from_anthill = 2;
    params.max_dist_from_anthill = 5;
    WorldGenerator::placeAnts(&world, params);
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Creature>().size(), 10);
    BOOST_CHECK_EQUAL(world.getEntityPtrs().size(), 11); // (+ anthill)
}

BOOST_FIXTURE_TEST_CASE(test_placeObstacles_shouldBeObstacles, Fixture)
{
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Obstacle>().size(), 0);
    ObstaclesParams params;
    params.quantity_per_100_by_100 = 5;
    WorldGenerator::placeObstacles(&world, params);
    BOOST_CHECK(world.getSimulationObjects<Obstacle>().size() > 0);
    BOOST_CHECK(world.getEntityPtrs().size() > 0);
}

BOOST_FIXTURE_TEST_CASE(test_placeFoods_shouldBeFoods, Fixture)
{
    BOOST_CHECK_EQUAL(world.getSimulationObjects<Food>().size(), 0);
    FoodsParams params;
    params.quantity_per_100_by_100 = 5;
    WorldGenerator::placeFoods(&world, params);
    BOOST_CHECK(world.getSimulationObjects<Food>().size() > 0);
    BOOST_CHECK(world.getEntityPtrs().size() > 0);
}

} // namespace WorldGeneratorTest<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cctype>

#include "dictionary.h"

using namespace std;

void lower(string& s);
string stripPunct(const string& s);
void checkSpelling(ifstream& in, Dictionary& dict);

int main(int argc, char* argv[])
{
	// Output usage message if improper command line args were given.
	if (argc != 3)
    {
		cerr << "Usage: " << argv[0] << " wordlist_filename input_file\n";
		return EXIT_FAILURE;
	}

	ifstream inf(argv[2]);
	if (! inf)
    {
		cerr << "Could not open " << argv[2] << "\n";
		return EXIT_FAILURE;
	}

	// Read dictionary, but let user know what we are working on.
	cout << "Loading dictionary, this may take awhile...\n";

	Dictionary d(argv[1]);

	checkSpelling(inf, d);

	inf.close();

	return EXIT_SUCCESS;
}

void checkSpelling(ifstream& in, Dictionary& dict)
{
	int line_number = 0;

	while (in)
    {
		++line_number;

		string line;
		getline(in, line);

  	    stringstream ss (stringstream::in | stringstream::out);
		ss << line;

		string word;
		while (ss >> word)
        {
			// If the word does not exits
			// So, it is misspelled
			if (!dict.search(word))
			{

			}
		}
	}
}

void lower(string& s)
{
    // Ensures that a word is lowercase
	for (int i = 0; i < s.length(); ++i)
    {
		s[i] = tolower(s[i]);
	}
}

string stripPunct(const string& s)
{
	// Remove any single trailing
	// punctuation character from a word.
	if (ispunct(s[s.length() - 1]))
		return s.substr (0, s.length() - 1);

    return s;
}
<commit_msg>Completed Spellchecking assignment<commit_after>/**
 * @author Nikita Marinosyan
 * @date 26.04.2017
 * Higher School of Economics,
 * Faculty of Computer Science
 */

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <algorithm>

#include "dictionary.h"

using namespace std;

void lower(string& s);
string stripPunct(const string& s);
void checkSpelling(ifstream& in, Dictionary& dict);

string swapWithNext(string misspelled, size_t i);
string eraseCharacter(string misspelled, size_t i);
string replaceCharacter(string misspelled, size_t toBeReplaced, char replacing);
string insertCharacter(string misspelled, size_t placeToInsertBefore, char toBeInserted);

void suggestTransposing(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions);
void suggestRemoval(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions);
void suggestReplacement(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions);
void suggestInserting(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions);

int main(int argc, char* argv[])
{
	// Output usage message if improper command line args were given.
	if (argc != 3)
    {
		cerr << "Usage: " << argv[0] << " wordlist_filename input_file\n";
		return EXIT_FAILURE;
	}

	ifstream inf(argv[2]);
	if (! inf)
    {
		cerr << "Could not open " << argv[2] << "\n";
		return EXIT_FAILURE;
	}

	// Read dictionary, but let user know what we are working on.
	cout << "Loading dictionary, this may take awhile...\n";

	Dictionary d(argv[1]);

	checkSpelling(inf, d);

	inf.close();

	return EXIT_SUCCESS;
}

void checkSpelling(ifstream& in, Dictionary& dict)
{
	int line_number = 0;
	while (in)
    {
		++line_number;

		string line;
		getline(in, line);

  	    stringstream ss (stringstream::in | stringstream::out);
		ss << line;

		string word;
		while (ss >> word)
        {
			// Ensure the word is
			// written in lowercase
			lower(word);

			// Ensure there is no
			// trailing punctuation character
			word = stripPunct(word);

			// If the word does not exits
			// So, it is misspelled
			if (!dict.search(word))
			{
				// Create hash set to control
				// the duplication of suggestions
				HashSet<string, hash_function, equality> suggestions;

				// Output the suggestions header
				cout << "line " << line_number << ": '" << word << "'" << endl;
				cout << "        suggestions:" << endl;

				suggestTransposing(word, dict, suggestions);
				suggestRemoval(word, dict, suggestions);
				suggestReplacement(word, dict, suggestions);
				suggestInserting(word, dict, suggestions);
			}
		}
	}
}

/*
 * Utility method to swap
 * adjacent characters
 */
string swapWithNext(string misspelled, size_t i)
{
	swap(misspelled[i], misspelled[i + 1]);
	return misspelled;
}

/*
 * Method to find the suggestions
 * by transposing adjacent characters
 */
void suggestTransposing(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions)
{
	for (size_t i = 0; i < misspelled.length() - 1; ++i)
	{
		string suggestion = swapWithNext(misspelled, i);
		if (dict.search(suggestion))
		{
			// Check if the word
			// was not suggested yet
			if (!suggestions.search(suggestion))
			{
				// Add it to the suggestions
				suggestions.insert(suggestion);

				// Output the new suggestion
				cout << "                " << suggestion << endl;
			}
		}
	}
}

/*
 * Utility method to erase
 * one character from the word
 */
string eraseCharacter(string misspelled, size_t i)
{
	return misspelled.erase(i, 1);
}

/*
 * Method to find the suggestions
 * by removing one character from the word
 */
void suggestRemoval(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions)
{
	for (size_t i = 0; i < misspelled.length(); ++i)
	{
		string suggestion = eraseCharacter(misspelled, i);
		if (dict.search(suggestion))
		{
            // Check if the word
            // was not suggested yet
            if (!suggestions.search(suggestion))
            {
                // Add it to the suggestions
                suggestions.insert(suggestion);

                // Output the new suggestion
                cout << "                " << suggestion << endl;
            }
		}
	}
}

/*
 * Utility method to replace
 * one character with another
 */
string replaceCharacter(string misspelled, size_t toBeReplaced, char replacing)
{
    return misspelled.replace(toBeReplaced, 1, 1, replacing);
}

/*
 * Method to find the suggestions
 * by replacing the characters
 */
void suggestReplacement(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions)
{
    for (size_t i = 0; i < misspelled.length(); ++i)
    {
        for (char c = 'a'; c <= 'z'; ++c)
        {
            string suggestion = replaceCharacter(misspelled, i, c);
            if (dict.search(suggestion))
            {
                // Check if the word
                // was not suggested yet
                if (!suggestions.search(suggestion))
                {
                    // Add it to the suggestions
                    suggestions.insert(suggestion);

                    // Output the new suggestion
                    cout << "                " << suggestion << endl;
                }
            }
        }
    }
}

/*
 * Utility method to insert
 * one character into the word
 */
string insertCharacter(string misspelled, size_t placeToInsertBefore, char toBeInserted)
{
    return misspelled.insert(placeToInsertBefore, 1, toBeInserted);
}

/*
 * Method to find the suggestions
 * by inserting the characters
 */
void suggestInserting(string misspelled, Dictionary& dict, HashSet<string, hash_function, equality>& suggestions)
{
    for (size_t i = 0; i <= misspelled.length(); ++i)
    {
        for (char c = 'a'; c <= 'z'; ++c)
        {
            string suggestion = insertCharacter(misspelled, i, c);
            if (dict.search(suggestion))
            {
                // Check if the word
                // was not suggested yet
                if (!suggestions.search(suggestion))
                {
                    // Add it to the suggestions
                    suggestions.insert(suggestion);

                    // Output the new suggestion
                    cout << "                " << suggestion << endl;
                }
            }
        }
    }
}

void lower(string& s)
{
    // Ensures that a word is lowercase
	for (int i = 0; i < s.length(); ++i)
		s[i] = (char) tolower(s[i]);
}

string stripPunct(const string& s)
{
	// Remove any single trailing
	// punctuation character from a word.
	if (ispunct(s[s.length() - 1]))
		return s.substr (0, s.length() - 1);

    return s;
}
<|endoftext|>


<commit_before>#include "consoleui.h"
#include <iostream>
#include <iomanip>
using namespace std;

consoleUI::consoleUI()
{

}

consoleUI::consoleUI(int chooseNumber)
{
    _chooseNumber = chooseNumber;
}

void consoleUI::run()
{
    int chooseNumber = 0;

    cout << "---------------------------------------" << endl;
    cout << "------- Database for Scientist --------" << endl;
    cout << "1: Display entire list.               *" << endl;
    cout << "2: Search by name.                    *" << endl;
    cout << "3: Search if alive.                   *" << endl;
    cout << "4: Search for award.                  *" << endl;
    cout << "5: Add new scientist.                 *" << endl;
    cout << "6: Enter Function.                    *" << endl;
    cout << "7: Enter Function.                    *" << endl;
    cout << "8: Enter Function.                    *" << endl;
    cout << "9: Enter Function.                    *" << endl;
    cout << "10: Enter Function.                   *" << endl;
    cout << "---------------------------------------" << endl;
    cout << "Enter number: ";

    cin >> chooseNumber;

    switch (chooseNumber)
    {
        case 1:
            //vector <scientistList> scientists = _scientist.();
            break;
        case 2:
            int firstOrLast;
            cout << "choose 1 for firstname or 2 for lastname" << endl;
            cin >> firstOrLast;
            if(firstOrLast == 1)
            {
                string firstName;
                cout << "Enter firstname";
                cin >> firstName;
                //searchfirstname
            }
            else
            {
                string lastName;
                cout << "Enter lastname:";
                cin >> lastName;

            }
            break;
        case 3:
            //sortAlive
            {
            listServices scientists;
            scientists.changeTo(_scientist.sortByAlive());
            cout << "An organized list starting with the oldest living scientist" << endl;
            for(unsigned int i = 0 ; i < scientists.getSize(); i++)
            {
                cout.width(15);
                cout << scientists.getFirstNameFromList(i) << left << scientists.getLastNameFromList(i) << endl;

            }
             }
              break;
        case 4:
            //sortAward
            break;

        case 5:
    {
            //addNew
        string firstName;
        string lastName;
        char gender;
        int birthYear;
        char isAlive;
        int deathYear;
        char isWinner;
        int awardYear;

        cout << "Please enter the scientist's first name: ";
        cin >> firstName;
        cout << "Please enter the scientist's last name: ";
        cin >> lastName;
        cout << "Enter the scientist's gender (m/f) : ";
        cin >> gender;
        cout << "Enter the scientist's birth year: ";
        cin >> birthYear;
        cout << "Is the scientist still alive? (y/n) ";
        cin >> isAlive;
        if(isAlive == 'n')
        {
        cout << "Enter the scientist's year of death: ";
        cin >>  deathYear;
        }
        else if(isAlive == 'y')
        {
        deathYear = 0;
        }
        else
        {
        "Invalid entry.  Please enter either y (yes) or n (no)";
        }
        cout << "Did the scientist win a Turing award? (y/n)";
        cin >> isWinner;
        if(isWinner == 'y')
        {
        cout << "Enter the year the scientist won: ";
        cin >>  awardYear;
        }
        else if(isWinner == 'n')
        {
        awardYear = 0;
        }
        else
        {
        "Invalid entry.  Please enter either y (yes) or n (no)";
        }

        _scientist.addNew(firstName, lastName, gender, birthYear, deathYear, awardYear);
    }
        break;

    }
}

<commit_msg>working on case 2<commit_after>#include "consoleui.h"
#include <iostream>
#include <iomanip>
using namespace std;

consoleUI::consoleUI()
{

}

consoleUI::consoleUI(int chooseNumber)
{
    _chooseNumber = chooseNumber;
}

void consoleUI::run()
{
    int chooseNumber = 0;

    cout << "---------------------------------------" << endl;
    cout << "------- Database for Scientist --------" << endl;
    cout << "1: Display entire list.               *" << endl;
    cout << "2: Search by name.                    *" << endl;
    cout << "3: Search if alive.                   *" << endl;
    cout << "4: Search for award.                  *" << endl;
    cout << "5: Add new scientist.                 *" << endl;
    cout << "6: Enter Function.                    *" << endl;
    cout << "7: Enter Function.                    *" << endl;
    cout << "8: Enter Function.                    *" << endl;
    cout << "9: Enter Function.                    *" << endl;
    cout << "10: Enter Function.                   *" << endl;
    cout << "---------------------------------------" << endl;
    cout << "Enter number: ";

    cin >> chooseNumber;

    switch (chooseNumber)
    {
        case 1:
            //vector <scientistList> scientists = _scientist.();
            break;
        case 2:
            //
            int firstOrLast;
            cout << "choose 1 for firstname or 2 for lastname" << endl;
            cin >> firstOrLast;
            if(firstOrLast == 1)
            {
                string firstName;
                cout << "Enter firstname";
                cin >> firstName;
                //searchfirstname
            }
            else
            {
                string lastName;
                cout << "Enter lastname:";
                cin >> lastName;

            }
            break;
        case 3:
            //sortAlive
            {
            listServices scientists;
            scientists.changeTo(_scientist.sortByAlive());
            cout << "An organized list starting with the oldest living scientist" << endl;
            for(unsigned int i = 0 ; i < scientists.getSize(); i++)
            {
                cout.width(15);
                cout << scientists.getFirstNameFromList(i) << left << scientists.getLastNameFromList(i) << endl;

            }
             }
              break;
        case 4:
            //sortAward
            break;

        case 5:
    {
            //addNew
        string firstName;
        string lastName;
        char gender;
        int birthYear;
        char isAlive;
        int deathYear;
        char isWinner;
        int awardYear;

        cout << "Please enter the scientist's first name: ";
        cin >> firstName;
        cout << "Please enter the scientist's last name: ";
        cin >> lastName;
        cout << "Enter the scientist's gender (m/f) : ";
        cin >> gender;
        cout << "Enter the scientist's birth year: ";
        cin >> birthYear;
        cout << "Is the scientist still alive? (y/n) ";
        cin >> isAlive;
        if(isAlive == 'n')
        {
        cout << "Enter the scientist's year of death: ";
        cin >>  deathYear;
        }
        else if(isAlive == 'y')
        {
        deathYear = 0;
        }
        else
        {
        "Invalid entry.  Please enter either y (yes) or n (no)";
        }
        cout << "Did the scientist win a Turing award? (y/n)";
        cin >> isWinner;
        if(isWinner == 'y')
        {
        cout << "Enter the year the scientist won: ";
        cin >>  awardYear;
        }
        else if(isWinner == 'n')
        {
        awardYear = 0;
        }
        else
        {
        "Invalid entry.  Please enter either y (yes) or n (no)";
        }

        _scientist.addNew(firstName, lastName, gender, birthYear, deathYear, awardYear);
    }
        break;

    }
}

<|endoftext|>


<commit_before>#include <catch2/catch.hpp>

#include "libslic3r/Model.hpp"
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/Format/stl.hpp"

#include <boost/filesystem/operations.hpp>

using namespace Slic3r;

SCENARIO("Reading 3mf file", "[3mf]") {
    GIVEN("umlauts in the path of the file") {
        Model model;
        WHEN("3mf model is read") {
        	std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf";
        	DynamicPrintConfig config;
            bool ret = load_3mf(path.c_str(), &config, &model, false);
            THEN("load should succeed") {
                REQUIRE(ret);
            }
        }
    }
}

SCENARIO("Export+Import geometry to/from 3mf file cycle", "[3mf]") {
    GIVEN("world vertices coordinates before save") {
        // load a model from stl file
        Model src_model;
        std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/prusa.stl";
        load_stl(src_file.c_str(), &src_model);
        src_model.add_default_instances();

        ModelObject* src_object = src_model.objects[0];

        // apply generic transformation to the 1st volume
        Geometry::Transformation src_volume_transform;
        src_volume_transform.set_offset(Vec3d(10.0, 20.0, 0.0));
        src_volume_transform.set_rotation(Vec3d(Geometry::deg2rad(25.0), Geometry::deg2rad(35.0), Geometry::deg2rad(45.0)));
        src_volume_transform.set_scaling_factor(Vec3d(1.1, 1.2, 1.3));
        src_volume_transform.set_mirror(Vec3d(-1.0, 1.0, -1.0));
        src_object->volumes[0]->set_transformation(src_volume_transform);

        // apply generic transformation to the 1st instance
        Geometry::Transformation src_instance_transform;
        src_instance_transform.set_offset(Vec3d(5.0, 10.0, 0.0));
        src_instance_transform.set_rotation(Vec3d(Geometry::deg2rad(12.0), Geometry::deg2rad(13.0), Geometry::deg2rad(14.0)));
        src_instance_transform.set_scaling_factor(Vec3d(0.9, 0.8, 0.7));
        src_instance_transform.set_mirror(Vec3d(1.0, -1.0, -1.0));
        src_object->instances[0]->set_transformation(src_instance_transform);

        WHEN("model is saved+loaded to/from 3mf file") {
            // save the model to 3mf file
            std::string test_file = std::string(TEST_DATA_DIR) + "/test_3mf/prusa.3mf";
            store_3mf(test_file.c_str(), &src_model, nullptr);

            // load back the model from the 3mf file
            Model dst_model;
            DynamicPrintConfig dst_config;
            load_3mf(test_file.c_str(), &dst_config, &dst_model, false);
            boost::filesystem::remove(test_file);

            // compare meshes
            TriangleMesh src_mesh = src_model.mesh();
            src_mesh.repair();

            TriangleMesh dst_mesh = dst_model.mesh();
            dst_mesh.repair();

            bool res = src_mesh.its.vertices.size() == dst_mesh.its.vertices.size();
            if (res)
            {
                for (size_t i = 0; i < dst_mesh.its.vertices.size(); ++i)
                {
                    res &= dst_mesh.its.vertices[i].isApprox(src_mesh.its.vertices[i]);
                    if (!res)
                    {
                        Vec3f diff = dst_mesh.its.vertices[i] - src_mesh.its.vertices[i];
                        std::cout << i << ": diff " << to_string((Vec3d)diff.cast<double>()) << "\n";
                    }
                }
            }
            THEN("world vertices coordinates after load match") {
                REQUIRE(res);
            }
        }
    }
}
<commit_msg>Follow-up of c790e2ff7c925252b1f83d54154cf858d6eb5afa -> Fixed include<commit_after>#include <catch2/catch.hpp>

#include "libslic3r/Model.hpp"
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/Format/STL.hpp"

#include <boost/filesystem/operations.hpp>

using namespace Slic3r;

SCENARIO("Reading 3mf file", "[3mf]") {
    GIVEN("umlauts in the path of the file") {
        Model model;
        WHEN("3mf model is read") {
        	std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf";
        	DynamicPrintConfig config;
            bool ret = load_3mf(path.c_str(), &config, &model, false);
            THEN("load should succeed") {
                REQUIRE(ret);
            }
        }
    }
}

SCENARIO("Export+Import geometry to/from 3mf file cycle", "[3mf]") {
    GIVEN("world vertices coordinates before save") {
        // load a model from stl file
        Model src_model;
        std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/prusa.stl";
        load_stl(src_file.c_str(), &src_model);
        src_model.add_default_instances();

        ModelObject* src_object = src_model.objects[0];

        // apply generic transformation to the 1st volume
        Geometry::Transformation src_volume_transform;
        src_volume_transform.set_offset(Vec3d(10.0, 20.0, 0.0));
        src_volume_transform.set_rotation(Vec3d(Geometry::deg2rad(25.0), Geometry::deg2rad(35.0), Geometry::deg2rad(45.0)));
        src_volume_transform.set_scaling_factor(Vec3d(1.1, 1.2, 1.3));
        src_volume_transform.set_mirror(Vec3d(-1.0, 1.0, -1.0));
        src_object->volumes[0]->set_transformation(src_volume_transform);

        // apply generic transformation to the 1st instance
        Geometry::Transformation src_instance_transform;
        src_instance_transform.set_offset(Vec3d(5.0, 10.0, 0.0));
        src_instance_transform.set_rotation(Vec3d(Geometry::deg2rad(12.0), Geometry::deg2rad(13.0), Geometry::deg2rad(14.0)));
        src_instance_transform.set_scaling_factor(Vec3d(0.9, 0.8, 0.7));
        src_instance_transform.set_mirror(Vec3d(1.0, -1.0, -1.0));
        src_object->instances[0]->set_transformation(src_instance_transform);

        WHEN("model is saved+loaded to/from 3mf file") {
            // save the model to 3mf file
            std::string test_file = std::string(TEST_DATA_DIR) + "/test_3mf/prusa.3mf";
            store_3mf(test_file.c_str(), &src_model, nullptr);

            // load back the model from the 3mf file
            Model dst_model;
            DynamicPrintConfig dst_config;
            load_3mf(test_file.c_str(), &dst_config, &dst_model, false);
            boost::filesystem::remove(test_file);

            // compare meshes
            TriangleMesh src_mesh = src_model.mesh();
            src_mesh.repair();

            TriangleMesh dst_mesh = dst_model.mesh();
            dst_mesh.repair();

            bool res = src_mesh.its.vertices.size() == dst_mesh.its.vertices.size();
            if (res)
            {
                for (size_t i = 0; i < dst_mesh.its.vertices.size(); ++i)
                {
                    res &= dst_mesh.its.vertices[i].isApprox(src_mesh.its.vertices[i]);
                    if (!res)
                    {
                        Vec3f diff = dst_mesh.its.vertices[i] - src_mesh.its.vertices[i];
                        std::cout << i << ": diff " << to_string((Vec3d)diff.cast<double>()) << "\n";
                    }
                }
            }
            THEN("world vertices coordinates after load match") {
                REQUIRE(res);
            }
        }
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

vector < string > GetWords (string s, char delim)
{
  vector < string > words;
  if (s.find (delim) == string::npos) {
    words.push_back (s);
    return words;
  }
  else {
    stringstream ss (s);
    string word;
    while (getline (ss, word, delim)) {
      words.push_back (word);
    }

    return words;
  }
}

string
LongestWord (string sen)
{
  if (sen == "")
    return "";

  if (sen[0] == ' ')
    sen = sen.substr (1);

  if (sen[sen.length () - 1] == ' ')
    sen = sen.substr (0, sen.length () - 1);

  vector < string > words = GetWords (sen, ' ');

  size_t index = 0;
  int longestWord = 0;
  bool found = false;

  for (int i = words.size () - 1; i >= 0; i--) {
    int length = words[i].length ();
    if (length >= longestWord) {
      longestWord = length;
      index = i;
      found = true;
    }
  }

  return (found ? words[index] : "");
}

int
main ()
{
  size_t tests = 7;
  string test[tests][2] = { {"", ""},
  {"        ", ""},
  {"A", "A"},
  {" A ", "A"},
  {"A AB", "AB"},
  {"AA AA A B", "AA"},
  {"%!#!@ ###3###", "###3###"}
  };
  string input;
  string actual;
  string expected;

  for (size_t i = 0; i < tests; i++) {
    input = test[i][0];
    actual = LongestWord (input);
    expected = test[i][1];
    cout << "Case #" << i +
      1 << " input: '" << input << "' expected: '" << expected <<
      "' actual: '" << actual << "'" << endl;
    if (actual != expected) {
      cout << actual << " did not match " << expected << "; Test failed!" <<
	endl;
    }
    else {
      cout << actual << " did match " << expected << ": Test passed!" << endl;
    }
    cout << endl;
  }

  return 0;
}
<commit_msg>Adds another test case<commit_after>#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

vector < string > GetWords (string s, char delim)
{
  vector < string > words;
  if (s.find (delim) == string::npos) {
    words.push_back (s);
    return words;
  }
  else {
    stringstream ss (s);
    string word;
    while (getline (ss, word, delim)) {
      words.push_back (word);
    }

    return words;
  }
}

string
LongestWord (string sen)
{
  if (sen == "")
    return "";

  if (sen[0] == ' ')
    sen = sen.substr (1);

  if (sen[sen.length () - 1] == ' ')
    sen = sen.substr (0, sen.length () - 1);

  vector < string > words = GetWords (sen, ' ');

  size_t index = 0;
  int longestWord = 0;
  bool found = false;

  for (int i = words.size () - 1; i >= 0; i--) {
    int length = words[i].length ();
    if (length >= longestWord) {
      longestWord = length;
      index = i;
      found = true;
    }
  }

  return (found ? words[index] : "");
}

int
main ()
{
  size_t tests = 8;
  string test[tests][2] = { {"", ""},
  {"        ", ""},
  {"A", "A"},
  {" A ", "A"},
  {"A AB", "AB"},
  {"AA AA A B", "AA"},
  {"%!#!@ ###3###", "###3###"},
  {" A  B   CC   A", "CC"}
  };
  string input;
  string actual;
  string expected;

  for (size_t i = 0; i < tests; i++) {
    input = test[i][0];
    actual = LongestWord (input);
    expected = test[i][1];
    cout << "Case #" << i +
      1 << " input: '" << input << "' expected: '" << expected <<
      "' actual: '" << actual << "'" << endl;
    if (actual != expected) {
      cout << actual << " did not match " << expected << "; Test failed!" <<
	endl;
    }
    else {
      cout << actual << " did match " << expected << ": Test passed!" << endl;
    }
    cout << endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>// @(#)root/gl:$Name:  $:$Id: TGLUtil.cxx,v 1.9 2005/08/10 16:26:35 brun Exp $
// Author:  Richard Maunder  25/05/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// TODO: Function descriptions
// TODO: Class def - same as header!!!

#include "TGLUtil.h"
#include "TGLIncludes.h"
#include "TError.h"
#include "Riostream.h"

ClassImp(TGLVertex3)

//______________________________________________________________________________
TGLVertex3::TGLVertex3()
{
   Fill(0.0);
}

//______________________________________________________________________________
TGLVertex3::TGLVertex3(Double_t x, Double_t y, Double_t z)
{
   Set(x,y,z);
}

//______________________________________________________________________________
TGLVertex3::TGLVertex3(const TGLVertex3 & other)
{
   Set(other);
}

//______________________________________________________________________________
TGLVertex3::~TGLVertex3()
{
}

//______________________________________________________________________________
void TGLVertex3::Shift(TGLVector3 & shift)
{
   fVals[0] += shift[0];
   fVals[1] += shift[1];
   fVals[2] += shift[2];
}

//______________________________________________________________________________
void TGLVertex3::Shift(Double_t xDelta, Double_t yDelta, Double_t zDelta)
{
   fVals[0] += xDelta;
   fVals[1] += yDelta;
   fVals[2] += zDelta;
}

//______________________________________________________________________________
void TGLVertex3::Dump() const
{
   std::cout << "(" << fVals[0] << "," << fVals[1] << "," << fVals[2] << ")" << std::endl;
}

ClassImp(TGLVector3)

//______________________________________________________________________________
TGLVector3::TGLVector3() :
   TGLVertex3()
{
}

//______________________________________________________________________________
TGLVector3::TGLVector3(Double_t x, Double_t y, Double_t z) :
   TGLVertex3(x, y, z)
{
}

//______________________________________________________________________________
TGLVector3::TGLVector3(const TGLVector3 & other) :
   TGLVertex3(other.fVals[0], other.fVals[1], other.fVals[2])
{
}

//______________________________________________________________________________
TGLVector3::~TGLVector3()
{
}

ClassImp(TGLRect)

//______________________________________________________________________________
TGLRect::TGLRect() :
      fX(0), fY(0), fWidth(0), fHeight(0)
{
}

//______________________________________________________________________________
TGLRect::TGLRect(Int_t x, Int_t y, UInt_t width, UInt_t height) :
      fX(x), fY(y), fWidth(width), fHeight(height)
{
}

//______________________________________________________________________________
TGLRect::~TGLRect()
{
}

//______________________________________________________________________________
void TGLRect::Expand(Int_t x, Int_t y)
{
   Int_t delX = x - fX;
   Int_t delY = y - fY;

   if (delX>static_cast<Int_t>(fWidth)) {
      fWidth = delX;
   }
   if (delY>static_cast<Int_t>(fHeight)) {
      fHeight = delY;
   }

   if (delX<0) {
      fX = x;
      fWidth += -delX;
   }
   if (delY<0) {
      fY = y;
      fHeight += -delY;
   }
}

//______________________________________________________________________________
Double_t TGLRect::Aspect() const
{
   if (fHeight == 0) {
      return 0.0;
   } else {
      return static_cast<Double_t>(fWidth) / static_cast<Double_t>(fHeight);
   }
}

//______________________________________________________________________________
EOverlap TGLRect::Overlap(const TGLRect & other) const
{
   if ((fX <= other.fX) && (fX + fWidth >= other.fX + other.fWidth) &&
        (fY <= other.fY) && (fY +fHeight >= other.fY + other.fHeight)) {
      return kInside;
   }
   else if ((fX >= other.fX + static_cast<Int_t>(other.fWidth)) ||
            (fX + static_cast<Int_t>(fWidth) <= other.fX) ||
            (fY >= other.fY + static_cast<Int_t>(other.fHeight)) ||
            (fY + static_cast<Int_t>(fHeight) <= other.fY)) {
      return kOutside;
   } else {
      return kPartial;
   }
}

ClassImp(TGLPlane)

//______________________________________________________________________________
TGLPlane::TGLPlane()
{
   // Construct a default plane of x + y + z = 0
   Set(1.0, 1.0, 1.0, 0.0);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(const TGLPlane & other)
{
   Set(other);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(Double_t a, Double_t b, Double_t c, Double_t d)
{
   // Construct plane with equation a.x + b.y + c.z + d = 0
   // with optional normalisation
   Set(a, b, c, d);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(Double_t eq[4])
{
   // Construct plane with equation eq[0].x + eq[1].y + eq[2].z + eq[3] = 0
   // with optional normalisation
   Set(eq);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(const TGLVertex3 & p1, const TGLVertex3 & p2,
                   const TGLVertex3 & p3)
{
   // Construct plane passing through 3 supplied points
   // with optional normalisation
   Set(p1, p2, p3);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(const TGLVector3 & v, const TGLVertex3 & p)
{
   // Construct plane with supplied normal vector, passing through point
   // with optional normalisation
   Set(v, p);
}

//______________________________________________________________________________
TGLPlane::~TGLPlane()
{
}

//______________________________________________________________________________
void TGLPlane::Dump() const
{
   std::cout.precision(6);
 	std::cout << "Plane : " << fVals[0] << "x + " << fVals[1] << "y + " << fVals[2] << "z + " << fVals[3] <<
	std::endl;
 }

ClassImp(TGLMatrix)

//______________________________________________________________________________
TGLMatrix::TGLMatrix()
{
   SetIdentity();
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(Double_t x, Double_t y, Double_t z)
{
   SetIdentity();
   Set(x, y, z);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const TGLVertex3 & translation)
{
   SetIdentity();
   Set(translation);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis)
{
   SetIdentity();
   Set(origin, zAxis);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const Double_t vals[16])
{
   Set(vals);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const TGLMatrix & other)
{
   *this = other;
}

//______________________________________________________________________________
TGLMatrix::~TGLMatrix()
{
}

//______________________________________________________________________________
void TGLMatrix::Set(Double_t x, Double_t y, Double_t z)
{
   Set(TGLVertex3(x,y,z));
}

//______________________________________________________________________________
void TGLMatrix::Set(const TGLVertex3 & translation)
{
   // Set the translation component of matirx - rest left unaffected
   fVals[12] = translation[0];
   fVals[13] = translation[1];
   fVals[14] = translation[2];
}

//______________________________________________________________________________
void TGLMatrix::Set(const TGLVertex3 & origin, const TGLVector3 & z)
{
   // Establish matrix transformation which when applied puts local origin at
   // passed 'origin' and the local Z axis in direction 'z'. Both
   // 'origin' and 'zAxisVec' are expressed in the parent frame
   TGLVector3 zAxis(z);
   zAxis.Normalise();
   TGLVector3 axis;
   if (fabsf(zAxis.X()) <= fabsf(zAxis.Y()) && fabsf(zAxis.X()) <= fabsf(zAxis.Z())) {
      axis.Set(1, 0, 0);
   } else if (fabsf(zAxis.Y()) <= fabsf(zAxis.X()) && fabsf(zAxis.Y()) <= fabsf(zAxis.Z())) {
      axis.Set(0, 1, 0);
   } else {
      axis.Set(0, 0, 1);
   }

   TGLVector3 xAxis = Cross(zAxis, axis);
   xAxis.Normalise();
   TGLVector3 yAxis = Cross(zAxis, xAxis);

   fVals[0] = xAxis.X(); fVals[4] = yAxis.X(); fVals[8 ] = zAxis.X(); fVals[12] = origin.X();
   fVals[1] = xAxis.Y(); fVals[5] = yAxis.Y(); fVals[9 ] = zAxis.Y(); fVals[13] = origin.Y();
   fVals[2] = xAxis.Z(); fVals[6] = yAxis.Z(); fVals[10] = zAxis.Z(); fVals[14] = origin.Z();
   fVals[3] = 0.0;       fVals[7] = 0.0;       fVals[11] = 0.0;       fVals[15] = 1.0;
}

//______________________________________________________________________________
void TGLMatrix::Set(const Double_t vals[16])
{
   for (UInt_t i=0; i < 16; i++) {
      fVals[i] = vals[i];
   }
}

//______________________________________________________________________________
void TGLMatrix::SetIdentity()
{
   fVals[0] = 1.0; fVals[4] = 0.0; fVals[8 ] = 0.0; fVals[12] = 0.0;
   fVals[1] = 0.0; fVals[5] = 1.0; fVals[9 ] = 0.0; fVals[13] = 0.0;
   fVals[2] = 0.0; fVals[6] = 0.0; fVals[10] = 1.0; fVals[14] = 0.0;
   fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
}

//______________________________________________________________________________
TGLVertex3 TGLMatrix::Translation() const
{
   return TGLVertex3(fVals[12], fVals[13], fVals[14]);
}

//______________________________________________________________________________
void TGLMatrix::Shift(const TGLVector3 & shift)
{
   fVals[12] += shift[0];
   fVals[13] += shift[1];
   fVals[14] += shift[2];
}

//______________________________________________________________________________
TGLVector3 TGLMatrix::Scale() const
{
   // Get local axis scaling factors
   TGLVector3 x(fVals[0], fVals[1], fVals[2]);
   TGLVector3 y(fVals[4], fVals[5], fVals[6]);
   TGLVector3 z(fVals[8], fVals[9], fVals[10]);
   return TGLVector3(x.Mag(), y.Mag(), z.Mag());
}

//______________________________________________________________________________
void TGLMatrix::SetScale(const TGLVector3 & scale)
{

   // Set local axis scaling factors
   TGLVector3 currentScale = Scale();

   // x
   if (currentScale[0] != 0.0) {
      fVals[0] *= scale[0]/currentScale[0];
      fVals[1] *= scale[0]/currentScale[0];
      fVals[2] *= scale[0]/currentScale[0];
   } else {
      Error("TGLMatrix::SetScale()", "zero scale div by zero");
   }
   // y
   if (currentScale[1] != 0.0) {
      fVals[4] *= scale[1]/currentScale[1];
      fVals[5] *= scale[1]/currentScale[1];
      fVals[6] *= scale[1]/currentScale[1];
   } else {
      Error("TGLMatrix::SetScale()", "zero scale div by zero");
   }
   // z
   if (currentScale[2] != 0.0) {
      fVals[8] *= scale[2]/currentScale[2];
      fVals[9] *= scale[2]/currentScale[2];
      fVals[10] *= scale[2]/currentScale[2];
   } else {
      Error("TGLMatrix::SetScale()", "zero scale div by zero");
   }
}

//______________________________________________________________________________
void TGLMatrix::Transpose3x3()
{
   // Transpose the top left 3x3 matrix component along major diagonal

   // TODO: Move this fix to the TBuffer3D filling side and remove

   // 0  4  8 12
   // 1  5  9 13
   // 2  6 10 14
   // 3  7 11 15

   Double_t temp = fVals[4];
	fVals[4] = fVals[1];
	fVals[1] = temp;
	temp = fVals[8];
	fVals[8] = fVals[2];
	fVals[2] = temp;
	temp = fVals[9];
	fVals[9] = fVals[6];
	fVals[6] = temp;
}

//______________________________________________________________________________
void TGLMatrix::TransformVertex(TGLVertex3 & vertex) const
{
   TGLVertex3 orig = vertex;
   for (UInt_t i = 0; i < 3; i++) {
      vertex[i] = orig[0] * fVals[0+i] + orig[1] * fVals[4+i] +
                  orig[2] * fVals[8+i] + fVals[12+i];
   }
}

//______________________________________________________________________________
void TGLMatrix::Dump() const
{
   std::cout.precision(6);
   for (Int_t x = 0; x < 4; x++) {
      std::cout << "[ ";
      for (Int_t y = 0; y < 4; y++) {
         std::cout << fVals[y*4 + x] << " ";
      }
      std::cout << "]" << std::endl;
   }
}

ClassImp(TGLUtil)

//______________________________________________________________________________
void TGLUtil::CheckError()
{
   GLenum errCode;
   const GLubyte *errString;

   if ((errCode = glGetError()) != GL_NO_ERROR) {
      errString = gluErrorString(errCode);
      Error("TGLUtil::CheckError", (const char *)errString);
   }
}
<commit_msg>From Richard: Fix Solaris compilation problem - hopefully.<commit_after>// @(#)root/gl:$Name:  $:$Id: TGLUtil.cxx,v 1.10 2005/10/03 15:19:35 brun Exp $
// Author:  Richard Maunder  25/05/2005

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// TODO: Function descriptions
// TODO: Class def - same as header!!!

#include "TGLUtil.h"
#include "TGLIncludes.h"
#include "TError.h"
#include "Riostream.h"

ClassImp(TGLVertex3)

//______________________________________________________________________________
TGLVertex3::TGLVertex3()
{
   Fill(0.0);
}

//______________________________________________________________________________
TGLVertex3::TGLVertex3(Double_t x, Double_t y, Double_t z)
{
   Set(x,y,z);
}

//______________________________________________________________________________
TGLVertex3::TGLVertex3(const TGLVertex3 & other)
{
   Set(other);
}

//______________________________________________________________________________
TGLVertex3::~TGLVertex3()
{
}

//______________________________________________________________________________
void TGLVertex3::Shift(TGLVector3 & shift)
{
   fVals[0] += shift[0];
   fVals[1] += shift[1];
   fVals[2] += shift[2];
}

//______________________________________________________________________________
void TGLVertex3::Shift(Double_t xDelta, Double_t yDelta, Double_t zDelta)
{
   fVals[0] += xDelta;
   fVals[1] += yDelta;
   fVals[2] += zDelta;
}

//______________________________________________________________________________
void TGLVertex3::Dump() const
{
   std::cout << "(" << fVals[0] << "," << fVals[1] << "," << fVals[2] << ")" << std::endl;
}

ClassImp(TGLVector3)

//______________________________________________________________________________
TGLVector3::TGLVector3() :
   TGLVertex3()
{
}

//______________________________________________________________________________
TGLVector3::TGLVector3(Double_t x, Double_t y, Double_t z) :
   TGLVertex3(x, y, z)
{
}

//______________________________________________________________________________
TGLVector3::TGLVector3(const TGLVector3 & other) :
   TGLVertex3(other.fVals[0], other.fVals[1], other.fVals[2])
{
}

//______________________________________________________________________________
TGLVector3::~TGLVector3()
{
}

ClassImp(TGLRect)

//______________________________________________________________________________
TGLRect::TGLRect() :
      fX(0), fY(0), fWidth(0), fHeight(0)
{
}

//______________________________________________________________________________
TGLRect::TGLRect(Int_t x, Int_t y, UInt_t width, UInt_t height) :
      fX(x), fY(y), fWidth(width), fHeight(height)
{
}

//______________________________________________________________________________
TGLRect::~TGLRect()
{
}

//______________________________________________________________________________
void TGLRect::Expand(Int_t x, Int_t y)
{
   Int_t delX = x - fX;
   Int_t delY = y - fY;

   if (delX>static_cast<Int_t>(fWidth)) {
      fWidth = delX;
   }
   if (delY>static_cast<Int_t>(fHeight)) {
      fHeight = delY;
   }

   if (delX<0) {
      fX = x;
      fWidth += -delX;
   }
   if (delY<0) {
      fY = y;
      fHeight += -delY;
   }
}

//______________________________________________________________________________
Double_t TGLRect::Aspect() const
{
   if (fHeight == 0) {
      return 0.0;
   } else {
      return static_cast<Double_t>(fWidth) / static_cast<Double_t>(fHeight);
   }
}

//______________________________________________________________________________
EOverlap TGLRect::Overlap(const TGLRect & other) const
{
   if ((fX <= other.fX) && (fX + fWidth >= other.fX + other.fWidth) &&
        (fY <= other.fY) && (fY +fHeight >= other.fY + other.fHeight)) {
      return kInside;
   }
   else if ((fX >= other.fX + static_cast<Int_t>(other.fWidth)) ||
            (fX + static_cast<Int_t>(fWidth) <= other.fX) ||
            (fY >= other.fY + static_cast<Int_t>(other.fHeight)) ||
            (fY + static_cast<Int_t>(fHeight) <= other.fY)) {
      return kOutside;
   } else {
      return kPartial;
   }
}

ClassImp(TGLPlane)

//______________________________________________________________________________
TGLPlane::TGLPlane()
{
   // Construct a default plane of x + y + z = 0
   Set(1.0, 1.0, 1.0, 0.0);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(const TGLPlane & other)
{
   Set(other);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(Double_t a, Double_t b, Double_t c, Double_t d)
{
   // Construct plane with equation a.x + b.y + c.z + d = 0
   // with optional normalisation
   Set(a, b, c, d);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(Double_t eq[4])
{
   // Construct plane with equation eq[0].x + eq[1].y + eq[2].z + eq[3] = 0
   // with optional normalisation
   Set(eq);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(const TGLVertex3 & p1, const TGLVertex3 & p2,
                   const TGLVertex3 & p3)
{
   // Construct plane passing through 3 supplied points
   // with optional normalisation
   Set(p1, p2, p3);
}

//______________________________________________________________________________
TGLPlane::TGLPlane(const TGLVector3 & v, const TGLVertex3 & p)
{
   // Construct plane with supplied normal vector, passing through point
   // with optional normalisation
   Set(v, p);
}

//______________________________________________________________________________
TGLPlane::~TGLPlane()
{
}

//______________________________________________________________________________
void TGLPlane::Dump() const
{
   std::cout.precision(6);
 	std::cout << "Plane : " << fVals[0] << "x + " << fVals[1] << "y + " << fVals[2] << "z + " << fVals[3] <<
	std::endl;
 }

ClassImp(TGLMatrix)

//______________________________________________________________________________
TGLMatrix::TGLMatrix()
{
   SetIdentity();
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(Double_t x, Double_t y, Double_t z)
{
   SetIdentity();
   Set(x, y, z);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const TGLVertex3 & translation)
{
   SetIdentity();
   Set(translation);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const TGLVertex3 & origin, const TGLVector3 & zAxis)
{
   SetIdentity();
   Set(origin, zAxis);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const Double_t vals[16])
{
   Set(vals);
}

//______________________________________________________________________________
TGLMatrix::TGLMatrix(const TGLMatrix & other)
{
   *this = other;
}

//______________________________________________________________________________
TGLMatrix::~TGLMatrix()
{
}

//______________________________________________________________________________
void TGLMatrix::Set(Double_t x, Double_t y, Double_t z)
{
   Set(TGLVertex3(x,y,z));
}

//______________________________________________________________________________
void TGLMatrix::Set(const TGLVertex3 & translation)
{
   // Set the translation component of matirx - rest left unaffected
   fVals[12] = translation[0];
   fVals[13] = translation[1];
   fVals[14] = translation[2];
}

//______________________________________________________________________________
void TGLMatrix::Set(const TGLVertex3 & origin, const TGLVector3 & z)
{
   // Establish matrix transformation which when applied puts local origin at
   // passed 'origin' and the local Z axis in direction 'z'. Both
   // 'origin' and 'zAxisVec' are expressed in the parent frame
   TGLVector3 zAxis(z);
   zAxis.Normalise();
   TGLVector3 axis;
   if (fabs(zAxis.X()) <= fabs(zAxis.Y()) && fabs(zAxis.X()) <= fabs(zAxis.Z())) {
      axis.Set(1, 0, 0);
   } else if (fabs(zAxis.Y()) <= fabs(zAxis.X()) && fabs(zAxis.Y()) <= fabs(zAxis.Z())) {
      axis.Set(0, 1, 0);
   } else {
      axis.Set(0, 0, 1);
   }

   TGLVector3 xAxis = Cross(zAxis, axis);
   xAxis.Normalise();
   TGLVector3 yAxis = Cross(zAxis, xAxis);

   fVals[0] = xAxis.X(); fVals[4] = yAxis.X(); fVals[8 ] = zAxis.X(); fVals[12] = origin.X();
   fVals[1] = xAxis.Y(); fVals[5] = yAxis.Y(); fVals[9 ] = zAxis.Y(); fVals[13] = origin.Y();
   fVals[2] = xAxis.Z(); fVals[6] = yAxis.Z(); fVals[10] = zAxis.Z(); fVals[14] = origin.Z();
   fVals[3] = 0.0;       fVals[7] = 0.0;       fVals[11] = 0.0;       fVals[15] = 1.0;
}

//______________________________________________________________________________
void TGLMatrix::Set(const Double_t vals[16])
{
   for (UInt_t i=0; i < 16; i++) {
      fVals[i] = vals[i];
   }
}

//______________________________________________________________________________
void TGLMatrix::SetIdentity()
{
   fVals[0] = 1.0; fVals[4] = 0.0; fVals[8 ] = 0.0; fVals[12] = 0.0;
   fVals[1] = 0.0; fVals[5] = 1.0; fVals[9 ] = 0.0; fVals[13] = 0.0;
   fVals[2] = 0.0; fVals[6] = 0.0; fVals[10] = 1.0; fVals[14] = 0.0;
   fVals[3] = 0.0; fVals[7] = 0.0; fVals[11] = 0.0; fVals[15] = 1.0;
}

//______________________________________________________________________________
TGLVertex3 TGLMatrix::Translation() const
{
   return TGLVertex3(fVals[12], fVals[13], fVals[14]);
}

//______________________________________________________________________________
void TGLMatrix::Shift(const TGLVector3 & shift)
{
   fVals[12] += shift[0];
   fVals[13] += shift[1];
   fVals[14] += shift[2];
}

//______________________________________________________________________________
TGLVector3 TGLMatrix::Scale() const
{
   // Get local axis scaling factors
   TGLVector3 x(fVals[0], fVals[1], fVals[2]);
   TGLVector3 y(fVals[4], fVals[5], fVals[6]);
   TGLVector3 z(fVals[8], fVals[9], fVals[10]);
   return TGLVector3(x.Mag(), y.Mag(), z.Mag());
}

//______________________________________________________________________________
void TGLMatrix::SetScale(const TGLVector3 & scale)
{

   // Set local axis scaling factors
   TGLVector3 currentScale = Scale();

   // x
   if (currentScale[0] != 0.0) {
      fVals[0] *= scale[0]/currentScale[0];
      fVals[1] *= scale[0]/currentScale[0];
      fVals[2] *= scale[0]/currentScale[0];
   } else {
      Error("TGLMatrix::SetScale()", "zero scale div by zero");
   }
   // y
   if (currentScale[1] != 0.0) {
      fVals[4] *= scale[1]/currentScale[1];
      fVals[5] *= scale[1]/currentScale[1];
      fVals[6] *= scale[1]/currentScale[1];
   } else {
      Error("TGLMatrix::SetScale()", "zero scale div by zero");
   }
   // z
   if (currentScale[2] != 0.0) {
      fVals[8] *= scale[2]/currentScale[2];
      fVals[9] *= scale[2]/currentScale[2];
      fVals[10] *= scale[2]/currentScale[2];
   } else {
      Error("TGLMatrix::SetScale()", "zero scale div by zero");
   }
}

//______________________________________________________________________________
void TGLMatrix::Transpose3x3()
{
   // Transpose the top left 3x3 matrix component along major diagonal

   // TODO: Move this fix to the TBuffer3D filling side and remove

   // 0  4  8 12
   // 1  5  9 13
   // 2  6 10 14
   // 3  7 11 15

   Double_t temp = fVals[4];
	fVals[4] = fVals[1];
	fVals[1] = temp;
	temp = fVals[8];
	fVals[8] = fVals[2];
	fVals[2] = temp;
	temp = fVals[9];
	fVals[9] = fVals[6];
	fVals[6] = temp;
}

//______________________________________________________________________________
void TGLMatrix::TransformVertex(TGLVertex3 & vertex) const
{
   TGLVertex3 orig = vertex;
   for (UInt_t i = 0; i < 3; i++) {
      vertex[i] = orig[0] * fVals[0+i] + orig[1] * fVals[4+i] +
                  orig[2] * fVals[8+i] + fVals[12+i];
   }
}

//______________________________________________________________________________
void TGLMatrix::Dump() const
{
   std::cout.precision(6);
   for (Int_t x = 0; x < 4; x++) {
      std::cout << "[ ";
      for (Int_t y = 0; y < 4; y++) {
         std::cout << fVals[y*4 + x] << " ";
      }
      std::cout << "]" << std::endl;
   }
}

ClassImp(TGLUtil)

//______________________________________________________________________________
void TGLUtil::CheckError()
{
   GLenum errCode;
   const GLubyte *errString;

   if ((errCode = glGetError()) != GL_NO_ERROR) {
      errString = gluErrorString(errCode);
      Error("TGLUtil::CheckError", (const char *)errString);
   }
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref gtc_random
/// @file glm/gtc/random.hpp
/// @date 2011-09-18 / 2011-09-18
/// @author Christophe Riccio
///
/// @see core (dependence)
/// @see gtc_half_float (dependence)
/// @see gtx_random (extended)
///
/// @defgroup gtc_random GLM_GTC_random: Random number generation
/// @ingroup gtc
///
/// @brief Generate random number from various distribution methods
///
/// <glm/gtc/random.hpp> need to be included to use these functionalities.
///////////////////////////////////////////////////////////////////////////////////

#ifndef GLM_GTC_random
#define GLM_GTC_random GLM_VERSION

// Dependency:
#include "../glm.hpp"
#include "../gtc/half_float.hpp"

#if(defined(GLM_MESSAGES) && !defined(glm_ext))
#	pragma message("GLM: GLM_GTC_random extension included")
#endif

namespace glm
{
	/// @addtogroup gtc_random
	/// @{

	/// Generate a random number in the interval [-1, 1], according a linear distribution.
	/// From GLM_GTC_random extension.
    template <typename T> T signedRand1();

	/// @}
}//namespace glm

#include "random.inl"

#endif//GLM_GTC_random
<commit_msg>Added new GTC API for random<commit_after>///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref gtc_random
/// @file glm/gtc/random.hpp
/// @date 2011-09-18 / 2011-09-18
/// @author Christophe Riccio
///
/// @see core (dependence)
/// @see gtc_half_float (dependence)
/// @see gtx_random (extended)
///
/// @defgroup gtc_random GLM_GTC_random: Random number generation
/// @ingroup gtc
///
/// @brief Generate random number from various distribution methods
///
/// <glm/gtc/random.hpp> need to be included to use these functionalities.
///////////////////////////////////////////////////////////////////////////////////

#ifndef GLM_GTC_random
#define GLM_GTC_random GLM_VERSION

// Dependency:
#include "../glm.hpp"
#include "../gtc/half_float.hpp"

#if(defined(GLM_MESSAGES) && !defined(glm_ext))
#	pragma message("GLM: GLM_GTC_random extension included")
#endif

namespace glm
{
	/// @addtogroup gtc_random
	/// @{

	/// Generate random numbers in the interval [Min, Max], according a linear distribution
	///
	/// @param Min
	/// @param Max
	/// @tparam genType Value type. Currently supported: half (not recommanded), float or double scalars and vectors.
	/// @see gtc_random
	template <typename genType>
	genType linearRand(
		genType const & Min,
		genType const & Max);

	/// Generate random numbers in the interval [Min, Max], according a gaussian distribution
	/// (From GLM_GTX_random extension)
	template <typename T, template <typename> class vecType>
	vecType<T> gaussRand(
		vecType<T> const & Mean,
		vecType<T> const & Deviation);

	/// Generate a random 2D vector which coordinates are regulary distributed on a circle of a given radius
	/// (From GLM_GTX_random extension)
	template <typename T>
	detail::tvec2<T> circularRand(T const & Radius);

	/// Generate a random 3D vector which coordinates are regulary distributed on a sphere of a given radius
	/// (From GLM_GTX_random extension)
	template <typename T>
	detail::tvec3<T> sphericalRand(T const & Radius);

	/// @}
}//namespace glm

#include "random.inl"

#endif//GLM_GTC_random
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <thrust/detail/raw_buffer.h>
#include <thrust/distance.h>
#include <thrust/copy.h>

namespace thrust
{

namespace detail
{

template<typename T, typename Space>
  raw_buffer<T,Space>
    ::raw_buffer(size_type n)
{
  m_begin = m_allocator.allocate(n);
  m_end = m_begin + n;
} // end raw_buffer::raw_buffer()

template<typename T, typename Space>
  template<typename InputIterator>
    raw_buffer<T,Space>
      ::raw_buffer(InputIterator first, InputIterator last)
{
  size_type n = thrust::distance(first,last);
  m_begin = m_allocator.allocate(n);
  m_end = m_begin + n;
  thrust::copy(first, last, begin());
} // end raw_buffer::raw_buffer()

template<typename T, typename Space>
  raw_buffer<T,Space>
    ::~raw_buffer(void)
{
  if(size() > 0)
  {
    m_allocator.deallocate(&*m_begin, size());
    m_begin = m_end = pointer(static_cast<T*>(0));
  } // end if
} // end raw_buffer::~raw_buffer()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::size_type raw_buffer<T,Space>
    ::size(void) const
{
  return m_end - m_begin;
} // end raw_buffer::size()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::iterator raw_buffer<T,Space>
    ::begin(void)
{
  return m_begin;
} // end raw_buffer::begin()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::begin(void) const
{
  return m_begin;
} // end raw_buffer::begin()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::cbegin(void) const
{
  return m_begin;
} // end raw_buffer::cbegin()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::iterator raw_buffer<T,Space>
    ::end(void)
{
  return m_end;
} // end raw_buffer::end()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::end(void) const
{
  return m_end;
} // end raw_buffer::end()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::cend(void) const
{
  return m_end;
} // end raw_buffer::cend()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::reference raw_buffer<T,Space>
    ::operator[](size_type n)
{
  return m_begin[n];
} // end raw_buffer::operator[]()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_reference raw_buffer<T,Space>
    ::operator[](size_type n) const
{
  return m_begin[n];
} // end raw_buffer::operator[]()

} // end detail

} // end thrust

<commit_msg>Simplify raw_buffer's destructor just a tad.<commit_after>/*
 *  Copyright 2008-2009 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <thrust/detail/raw_buffer.h>
#include <thrust/distance.h>
#include <thrust/copy.h>

namespace thrust
{

namespace detail
{

template<typename T, typename Space>
  raw_buffer<T,Space>
    ::raw_buffer(size_type n)
{
  m_begin = m_allocator.allocate(n);
  m_end = m_begin + n;
} // end raw_buffer::raw_buffer()

template<typename T, typename Space>
  template<typename InputIterator>
    raw_buffer<T,Space>
      ::raw_buffer(InputIterator first, InputIterator last)
{
  size_type n = thrust::distance(first,last);
  m_begin = m_allocator.allocate(n);
  m_end = m_begin + n;
  thrust::copy(first, last, begin());
} // end raw_buffer::raw_buffer()

template<typename T, typename Space>
  raw_buffer<T,Space>
    ::~raw_buffer(void)
{
  if(size() > 0)
  {
    m_allocator.deallocate(&*m_begin, size());
    m_end = m_begin;
  } // end if
} // end raw_buffer::~raw_buffer()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::size_type raw_buffer<T,Space>
    ::size(void) const
{
  return m_end - m_begin;
} // end raw_buffer::size()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::iterator raw_buffer<T,Space>
    ::begin(void)
{
  return m_begin;
} // end raw_buffer::begin()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::begin(void) const
{
  return m_begin;
} // end raw_buffer::begin()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::cbegin(void) const
{
  return m_begin;
} // end raw_buffer::cbegin()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::iterator raw_buffer<T,Space>
    ::end(void)
{
  return m_end;
} // end raw_buffer::end()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::end(void) const
{
  return m_end;
} // end raw_buffer::end()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_iterator raw_buffer<T,Space>
    ::cend(void) const
{
  return m_end;
} // end raw_buffer::cend()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::reference raw_buffer<T,Space>
    ::operator[](size_type n)
{
  return m_begin[n];
} // end raw_buffer::operator[]()

template<typename T, typename Space>
  typename raw_buffer<T,Space>::const_reference raw_buffer<T,Space>
    ::operator[](size_type n) const
{
  return m_begin[n];
} // end raw_buffer::operator[]()

} // end detail

} // end thrust

<|endoftext|>