<commit_before>//
// Copyright (c) 2020 Andrii Verbytskyi <andrii.verbytskyi@mpp.mpg.de> for the binder project
//
// All rights reserved. Use of this source code is governed by a
// MIT license that can be found in the LICENSE file.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <vector>
#include <string.h>

int skip(std::string const & s1)
{
    if (s1.length()==0) return 1;
    if (s1.length()>1)
    {
        size_t comment=s1.find_first_of("//");
        if (comment==s1.find_first_not_of(" \t")&&comment!=std::string::npos) return 2; //The comments should be ignored
    }
    if (s1.find("Source list file")!=std::string::npos) return 3;       //Same as the list of source files
    if (s1.find("Modules list file")!=std::string::npos) return 4;      //Same as the list of modules
    if (s1.find("File:")!=std::string::npos) return 5;                  //Same as the full file paths.
    if (s1.find("pybind11::handle cl_type = cl;")!=std::string::npos) return 6;  //This could be optimized in binder
    if (s1.find("__cxx11")!=std::string::npos) return 7;                         //This looks like implementation dependent
    if (s1.find("assign")!=std::string::npos) return 8;                          // The assing is binded differently for some reasons
    return 0;
}
int compare_text_files(std::string const & f1,const std::string & f2)
{
    std::fstream file1(f1), file2(f2);
    std::string string1, string2;
    int j1,j2;
    j1 = 0;
    j2 = 0;
    if (!file1 || !file2 )
    {
            std::cout << "Cannot open one of files " << f1<<" or "<<f2<<"\n";
            return EXIT_FAILURE;
    }
    std::cout <<"Run comparison"<< "\n";
    while((!file1.eof())&&(!file2.eof()))
    {
        for (;;) {
            j1++;
            if (!std::getline(file1,string1)) break;
            if (skip(string1)==0) break;
        }
        for (;;) {
            j2++;
            if (!std::getline(file2,string2)) break;
            if (skip(string2)==0) break;
        }
        if(string1.compare(string2) != 0)
        {
            std::cout << j1<<"/"<<j2 << "-th strings are not equal" << f1<<f2<<"\n";
            std::cout << "   ->" << string1 << "<-\n";
            std::cout << "   ->" << string2 << "<-\n";
            return EXIT_FAILURE;
        }
    }
    return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
    if (argc!=3&&argc!=4) {
        std::cout<<"Wrong number of arguments"<<std::endl;
        return EXIT_FAILURE;
    }
    int status=compare_text_files(argv[1],argv[2]);
    if (argc==4)  { if (strcmp(argv[3],"--always-success")==0)  return EXIT_SUCCESS; }
    return status;
}
<commit_msg>Ignore difference of the includes<commit_after>//
// Copyright (c) 2020 Andrii Verbytskyi <andrii.verbytskyi@mpp.mpg.de> for the binder project
//
// All rights reserved. Use of this source code is governed by a
// MIT license that can be found in the LICENSE file.
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <vector>
#include <string.h>

int skip(std::string const & s1)
{
    if (s1.length()==0) return 1;
    if (s1.length()>1)
    {
        size_t comment=s1.find_first_of("//");
        if (comment==s1.find_first_not_of(" \t")&&comment!=std::string::npos) return 2; //The comments should be ignored
    }
    if (s1.find("Source list file")!=std::string::npos) return 3;       //Same as the list of source files
    if (s1.find("Modules list file")!=std::string::npos) return 4;      //Same as the list of modules
    if (s1.find("File:")!=std::string::npos) return 5;                  //Same as the full file paths.
    if (s1.find("pybind11::handle cl_type = cl;")!=std::string::npos) return 6;  //This could be optimized in binder
    if (s1.find("__cxx11")!=std::string::npos) return 7;                         //This looks like implementation dependent
    if (s1.find("assign")!=std::string::npos) return 8;                          // The assing is binded differently for some reasons
    if (s1.find("#include")==std::string::npos) return 9;                        // Includes could differ
    return 0;
}
int compare_text_files(std::string const & f1,const std::string & f2)
{
    std::fstream file1(f1), file2(f2);
    std::string string1, string2;
    int j1,j2;
    j1 = 0;
    j2 = 0;
    if (!file1 || !file2 )
    {
            std::cout << "Cannot open one of files " << f1<<" or "<<f2<<"\n";
            return EXIT_FAILURE;
    }
    std::cout <<"Run comparison"<< "\n";
    while((!file1.eof())&&(!file2.eof()))
    {
        for (;;) {
            j1++;
            if (!std::getline(file1,string1)) break;
            if (skip(string1)==0) break;
        }
        for (;;) {
            j2++;
            if (!std::getline(file2,string2)) break;
            if (skip(string2)==0) break;
        }
        if(string1.compare(string2) != 0)
        {
            std::cout << j1<<"/"<<j2 << "-th strings are not equal" << f1<<" "<<f2<<"\n";
            std::cout << "   ->" << string1 << "<-\n";
            std::cout << "   ->" << string2 << "<-\n";
            return EXIT_FAILURE;
        }
    }
    return EXIT_SUCCESS;
}
int main(int argc, char** argv)
{
    if (argc!=3&&argc!=4) {
        std::cout<<"Wrong number of arguments"<<std::endl;
        return EXIT_FAILURE;
    }
    int status=compare_text_files(argv[1],argv[2]);
    if (argc==4)  { if (strcmp(argv[3],"--always-success")==0)  return EXIT_SUCCESS; }
    return status;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <chrono>
#include <assert.h>
#include <stdlib.h>
#include <chrono>
#include <typeinfo>
#include <vector>

#include "../sources/table.h"
#include "../sources/columnStoreTable.h"
#include "../sources/rowStoreTable.h"
#include "../sources/timer.h"

/**
* Returns numValues random Values from 1 - maxValues
*/
uint32_t *getRandomValuesInRange(int32_t numValues, int32_t maxValue)
{
    uint32_t *returnValues = new uint32_t[numValues];
    for (auto i = 0; i < numValues; ++i)
    {
        returnValues[i] = (uint32_t)(std::rand() % maxValue + 1);
    }
    return returnValues;
}

/**
* Returns a predefined selectivity. Selectivity is 0 to 1, representing a procentual value of distinct values. 0 means ther will be just one value
**/
uint32_t *getValuesWithSelectivity(int32_t numValues, int32_t maxValue, int32_t relativeSelectivity)
{
    uint32_t *returnValues = new uint32_t[numValues];
    for (auto i = 0; i < numValues; ++i)
    {
        if (relativeSelectivity == 0) {
            returnValues[i] = 1;
        } else {
            returnValues[i] = relativeSelectivity * maxValue;
        }
    }
    return returnValues;
}

int main(int argc, char const *argv[])
{
    std::cout << "Starting scan benchmark... " << std::endl;

    std::ofstream out("times_scan.csv");
    out << "rows,columns,relativeSelectivity,ns rowstore, ns columnstore" << std::endl;
    int32_t rows = 10000000;
    int32_t rounds = 20;

    for (int columns = 1; columns <= 128; columns *= 2)
    {
        for (int relativeSelectivity = 0; relativeSelectivity <= 1; relativeSelectivity += 0.2) {
            // start with relativeSelectivity = 0 (means onaly 1 distinct value in every row) and increase it 20% every round until 100% is reached

            std::cout << "Creating table with " << columns << " columns and a selectivity of " << relativeSelectivity << std::endl;

            // create tables
            auto row_table = RowStoreTable(rows, columns);
            auto column_table = ColumnStoreTable(rows, columns);

            // fill tables with same data
            // TODO: replace with data with known selectivity

            // auto randomValues = getRandomValuesInRange(columns, (rows / 500));

            auto distinctValues = getValuesWithSelectivity(columns, rows, 0.1);

             std::cout << "Distinct vlaues in col 0: " << distinctValues[0] << std::endl;

            row_table.generateData(rows, distinctValues);
            column_table.generateData(rows, distinctValues);
            delete[] distinctValues;
            auto column = columns/2;

            // scan tables
            // -> row
            auto comparison_value = row_table.getLocation(0, column); // TODO: replace with know value
            std::cout << "comparsion value is " << comparison_value << std::endl;
            auto start = std::chrono::high_resolution_clock::now();
            for (int32_t round = 0; round != rounds; ++round) {
                row_table.table_eq_scan(column, comparison_value);
                // (optional) clear caches
            }
            auto end = std::chrono::high_resolution_clock::now();
            auto scanTime_row = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() / rounds;

            // -> col
            comparison_value = column_table.getLocation(0, column); // TODO: replace with know value
            start = std::chrono::high_resolution_clock::now();
            for (int32_t round = 0; round != rounds; ++round) {
                column_table.table_eq_scan(column, comparison_value);
                // (optional) clear caches
            }
            end = std::chrono::high_resolution_clock::now();
            auto scanTime_col = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() / rounds;

            // output results
            out << rows << "," << columns << "," << relativeSelectivity << "," << scanTime_row << "," << scanTime_col << std::endl;
            std::cout << rows << "," << columns << "," << relativeSelectivity << "," << scanTime_row << "," << scanTime_col << std::endl;
        }
    }

}
<commit_msg>fix ints<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <chrono>
#include <assert.h>
#include <stdlib.h>
#include <chrono>
#include <typeinfo>
#include <vector>

#include "../sources/table.h"
#include "../sources/columnStoreTable.h"
#include "../sources/rowStoreTable.h"
#include "../sources/timer.h"

/**
* Returns numValues random Values from 1 - maxValues
*/
uint32_t *getRandomValuesInRange(int32_t numValues, int32_t maxValue)
{
    uint32_t *returnValues = new uint32_t[numValues];
    for (auto i = 0; i < numValues; ++i)
    {
        returnValues[i] = (uint32_t)(std::rand() % maxValue + 1);
    }
    return returnValues;
}

/**
* Returns a predefined selectivity. Selectivity is 0 to 100, representing a procentual value of distinct values. 0 means ther will be just one value
**/
uint32_t *getValuesWithSelectivity(int32_t numValues, int32_t maxValue, int32_t relativeSelectivity)
{
    uint32_t *returnValues = new uint32_t[numValues];
    for (auto i = 0; i < numValues; ++i)
    {
        if (relativeSelectivity == 0) {
            returnValues[i] = 1;
        } else {
            returnValues[i] = relativeSelectivity * maxValue / 100;
        }
    }
    return returnValues;
}

int main(int argc, char const *argv[])
{
    std::cout << "Starting scan benchmark... " << std::endl;

    std::ofstream out("times_scan.csv");
    out << "rows,columns,relativeSelectivity,ns rowstore, ns columnstore" << std::endl;
    int32_t rows = 10000000;
    int32_t rounds = 20;

    for (int columns = 1; columns <= 128; columns *= 2)
    {
        for (int relativeSelectivity = 0; relativeSelectivity <= 100; relativeSelectivity += 20) {
            // start with relativeSelectivity = 0 (means onaly 1 distinct value in every row) and increase it 20% every round until 100% is reached

            std::cout << "Creating table with " << columns << " columns and a selectivity of " << relativeSelectivity << "%" << std::endl;

            // create tables
            auto row_table = RowStoreTable(rows, columns);
            auto column_table = ColumnStoreTable(rows, columns);

            // fill tables with same data
            // TODO: replace with data with known selectivity

            // auto randomValues = getRandomValuesInRange(columns, (rows / 500));

            auto selectivityValues = getValuesWithSelectivity(columns, rows, relativeSelectivity);

            std::cout << "Distinct values in col 0: " << selectivityValues[0] << std::endl;

            row_table.generateData(rows, selectivityValues);
            column_table.generateData(rows, selectivityValues);
            delete[] selectivityValues;
            auto column = columns/2;

            // scan tables
            // -> row
            auto comparison_value = row_table.getLocation(0, column); // TODO: replace with know value
            std::cout << "comparsion value is " << comparison_value << std::endl;
            auto start = std::chrono::high_resolution_clock::now();
            for (int32_t round = 0; round != rounds; ++round) {
                row_table.table_eq_scan(column, comparison_value);
                // (optional) clear caches
            }
            auto end = std::chrono::high_resolution_clock::now();
            auto scanTime_row = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() / rounds;

            // -> col
            comparison_value = column_table.getLocation(0, column); // TODO: replace with know value
            start = std::chrono::high_resolution_clock::now();
            for (int32_t round = 0; round != rounds; ++round) {
                column_table.table_eq_scan(column, comparison_value);
                // (optional) clear caches
            }
            end = std::chrono::high_resolution_clock::now();
            auto scanTime_col = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() / rounds;

            // output results
            out << rows << "," << columns << "," << relativeSelectivity << "," << scanTime_row << "," << scanTime_col << std::endl;
            std::cout << rows << "," << columns << "," << relativeSelectivity << "," << scanTime_row << "," << scanTime_col << std::endl;
        }
    }

}
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#include <hpp/core/kinodynamic-distance.hh>
#include <limits>
#include <hpp/util/debug.hh>
#include <hpp/model/body.hh>
#include <hpp/model/device.hh>
#include <hpp/model/joint.hh>
#include <hpp/core/problem.hh>
#include <hpp/model/joint-configuration.hh>
#include <hpp/model/children-iterator.hh>
#include <hpp/model/configuration.hh>
#include <Eigen/SVD>

namespace hpp {
namespace core {

KinodynamicDistancePtr_t KinodynamicDistance::create (const DevicePtr_t& robot)
{
    KinodynamicDistance* ptr = new KinodynamicDistance (robot);
    KinodynamicDistancePtr_t shPtr (ptr);
    ptr->init (shPtr);
    return shPtr;
}

KinodynamicDistancePtr_t KinodynamicDistance::createFromProblem (const ProblemPtr_t& problem)
{
    KinodynamicDistance* ptr = new KinodynamicDistance (problem->robot());
    KinodynamicDistancePtr_t shPtr (ptr);
    ptr->init (shPtr);
    return shPtr;
}

KinodynamicDistancePtr_t KinodynamicDistance::createCopy
(const KinodynamicDistancePtr_t& distance)
{
    KinodynamicDistance* ptr = new KinodynamicDistance (*distance);
    KinodynamicDistancePtr_t shPtr (ptr);
    ptr->init (shPtr);
    return shPtr;
}

DistancePtr_t KinodynamicDistance::clone () const
{
    return createCopy (weak_.lock ());
}

KinodynamicDistance::KinodynamicDistance (const DevicePtr_t& robot) :
    robot_ (robot)
{
    if((2*(robot_->extraConfigSpace().dimension())) < robot_->configSize()){
        std::cout<<"Error : you need at least "<<robot_->configSize()-robot_->extraConfigSpace().dimension()<<" extra DOF"<<std::endl;
        hppDout(error,"Error : you need at least "<<robot_->configSize() - robot_->extraConfigSpace().dimension()<<" extra DOF");
    }
    aMax_ = 1;
    vMax_ = 2;
}

KinodynamicDistance::KinodynamicDistance (const KinodynamicDistance& distance) :
    robot_ (distance.robot_)
{
}

void KinodynamicDistance::init (KinodynamicDistanceWkPtr_t self)
{
    weak_ = self;
}

inline double sgnenum(double val) {
  return ((0. < val ) - (val < 0.));
}

inline int sgn(double d)  {
  return d >= 0.0 ? 1 : -1;
}

inline double sgnf(double d)  {
  return d >= 0.0 ? 1.0 : -1.0;
}

double KinodynamicDistance::computeMinTime(double p1, double p2, double v1, double v2) const{
  //hppDout(info,"p1 = "<<p1<<"  p2 = "<<p2<<"   ; v1 = "<<v1<<"    v2 = "<<v2);
  // compute the sign of each acceleration
  double t1,t2,tv;
  int sigma;
  double deltaPacc = 0.5*(v1+v2)*(fabs(v2-v1)/aMax_);
  sigma = sgn(p2-p1-deltaPacc);  //TODO bug sigma == 0, temp fix ?
  //hppDout(info,"sigma = "<<sigma);
  if(sigma == 0){ // ??? FIXME
    sigma = sgn(p2-p1);
    //hppDout(info,"sigma Bis= "<<sigma);
  }
  double a1 = (sigma)*aMax_;
  double a2 = -a1;
  double vLim = (sigma) * vMax_;
  //hppDout(info,"Vlim = "<<vLim<<"   ;  aMax = "<<aMax_);
  if((p2-p1) == 0. && (v2-v1)==0. ){
    //hppDout(notice,"No movement in this joints, abort.");
    return 0.;
  }
  // test if two segment trajectory is valid :
  bool twoSegment = false;

  // solve quadratic equation (cf eq 13 article)
  const double a = a1;
  const double b = 2. * v1;
  const double c = (0.5*(v1+v2)*(v2-v1)/a2) - (p2-p1);

  const double q = -0.5*(b+sgnf(b)*sqrt(b*b-4*a*c));
  //hppDout(info, "sign of "<<b<<" is : "<<sgnf(b));
  const double x1 = q/a;
  const double x2 = c/q;
  const double x = std::max(x1,x2);
  //hppDout(info,"Solve quadratic equation : x1 = "<<x1<<"  ; x2 = "<<x2);
  //hppDout(info," x = "<<x);
  //hppDout(info,"t1 before vel limit = "<<x);

  //hppDout(info,"inf bound on t1 (from t2 > 0) "<<-((v2-v1)/a2));
  double minT1 = std::max(0.,-((v2-v1)/a2));  //lower bound for valid t1 value (cf eq 14)

  if(x >= minT1){
    twoSegment = true;
    t1 = x;
    //hppDout(info,"t1 >= minT1");
  }
  if(twoSegment){ // check if max velocity is respected
    if(std::abs(v1+(t1)*a1) > vMax_){
      twoSegment = false;
      //hppDout(info,"Doesn't respect max velocity, need 3 segments");
    }
  }
  if(twoSegment){ // compute t2 for two segment trajectory
    tv = 0.;
    t2 = ((v2-v1)/a2) + (t1);// eq 14
  }else{// compute 3 segment trajectory, with constant velocity phase :
    t1 = (vLim - v1)/a1;  //eq 15
    tv = ((v1*v1+v2*v2 - 2*vLim*vLim)/(2*vLim*a1)) + (p2-p1)/vLim ; //eq 16
    t2 = (v2-vLim)/a2;  //eq 17
  }
  if(twoSegment){
    //hppDout(notice,"Trajectory with 2 segments");
  }else{
    //hppDout(notice,"Trajectory with 3 segments");
  }
  //hppDout(notice,"a1 = "<<a1<<"  ;  a2 ="<<a2);
  //hppDout(notice,"t = "<<(t1)<<"   ;   "<<(tv)<<"   ;   "<<(t2));
  double T = (t1)+(tv)+(t2);
  //hppDout(notice,"T = "<<T);
  return T;
}

value_type KinodynamicDistance::impl_distance (ConfigurationIn_t q1,
                                               ConfigurationIn_t q2) const
{
    double Tmax = 0;
    double T = 0;

    size_type configSize = robot_->configSize() - robot_->extraConfigSpace().dimension ();
    // looking for Tmax
    //hppDout(notice,"KinodynamicDistance :  Looking for Tmax :");
   // hppDout(info,"Distance between : "<<model::displayConfig(q1));
    //hppDout(info,"and              : "<<model::displayConfig(q2));

    for(int indexConfig = 0 ; indexConfig < 3 ; indexConfig++){// FIX ME : only work with freeflyer
        size_type indexVel = indexConfig + configSize;
        //hppDout(notice,"For joint :"<<robot_->getJointAtConfigRank(indexConfig)->name());
        if(robot_->getJointAtConfigRank(indexConfig)->name() != "base_joint_SO3"){
            T = computeMinTime(q1[indexConfig],q2[indexConfig],q1[indexVel],q2[indexVel]);
            if(T > Tmax)
                Tmax = T;
        }else{
            //hppDout(notice,"!! Kinodynamic distance for quaternion not implemented yet.");
        }

    }
   // hppDout(info," is : "<<Tmax);
    return Tmax;
}
} //   namespace core
} // namespace hpp
<commit_msg>small cleaning in kindoynamicDistance<commit_after>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core 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 Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#include <hpp/core/kinodynamic-distance.hh>
#include <limits>
#include <hpp/util/debug.hh>
#include <hpp/model/body.hh>
#include <hpp/model/device.hh>
#include <hpp/model/joint.hh>
#include <hpp/core/problem.hh>
#include <hpp/model/joint-configuration.hh>
#include <hpp/model/children-iterator.hh>
#include <hpp/model/configuration.hh>
#include <Eigen/SVD>

namespace hpp {
namespace core {

KinodynamicDistancePtr_t KinodynamicDistance::create (const DevicePtr_t& robot)
{
    KinodynamicDistance* ptr = new KinodynamicDistance (robot);
    KinodynamicDistancePtr_t shPtr (ptr);
    ptr->init (shPtr);
    return shPtr;
}

KinodynamicDistancePtr_t KinodynamicDistance::createFromProblem (const ProblemPtr_t& problem)
{
    KinodynamicDistance* ptr = new KinodynamicDistance (problem->robot());
    KinodynamicDistancePtr_t shPtr (ptr);
    ptr->init (shPtr);
    return shPtr;
}

KinodynamicDistancePtr_t KinodynamicDistance::createCopy
(const KinodynamicDistancePtr_t& distance)
{
    KinodynamicDistance* ptr = new KinodynamicDistance (*distance);
    KinodynamicDistancePtr_t shPtr (ptr);
    ptr->init (shPtr);
    return shPtr;
}

DistancePtr_t KinodynamicDistance::clone () const
{
    return createCopy (weak_.lock ());
}

KinodynamicDistance::KinodynamicDistance (const DevicePtr_t& robot) :
    robot_ (robot)
{
    if((2*(robot_->extraConfigSpace().dimension())) < robot_->configSize()){
        std::cout<<"Error : you need at least "<<robot_->configSize()-robot_->extraConfigSpace().dimension()<<" extra DOF"<<std::endl;
        hppDout(error,"Error : you need at least "<<robot_->configSize() - robot_->extraConfigSpace().dimension()<<" extra DOF");
    }
    aMax_ = 1;
    vMax_ = 2;
}

KinodynamicDistance::KinodynamicDistance (const KinodynamicDistance& distance) :
    robot_ (distance.robot_)
{
}

void KinodynamicDistance::init (KinodynamicDistanceWkPtr_t self)
{
    weak_ = self;
}

inline double sgnenum(double val) {
  return ((0. < val ) - (val < 0.));
}

inline int sgn(double d)  {
  return d >= 0.0 ? 1 : -1;
}

inline double sgnf(double d)  {
  return d >= 0.0 ? 1.0 : -1.0;
}

double KinodynamicDistance::computeMinTime(double p1, double p2, double v1, double v2) const{
  //hppDout(info,"p1 = "<<p1<<"  p2 = "<<p2<<"   ; v1 = "<<v1<<"    v2 = "<<v2);
  // compute the sign of each acceleration
  double t1,t2,tv;
  int sigma;
  double deltaPacc = 0.5*(v1+v2)*(fabs(v2-v1)/aMax_);
  sigma = sgn(p2-p1-deltaPacc);  //TODO bug sigma == 0, temp fix ?
  //hppDout(info,"sigma = "<<sigma);
  if(sigma == 0){ // ??? FIXME
    sigma = sgn(p2-p1);
    //hppDout(info,"sigma Bis= "<<sigma);
  }
  double a1 = (sigma)*aMax_;
  double a2 = -a1;
  double vLim = (sigma) * vMax_;
  //hppDout(info,"Vlim = "<<vLim<<"   ;  aMax = "<<aMax_);
  if((p2-p1) == 0. && (v2-v1)==0. ){
    //hppDout(notice,"No movement in this joints, abort.");
    return 0.;
  }
  // test if two segment trajectory is valid :
  bool twoSegment = false;

  // solve quadratic equation (cf eq 13 article)
  const double a = a1;
  const double b = 2. * v1;
  const double c = (0.5*(v1+v2)*(v2-v1)/a2) - (p2-p1);

  const double q = -0.5*(b+sgnf(b)*sqrt(b*b-4*a*c));
  //hppDout(info, "sign of "<<b<<" is : "<<sgnf(b));
  const double x1 = q/a;
  const double x2 = c/q;
  const double x = std::max(x1,x2);
  //hppDout(info,"Solve quadratic equation : x1 = "<<x1<<"  ; x2 = "<<x2);
  //hppDout(info," x = "<<x);
  //hppDout(info,"t1 before vel limit = "<<x);

  //hppDout(info,"inf bound on t1 (from t2 > 0) "<<-((v2-v1)/a2));
  double minT1 = std::max(0.,-((v2-v1)/a2));  //lower bound for valid t1 value (cf eq 14)

  if(x >= minT1){
    twoSegment = true;
    t1 = x;
    //hppDout(info,"t1 >= minT1");
  }
  if(twoSegment){ // check if max velocity is respected
    if(std::abs(v1+(t1)*a1) > vMax_){
      twoSegment = false;
      //hppDout(info,"Doesn't respect max velocity, need 3 segments");
    }
  }
  if(twoSegment){ // compute t2 for two segment trajectory
    tv = 0.;
    t2 = ((v2-v1)/a2) + (t1);// eq 14
  }else{// compute 3 segment trajectory, with constant velocity phase :
    t1 = (vLim - v1)/a1;  //eq 15
    tv = ((v1*v1+v2*v2 - 2*vLim*vLim)/(2*vLim*a1)) + (p2-p1)/vLim ; //eq 16
    t2 = (v2-vLim)/a2;  //eq 17
  }
  /*
  if(twoSegment){
    hppDout(notice,"Trajectory with 2 segments");
  }else{
    hppDout(notice,"Trajectory with 3 segments");
  }
  */
  //hppDout(notice,"a1 = "<<a1<<"  ;  a2 ="<<a2);
  //hppDout(notice,"t = "<<(t1)<<"   ;   "<<(tv)<<"   ;   "<<(t2));
  //double T = (t1)+(tv)+(t2);
  //hppDout(notice,"T = "<<T);
  return (t1)+(tv)+(t2);
}

value_type KinodynamicDistance::impl_distance (ConfigurationIn_t q1,
                                               ConfigurationIn_t q2) const
{
    double Tmax = 0;
    double T = 0;

    size_type configSize = robot_->configSize() - robot_->extraConfigSpace().dimension ();
    // looking for Tmax
    //hppDout(notice,"KinodynamicDistance :  Looking for Tmax :");
   // hppDout(info,"Distance between : "<<model::displayConfig(q1));
    //hppDout(info,"and              : "<<model::displayConfig(q2));

    for(int indexConfig = 0 ; indexConfig < 3 ; indexConfig++){// FIX ME : only work with freeflyer
        //hppDout(notice,"For joint :"<<robot_->getJointAtConfigRank(indexConfig)->name());
        //if(robot_->getJointAtConfigRank(indexConfig)->name() != "base_joint_SO3" true){
            T = computeMinTime(q1[indexConfig],q2[indexConfig],q1[indexConfig + configSize],q2[indexConfig + configSize]);
            if(T > Tmax)
                Tmax = T;
        /*}else{
            hppDout(notice,"!! Kinodynamic distance for quaternion not implemented yet.");
        }*/

    }
   // hppDout(info," is : "<<Tmax);
    return Tmax;
}
} //   namespace core
} // namespace hpp
<|endoftext|>


<commit_before>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow_lite_support/cc/task/processor/image_preprocessor.h"

#include "tensorflow_lite_support/cc/port/status_macros.h"
#include "tensorflow_lite_support/cc/task/core/task_utils.h"
#include "tensorflow_lite_support/cc/task/vision/proto/bounding_box_proto_inc.h"
#include "tensorflow_lite_support/cc/task/vision/utils/frame_buffer_utils.h"
#include "tensorflow_lite_support/cc/task/vision/utils/image_tensor_specs.h"

namespace tflite {
namespace task {
namespace processor {

namespace {
// Number of bytes required for 8-bit per pixel RGB color space.
static constexpr int kRgbPixelBytes = 3;

using ::tflite::task::vision::BoundingBox;
using ::tflite::task::vision::FrameBuffer;
}  // namespace

// Returns false if image preprocessing could be skipped, true otherwise.
bool ImagePreprocessor::IsImagePreprocessingNeeded(
    const FrameBuffer& frame_buffer, const BoundingBox& roi) {
  // Is crop required?
  if (roi.origin_x() != 0 || roi.origin_y() != 0 ||
      roi.width() != frame_buffer.dimension().width ||
      roi.height() != frame_buffer.dimension().height) {
    return true;
  }

  // Are image transformations required?
  if (frame_buffer.orientation() != FrameBuffer::Orientation::kTopLeft ||
      frame_buffer.format() != FrameBuffer::Format::kRGB ||
      frame_buffer.dimension().width != input_specs_.image_width ||
      frame_buffer.dimension().height != input_specs_.image_height) {
    return true;
  }

  return false;
}

// Returns true if the model expects dynamic image shape, false otherwise.
bool ImagePreprocessor::IsInputImageDynamic()
{
  // Determine if the input shape is resizable.
  const TfLiteIntArray* dims_signature = Tensor()->dims_signature;

  if (dims_signature == nullptr) return false;

  bool height_or_width_mutable = dims_signature->data[1] == -1 ||
                                 dims_signature->data[2] == -1;
  // Only the HXW dimensions support mutability.
  bool batch_and_color_fixed = dims_signature->data[0] != -1 &&
                               dims_signature->data[3] != -1;

  if (height_or_width_mutable && batch_and_color_fixed) return true;

  return false;
}

absl::Status ImagePreprocessor::Init(
    const vision::FrameBufferUtils::ProcessEngine& process_engine) {
  frame_buffer_utils_ = vision::FrameBufferUtils::Create(process_engine);

  ASSIGN_OR_RETURN(input_specs_, vision::BuildInputImageTensorSpecs(
                                     *engine_->interpreter(),
                                     *engine_->metadata_extractor()));

  if (input_specs_.color_space != tflite::ColorSpaceType_RGB) {
    return tflite::support::CreateStatusWithPayload(
        absl::StatusCode::kUnimplemented,
        "ImagePreprocessor only supports RGB color space for now.");
  }

  return absl::OkStatus();
}

absl::Status ImagePreprocessor::Preprocess(const FrameBuffer& frame_buffer) {
  BoundingBox roi;
  roi.set_width(frame_buffer.dimension().width);
  roi.set_height(frame_buffer.dimension().height);
  return Preprocess(frame_buffer, roi);
}

absl::Status ImagePreprocessor::Preprocess(const FrameBuffer& frame_buffer,
                                           const BoundingBox& roi) {
  // Input data to be normalized (if needed) and used for inference. In most
  // cases, this is the result of image preprocessing. In case no image
  // preprocessing is needed (see below), this points to the input frame
  // buffer raw data.
  const uint8* input_data;
  size_t input_data_byte_size;

  // Optional buffers in case image preprocessing is needed.
  std::unique_ptr<FrameBuffer> preprocessed_frame_buffer;
  std::vector<uint8> preprocessed_data;

  if (IsImagePreprocessingNeeded(frame_buffer, roi) && !IsInputImageDynamic()) {
    // Preprocess input image to fit model requirements.
    // For now RGB is the only color space supported, which is ensured by
    // `InitInternal`.
    FrameBuffer::Dimension to_buffer_dimension = {input_specs_.image_width,
                                                  input_specs_.image_height};
    input_data_byte_size =
        GetBufferByteSize(to_buffer_dimension, FrameBuffer::Format::kRGB);
    preprocessed_data.resize(input_data_byte_size / sizeof(uint8), 0);
    input_data = preprocessed_data.data();

    FrameBuffer::Plane preprocessed_plane = {
        /*buffer=*/preprocessed_data.data(),
        /*stride=*/{input_specs_.image_width * kRgbPixelBytes, kRgbPixelBytes}};
    preprocessed_frame_buffer = FrameBuffer::Create(
        {preprocessed_plane}, to_buffer_dimension, FrameBuffer::Format::kRGB,
        FrameBuffer::Orientation::kTopLeft);

    RETURN_IF_ERROR(frame_buffer_utils_->Preprocess(
        frame_buffer, roi, preprocessed_frame_buffer.get()));
  } else {
    // Input frame buffer already targets model requirements: skip image
    // preprocessing. For RGB, the data is always stored in a single plane.

    // If dynamic, it will re-dim the entire graph as per the input.
    if (IsInputImageDynamic()) {
      // Determine if the input shape is resizable.
      const TfLiteIntArray* dims_signature = Tensor()->dims_signature;

      const bool height_mutable = dims_signature->data[1] == -1;
      const bool width_mutable = dims_signature->data[2] == -1;

      if (height_mutable || width_mutable) {
        const TfLiteIntArray* dims = Tensor()->dims;
        const Interpreter* interpreter = engine_->interpreter();

        // The expected BXHXWXD values of the model.
        const int expected_batch = Tensor()->dims->data[0];
        int expected_height = Tensor()->dims->data[1];
        int expected_width = Tensor()->dims->data[2];
        const int expected_depth = Tensor()->dims->data[3];

        // HXW of the input image.
        int image_height = frame_buffer.dimension().height;
        int image_width = frame_buffer.dimension().width;

        int height = height_mutable ? image_height : expected_height;
        int width = width_mutable ? image_width : expected_width;

        const std::vector<int> new_dims {expected_batch, height, width, expected_depth};

        interpreter->ResizeInputTensorStrict(0, new_dims);
      }
    }

    input_data = frame_buffer.plane(0).buffer;
    input_data_byte_size = frame_buffer.plane(0).stride.row_stride_bytes *
                           frame_buffer.dimension().height;
  }

  // Then normalize pixel data (if needed) and populate the input tensor.
  switch (input_specs_.tensor_type) {
    case kTfLiteUInt8:
      if (Tensor()->bytes != input_data_byte_size) {
        return tflite::support::CreateStatusWithPayload(
            absl::StatusCode::kInternal,
            "Size mismatch or unsupported padding bytes between pixel data "
            "and input tensor.");
      }
      // No normalization required: directly populate data.
      tflite::task::core::PopulateTensor(
          input_data, input_data_byte_size / sizeof(uint8), Tensor());
      break;
    case kTfLiteFloat32: {
      if (Tensor()->bytes / sizeof(float) !=
          input_data_byte_size / sizeof(uint8)) {
        return tflite::support::CreateStatusWithPayload(
            absl::StatusCode::kInternal,
            "Size mismatch or unsupported padding bytes between pixel data "
            "and input tensor.");
      }
      // Normalize and populate.
      float* normalized_input_data =
          tflite::task::core::AssertAndReturnTypedTensor<float>(Tensor());
      const tflite::task::vision::NormalizationOptions& normalization_options =
          input_specs_.normalization_options.value();
      for (int i = 0; i < normalization_options.num_values; i++) {
        if (std::abs(normalization_options.std_values[i]) <
            std::numeric_limits<float>::epsilon()) {
          return tflite::support::CreateStatusWithPayload(
              absl::StatusCode::kInternal,
              "NormalizationOptions.std_values can't be 0. Please check if the "
              "tensor metadata has been populated correctly.");
        }
      }
      if (normalization_options.num_values == 1) {
        float mean_value = normalization_options.mean_values[0];
        float inv_std_value = (1.0f / normalization_options.std_values[0]);
        for (size_t i = 0; i < input_data_byte_size / sizeof(uint8);
             i++, input_data++, normalized_input_data++) {
          *normalized_input_data =
              inv_std_value * (static_cast<float>(*input_data) - mean_value);
        }
      } else {
        std::array<float, 3> inv_std_values = {
            1.0f / normalization_options.std_values[0],
            1.0f / normalization_options.std_values[1],
            1.0f / normalization_options.std_values[2]};
        for (size_t i = 0; i < input_data_byte_size / sizeof(uint8);
             i++, input_data++, normalized_input_data++) {
          *normalized_input_data = inv_std_values[i % 3] *
                                   (static_cast<float>(*input_data) -
                                    normalization_options.mean_values[i % 3]);
        }
      }
      break;
    }
    case kTfLiteInt8:
      return tflite::support::CreateStatusWithPayload(
          absl::StatusCode::kUnimplemented,
          "kTfLiteInt8 input type is not implemented yet.");
    default:
      return tflite::support::CreateStatusWithPayload(
          absl::StatusCode::kInternal, "Unexpected input tensor type.");
  }

  return absl::OkStatus();
}

}  // namespace processor
}  // namespace task
}  // namespace tflite
<commit_msg>redundant space<commit_after>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

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

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

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

#include "tensorflow_lite_support/cc/task/processor/image_preprocessor.h"

#include "tensorflow_lite_support/cc/port/status_macros.h"
#include "tensorflow_lite_support/cc/task/core/task_utils.h"
#include "tensorflow_lite_support/cc/task/vision/proto/bounding_box_proto_inc.h"
#include "tensorflow_lite_support/cc/task/vision/utils/frame_buffer_utils.h"
#include "tensorflow_lite_support/cc/task/vision/utils/image_tensor_specs.h"

namespace tflite {
namespace task {
namespace processor {

namespace {
// Number of bytes required for 8-bit per pixel RGB color space.
static constexpr int kRgbPixelBytes = 3;

using ::tflite::task::vision::BoundingBox;
using ::tflite::task::vision::FrameBuffer;
}  // namespace

// Returns false if image preprocessing could be skipped, true otherwise.
bool ImagePreprocessor::IsImagePreprocessingNeeded(
    const FrameBuffer& frame_buffer, const BoundingBox& roi) {
  // Is crop required?
  if (roi.origin_x() != 0 || roi.origin_y() != 0 ||
      roi.width() != frame_buffer.dimension().width ||
      roi.height() != frame_buffer.dimension().height) {
    return true;
  }

  // Are image transformations required?
  if (frame_buffer.orientation() != FrameBuffer::Orientation::kTopLeft ||
      frame_buffer.format() != FrameBuffer::Format::kRGB ||
      frame_buffer.dimension().width != input_specs_.image_width ||
      frame_buffer.dimension().height != input_specs_.image_height) {
    return true;
  }

  return false;
}

// Returns true if the model expects dynamic image shape, false otherwise.
bool ImagePreprocessor::IsInputImageDynamic()
{
  // Determine if the input shape is resizable.
  const TfLiteIntArray* dims_signature = Tensor()->dims_signature;

  if (dims_signature == nullptr) return false;

  bool height_or_width_mutable = dims_signature->data[1] == -1 ||
                                 dims_signature->data[2] == -1;
  // Only the HXW dimensions support mutability.
  bool batch_and_color_fixed = dims_signature->data[0] != -1 &&
                               dims_signature->data[3] != -1;

  if (height_or_width_mutable && batch_and_color_fixed) return true;

  return false;
}

absl::Status ImagePreprocessor::Init(
    const vision::FrameBufferUtils::ProcessEngine& process_engine) {
  frame_buffer_utils_ = vision::FrameBufferUtils::Create(process_engine);

  ASSIGN_OR_RETURN(input_specs_, vision::BuildInputImageTensorSpecs(
                                     *engine_->interpreter(),
                                     *engine_->metadata_extractor()));

  if (input_specs_.color_space != tflite::ColorSpaceType_RGB) {
    return tflite::support::CreateStatusWithPayload(
        absl::StatusCode::kUnimplemented,
        "ImagePreprocessor only supports RGB color space for now.");
  }

  return absl::OkStatus();
}

absl::Status ImagePreprocessor::Preprocess(const FrameBuffer& frame_buffer) {
  BoundingBox roi;
  roi.set_width(frame_buffer.dimension().width);
  roi.set_height(frame_buffer.dimension().height);
  return Preprocess(frame_buffer, roi);
}

absl::Status ImagePreprocessor::Preprocess(const FrameBuffer& frame_buffer,
                                           const BoundingBox& roi) {
  // Input data to be normalized (if needed) and used for inference. In most
  // cases, this is the result of image preprocessing. In case no image
  // preprocessing is needed (see below), this points to the input frame
  // buffer raw data.
  const uint8* input_data;
  size_t input_data_byte_size;

  // Optional buffers in case image preprocessing is needed.
  std::unique_ptr<FrameBuffer> preprocessed_frame_buffer;
  std::vector<uint8> preprocessed_data;

  if (IsImagePreprocessingNeeded(frame_buffer, roi) && !IsInputImageDynamic()) {
    // Preprocess input image to fit model requirements.
    // For now RGB is the only color space supported, which is ensured by
    // `InitInternal`.
    FrameBuffer::Dimension to_buffer_dimension = {input_specs_.image_width,
                                                  input_specs_.image_height};
    input_data_byte_size =
        GetBufferByteSize(to_buffer_dimension, FrameBuffer::Format::kRGB);
    preprocessed_data.resize(input_data_byte_size / sizeof(uint8), 0);
    input_data = preprocessed_data.data();

    FrameBuffer::Plane preprocessed_plane = {
        /*buffer=*/preprocessed_data.data(),
        /*stride=*/{input_specs_.image_width * kRgbPixelBytes, kRgbPixelBytes}};
    preprocessed_frame_buffer = FrameBuffer::Create(
        {preprocessed_plane}, to_buffer_dimension, FrameBuffer::Format::kRGB,
        FrameBuffer::Orientation::kTopLeft);

    RETURN_IF_ERROR(frame_buffer_utils_->Preprocess(
        frame_buffer, roi, preprocessed_frame_buffer.get()));
  } else {
    // Input frame buffer already targets model requirements: skip image
    // preprocessing. For RGB, the data is always stored in a single plane.

    // If dynamic, it will re-dim the entire graph as per the input.
    if (IsInputImageDynamic()) {
      // Determine if the input shape is resizable.
      const TfLiteIntArray* dims_signature = Tensor()->dims_signature;

      const bool height_mutable = dims_signature->data[1] == -1;
      const bool width_mutable = dims_signature->data[2] == -1;

      if (height_mutable || width_mutable) {
        const TfLiteIntArray* dims = Tensor()->dims;
        const Interpreter* interpreter = engine_->interpreter();

        // The expected BXHXWXD values of the model.
        const int expected_batch = Tensor()->dims->data[0];
        int expected_height = Tensor()->dims->data[1];
        int expected_width = Tensor()->dims->data[2];
        const int expected_depth = Tensor()->dims->data[3];

        // HXW of the input image.
        int image_height = frame_buffer.dimension().height;
        int image_width = frame_buffer.dimension().width;

        int height = height_mutable ? image_height : expected_height;
        int width = width_mutable ? image_width : expected_width;

        const std::vector<int> new_dims {expected_batch, height, width, expected_depth};

        interpreter->ResizeInputTensorStrict(0, new_dims);
      }
    }

    input_data = frame_buffer.plane(0).buffer;
    input_data_byte_size = frame_buffer.plane(0).stride.row_stride_bytes *
                           frame_buffer.dimension().height;
  }

  // Then normalize pixel data (if needed) and populate the input tensor.
  switch (input_specs_.tensor_type) {
    case kTfLiteUInt8:
      if (Tensor()->bytes != input_data_byte_size) {
        return tflite::support::CreateStatusWithPayload(
            absl::StatusCode::kInternal,
            "Size mismatch or unsupported padding bytes between pixel data "
            "and input tensor.");
      }
      // No normalization required: directly populate data.
      tflite::task::core::PopulateTensor(
          input_data, input_data_byte_size / sizeof(uint8), Tensor());
      break;
    case kTfLiteFloat32: {
      if (Tensor()->bytes / sizeof(float) !=
          input_data_byte_size / sizeof(uint8)) {
        return tflite::support::CreateStatusWithPayload(
            absl::StatusCode::kInternal,
            "Size mismatch or unsupported padding bytes between pixel data "
            "and input tensor.");
      }
      // Normalize and populate.
      float* normalized_input_data =
          tflite::task::core::AssertAndReturnTypedTensor<float>(Tensor());
      const tflite::task::vision::NormalizationOptions& normalization_options =
          input_specs_.normalization_options.value();
      for (int i = 0; i < normalization_options.num_values; i++) {
        if (std::abs(normalization_options.std_values[i]) <
            std::numeric_limits<float>::epsilon()) {
          return tflite::support::CreateStatusWithPayload(
              absl::StatusCode::kInternal,
              "NormalizationOptions.std_values can't be 0. Please check if the "
              "tensor metadata has been populated correctly.");
        }
      }
      if (normalization_options.num_values == 1) {
        float mean_value = normalization_options.mean_values[0];
        float inv_std_value = (1.0f / normalization_options.std_values[0]);
        for (size_t i = 0; i < input_data_byte_size / sizeof(uint8);
             i++, input_data++, normalized_input_data++) {
          *normalized_input_data =
              inv_std_value * (static_cast<float>(*input_data) - mean_value);
        }
      } else {
        std::array<float, 3> inv_std_values = {
            1.0f / normalization_options.std_values[0],
            1.0f / normalization_options.std_values[1],
            1.0f / normalization_options.std_values[2]};
        for (size_t i = 0; i < input_data_byte_size / sizeof(uint8);
             i++, input_data++, normalized_input_data++) {
          *normalized_input_data = inv_std_values[i % 3] *
                                   (static_cast<float>(*input_data) -
                                    normalization_options.mean_values[i % 3]);
        }
      }
      break;
    }
    case kTfLiteInt8:
      return tflite::support::CreateStatusWithPayload(
          absl::StatusCode::kUnimplemented,
          "kTfLiteInt8 input type is not implemented yet.");
    default:
      return tflite::support::CreateStatusWithPayload(
          absl::StatusCode::kInternal, "Unexpected input tensor type.");
  }

  return absl::OkStatus();
}

}  // namespace processor
}  // namespace task
}  // namespace tflite
<|endoftext|>


<commit_before>#include "builtin/class.hpp"
#include "builtin/object.hpp"
#include "builtin/stat.hpp"
#include "builtin/string.hpp"
#include "builtin/time.hpp"
#include "ontology.hpp"

namespace rubinius {
  void Stat::init(STATE) {
    GO(stat_class).set(ontology::new_class(state, "Stat", G(object), G(rubinius)));
    G(stat_class)->set_object_type(state, StatType);
  }

  Fixnum* Stat::stat(STATE, String* p) {
    path(state, p);
    return Fixnum::from(::stat(p->c_str_null_safe(state), &st_));
  }

  Fixnum* Stat::fstat(STATE, Integer* fd) {
    return Fixnum::from(::fstat(fd->to_native(), &st_));
  }

  Fixnum* Stat::lstat(STATE, String* p) {
    path(state, p);
    return Fixnum::from(::lstat(p->c_str_null_safe(state), &st_));
  }

  Integer* Stat::stat_dev(STATE) {
    return Integer::from(state, st_.st_dev);
  }

  Integer* Stat::stat_ino(STATE) {
    return Integer::from(state, st_.st_ino);
  }

  Integer* Stat::stat_mode(STATE) {
    return Integer::from(state, st_.st_mode);
  }

  Integer* Stat::stat_nlink(STATE) {
    return Integer::from(state, st_.st_nlink);
  }

  Integer* Stat::stat_uid(STATE) {
    return Integer::from(state, st_.st_uid);
  }

  Integer* Stat::stat_gid(STATE) {
    return Integer::from(state, st_.st_gid);
  }

  Integer* Stat::stat_rdev(STATE) {
    return Integer::from(state, st_.st_rdev);
  }

  Integer* Stat::stat_size(STATE) {
    return Integer::from(state, st_.st_size);
  }

  Integer* Stat::stat_blksize(STATE) {
    return Integer::from(state, st_.st_blksize);
  }

  Integer* Stat::stat_blocks(STATE) {
    return Integer::from(state, st_.st_blocks);
  }

  Time* Stat::stat_atime(STATE) {
    return Time::at(state, st_.st_atime);
  }

  Time* Stat::stat_mtime(STATE) {
    return Time::at(state, st_.st_mtime);
  }

  Time* Stat::stat_ctime(STATE) {
    return Time::at(state, st_.st_ctime);
  }

  Object* Stat::stat_birthtime(STATE) {
    #ifdef HAVE_ST_BIRTHTIME
      return Time::at(state, st_.st_birthtimespec);
    #else
      return Primitives::failure();
    #endif
  }

}

<commit_msg>Fix Stat::stat_birthtime.<commit_after>#include "builtin/class.hpp"
#include "builtin/object.hpp"
#include "builtin/stat.hpp"
#include "builtin/string.hpp"
#include "builtin/time.hpp"
#include "ontology.hpp"

namespace rubinius {
  void Stat::init(STATE) {
    GO(stat_class).set(ontology::new_class(state, "Stat", G(object), G(rubinius)));
    G(stat_class)->set_object_type(state, StatType);
  }

  Fixnum* Stat::stat(STATE, String* p) {
    path(state, p);
    return Fixnum::from(::stat(p->c_str_null_safe(state), &st_));
  }

  Fixnum* Stat::fstat(STATE, Integer* fd) {
    return Fixnum::from(::fstat(fd->to_native(), &st_));
  }

  Fixnum* Stat::lstat(STATE, String* p) {
    path(state, p);
    return Fixnum::from(::lstat(p->c_str_null_safe(state), &st_));
  }

  Integer* Stat::stat_dev(STATE) {
    return Integer::from(state, st_.st_dev);
  }

  Integer* Stat::stat_ino(STATE) {
    return Integer::from(state, st_.st_ino);
  }

  Integer* Stat::stat_mode(STATE) {
    return Integer::from(state, st_.st_mode);
  }

  Integer* Stat::stat_nlink(STATE) {
    return Integer::from(state, st_.st_nlink);
  }

  Integer* Stat::stat_uid(STATE) {
    return Integer::from(state, st_.st_uid);
  }

  Integer* Stat::stat_gid(STATE) {
    return Integer::from(state, st_.st_gid);
  }

  Integer* Stat::stat_rdev(STATE) {
    return Integer::from(state, st_.st_rdev);
  }

  Integer* Stat::stat_size(STATE) {
    return Integer::from(state, st_.st_size);
  }

  Integer* Stat::stat_blksize(STATE) {
    return Integer::from(state, st_.st_blksize);
  }

  Integer* Stat::stat_blocks(STATE) {
    return Integer::from(state, st_.st_blocks);
  }

  Time* Stat::stat_atime(STATE) {
    return Time::at(state, st_.st_atime);
  }

  Time* Stat::stat_mtime(STATE) {
    return Time::at(state, st_.st_mtime);
  }

  Time* Stat::stat_ctime(STATE) {
    return Time::at(state, st_.st_ctime);
  }

  Object* Stat::stat_birthtime(STATE) {
    #ifdef HAVE_ST_BIRTHTIME
      struct timespec ts = st_.st_birthtimespec;
      return Time::at(state, ts.tv_sec, ts.tv_nsec);
    #else
      return Primitives::failure();
    #endif
  }

}

<|endoftext|>


<commit_before>/*
  This file is part of KOrganizer.

  Copyright (c) 2004 Till Adam <adam@kde.org>
  Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
  Copyright (c) 2008 Thomas Thrainer <tom_t@gmx.at>

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

  This program 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 this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kotodoviewquicksearch.h"
#include "koprefs.h"

#include <libkdepim/categoryhierarchyreader.h>

#include <kcal/calendar.h>
#include <kcal/calfilter.h>

#include "kcheckcombobox.h"
#include <KLineEdit>

#include <QString>
#include <QStringList>
#include <QModelIndex>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QAbstractItemView>
#include <QHBoxLayout>

using namespace KCal;
using namespace KPIM;

KOTodoViewQuickSearch::KOTodoViewQuickSearch( Calendar *calendar, QWidget *parent )
  : QWidget( parent ), mCalendar( calendar )
{
  QHBoxLayout *layout = new QHBoxLayout( this );
  // no special margin because it is added by the view
  layout->setContentsMargins( 0, 0, 0, 0 );

  mSearchLine = new KLineEdit( this );
  mSearchLine->setClickMessage( i18nc( "@label in QuickSearchLine", "Search" ) );
  mSearchLine->setClearButtonShown( true );
  connect( mSearchLine, SIGNAL(textChanged(const QString &)),
           this, SIGNAL(searchTextChanged(const QString &)) );

  layout->addWidget( mSearchLine, 3 );

  mCategoryCombo = new KCheckComboBox( this );
  mCategoryCombo->setDefaultText( i18nc( "@item:inlistbox", "Select Categories" ) );
  mCategoryCombo->setSeparator( i18nc( "@info delimiter for joining category names", "," ) );

  connect( mCategoryCombo, SIGNAL(checkedItemsChanged(const QStringList &)),
           this, SIGNAL(searchCategoryChanged(const QStringList &)) );

  layout->addWidget( mCategoryCombo, 1 );
  fillCategories();

  setLayout( layout );
}

void KOTodoViewQuickSearch::setCalendar( Calendar *calendar )
{
  mCalendar = calendar;
  fillCategories();
}

void KOTodoViewQuickSearch::updateCategories()
{
  fillCategories();
}

void KOTodoViewQuickSearch::reset()
{
  mSearchLine->clear();
  mCategoryCombo->setCurrentIndex( 0 );
}

void KOTodoViewQuickSearch::fillCategories()
{
  QStringList currentCategories = mCategoryCombo->checkedItems();
  mCategoryCombo->clear();

  QStringList categories;

  if ( mCalendar ) {
    CalFilter *filter = mCalendar->filter();
    if ( filter->criteria() & CalFilter::ShowCategories ) {
      categories = filter->categoryList();
      categories.sort();
    } else {
      categories = KOPrefs::instance()->mCustomCategories;
      QStringList filterCategories = filter->categoryList();
      categories.sort();
      filterCategories.sort();

      QStringList::Iterator it = categories.begin();
      QStringList::Iterator jt = filterCategories.begin();
      while ( it != categories.end() && jt != filterCategories.end() ) {
        if ( *it == *jt ) {
          it = categories.erase( it );
          jt++;
        } else if ( *it < *jt ) {
          it++;
        } else if ( *it > *jt ) {
          jt++;
        }
      }
    }
  }

  CategoryHierarchyReaderQComboBox( mCategoryCombo ).read( categories );

  QStandardItemModel *model =
      qobject_cast<QStandardItemModel *>( mCategoryCombo->model() );
  Q_ASSERT( model );
  for ( int r = 0; r < model->rowCount(); ++r ) {
    QStandardItem *item = model->item( r );
    item->setCheckable( true );
  }
  mCategoryCombo->setCheckedItems( currentCategories );
}

#include "kotodoviewquicksearch.moc"
<commit_msg>Backport: @info return a richtext for separator<commit_after>/*
  This file is part of KOrganizer.

  Copyright (c) 2004 Till Adam <adam@kde.org>
  Copyright (c) 2005 Rafal Rzepecki <divide@users.sourceforge.net>
  Copyright (c) 2008 Thomas Thrainer <tom_t@gmx.at>

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

  This program 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 this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kotodoviewquicksearch.h"
#include "koprefs.h"

#include <libkdepim/categoryhierarchyreader.h>

#include <kcal/calendar.h>
#include <kcal/calfilter.h>

#include "kcheckcombobox.h"
#include <KLineEdit>

#include <QString>
#include <QStringList>
#include <QModelIndex>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QAbstractItemView>
#include <QHBoxLayout>

using namespace KCal;
using namespace KPIM;

KOTodoViewQuickSearch::KOTodoViewQuickSearch( Calendar *calendar, QWidget *parent )
  : QWidget( parent ), mCalendar( calendar )
{
  QHBoxLayout *layout = new QHBoxLayout( this );
  // no special margin because it is added by the view
  layout->setContentsMargins( 0, 0, 0, 0 );

  mSearchLine = new KLineEdit( this );
  mSearchLine->setClickMessage( i18nc( "@label in QuickSearchLine", "Search" ) );
  mSearchLine->setClearButtonShown( true );
  connect( mSearchLine, SIGNAL(textChanged(const QString &)),
           this, SIGNAL(searchTextChanged(const QString &)) );

  layout->addWidget( mSearchLine, 3 );

  mCategoryCombo = new KCheckComboBox( this );
  mCategoryCombo->setDefaultText( i18nc( "@item:inlistbox", "Select Categories" ) );
  mCategoryCombo->setSeparator( i18nc( "@item delimiter for joining category names", "," ) );

  connect( mCategoryCombo, SIGNAL(checkedItemsChanged(const QStringList &)),
           this, SIGNAL(searchCategoryChanged(const QStringList &)) );

  layout->addWidget( mCategoryCombo, 1 );
  fillCategories();

  setLayout( layout );
}

void KOTodoViewQuickSearch::setCalendar( Calendar *calendar )
{
  mCalendar = calendar;
  fillCategories();
}

void KOTodoViewQuickSearch::updateCategories()
{
  fillCategories();
}

void KOTodoViewQuickSearch::reset()
{
  mSearchLine->clear();
  mCategoryCombo->setCurrentIndex( 0 );
}

void KOTodoViewQuickSearch::fillCategories()
{
  QStringList currentCategories = mCategoryCombo->checkedItems();
  mCategoryCombo->clear();

  QStringList categories;

  if ( mCalendar ) {
    CalFilter *filter = mCalendar->filter();
    if ( filter->criteria() & CalFilter::ShowCategories ) {
      categories = filter->categoryList();
      categories.sort();
    } else {
      categories = KOPrefs::instance()->mCustomCategories;
      QStringList filterCategories = filter->categoryList();
      categories.sort();
      filterCategories.sort();

      QStringList::Iterator it = categories.begin();
      QStringList::Iterator jt = filterCategories.begin();
      while ( it != categories.end() && jt != filterCategories.end() ) {
        if ( *it == *jt ) {
          it = categories.erase( it );
          jt++;
        } else if ( *it < *jt ) {
          it++;
        } else if ( *it > *jt ) {
          jt++;
        }
      }
    }
  }

  CategoryHierarchyReaderQComboBox( mCategoryCombo ).read( categories );

  QStandardItemModel *model =
      qobject_cast<QStandardItemModel *>( mCategoryCombo->model() );
  Q_ASSERT( model );
  for ( int r = 0; r < model->rowCount(); ++r ) {
    QStandardItem *item = model->item( r );
    item->setCheckable( true );
  }
  mCategoryCombo->setCheckedItems( currentCategories );
}

#include "kotodoviewquicksearch.moc"
<|endoftext|>


<commit_before>/*************************************************************************/
/*  eq.cpp                                                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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.                */
/*************************************************************************/

// Author: reduzio@gmail.com (C) 2006

#include "eq.h"
#include "core/error_macros.h"
#include "core/math/math_funcs.h"
#include <math.h>

#define POW2(v) ((v) * (v))

/* Helper */
static int solve_quadratic(double a, double b, double c, double *r1, double *r2) {
	//solves quadractic and returns number of roots

	double base = 2 * a;
	if (base == 0.0f)
		return 0;

	double squared = b * b - 4 * a * c;
	if (squared < 0.0)
		return 0;

	squared = sqrt(squared);

	*r1 = (-b + squared) / base;
	*r2 = (-b - squared) / base;

	if (*r1 == *r2)
		return 1;
	else
		return 2;
}

EQ::BandProcess::BandProcess() {

	c1 = c2 = c3 = history.a1 = history.a2 = history.a3 = 0;
	history.b1 = history.b2 = history.b3 = 0;
}

void EQ::recalculate_band_coefficients() {

#define BAND_LOG(m_f) (log((m_f)) / log(2.))

	for (int i = 0; i < band.size(); i++) {

		double octave_size;

		double frq = band[i].freq;

		if (i == 0) {

			octave_size = BAND_LOG(band[1].freq) - BAND_LOG(frq);
		} else if (i == (band.size() - 1)) {

			octave_size = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq);
		} else {

			double next = BAND_LOG(band[i + 1].freq) - BAND_LOG(frq);
			double prev = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq);
			octave_size = (next + prev) / 2.0;
		}

		double frq_l = round(frq / pow(2.0, octave_size / 2.0));

		double side_gain2 = POW2(Math_SQRT12);
		double th = 2.0 * Math_PI * frq / mix_rate;
		double th_l = 2.0 * Math_PI * frq_l / mix_rate;

		double c2a = side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) + side_gain2 - POW2(sin(th_l));

		double c2b = 2.0 * side_gain2 * POW2(cos(th_l)) + side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) - side_gain2 + POW2(sin(th_l));

		double c2c = 0.25 * side_gain2 * POW2(cos(th)) - 0.5 * side_gain2 * cos(th_l) * cos(th) + 0.25 * side_gain2 - 0.25 * POW2(sin(th_l));

		//printf("band %i, precoefs = %f,%f,%f\n",i,c2a,c2b,c2c);

		double r1, r2; //roots
		int roots = solve_quadratic(c2a, c2b, c2c, &r1, &r2);

		ERR_CONTINUE(roots == 0);

		band.write[i].c1 = 2.0 * ((0.5 - r1) / 2.0);
		band.write[i].c2 = 2.0 * r1;
		band.write[i].c3 = 2.0 * (0.5 + r1) * cos(th);
		//printf("band %i, coefs = %f,%f,%f\n",i,(float)bands[i].c1,(float)bands[i].c2,(float)bands[i].c3);
	}
}

void EQ::set_preset_band_mode(Preset p_preset) {

	band.clear();

#define PUSH_BANDS(m_bands)             \
	for (int i = 0; i < m_bands; i++) { \
		Band b;                         \
		b.freq = bands[i];              \
		band.push_back(b);              \
	}

	switch (p_preset) {

		case PRESET_6_BANDS: {

			static const double bands[] = { 32, 100, 320, 1e3, 3200, 10e3 };
			PUSH_BANDS(6);

		} break;

		case PRESET_8_BANDS: {

			static const double bands[] = { 32, 72, 192, 512, 1200, 3000, 7500, 16e3 };

			PUSH_BANDS(8);
		} break;

		case PRESET_10_BANDS: {
			static const double bands[] = { 31.25, 62.5, 125, 250, 500, 1e3, 2e3, 4e3, 8e3, 16e3 };

			PUSH_BANDS(10);

		} break;

		case PRESET_21_BANDS: {

			static const double bands[] = { 22, 32, 44, 63, 90, 125, 175, 250, 350, 500, 700, 1e3, 1400, 2e3, 2800, 4e3, 5600, 8e3, 11e3, 16e3, 22e3 };
			PUSH_BANDS(21);

		} break;

		case PRESET_31_BANDS: {

			static const double bands[] = { 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1e3, 1250, 1600, 2e3, 2500, 3150, 4e3, 5e3, 6300, 8e3, 10e3, 12500, 16e3, 20e3 };
			PUSH_BANDS(31);
		} break;
	};

	recalculate_band_coefficients();
}

int EQ::get_band_count() const {

	return band.size();
}
float EQ::get_band_frequency(int p_band) {

	ERR_FAIL_INDEX_V(p_band, band.size(), 0);
	return band[p_band].freq;
}
void EQ::set_bands(const Vector<float> &p_bands) {

	band.resize(p_bands.size());
	for (int i = 0; i < p_bands.size(); i++) {

		band.write[i].freq = p_bands[i];
	}

	recalculate_band_coefficients();
}

void EQ::set_mix_rate(float p_mix_rate) {

	mix_rate = p_mix_rate;
	recalculate_band_coefficients();
}

EQ::BandProcess EQ::get_band_processor(int p_band) const {

	EQ::BandProcess band_proc;

	ERR_FAIL_INDEX_V(p_band, band.size(), band_proc);

	band_proc.c1 = band[p_band].c1;
	band_proc.c2 = band[p_band].c2;
	band_proc.c3 = band[p_band].c3;

	return band_proc;
}

EQ::EQ() {
	mix_rate = 44100;
}

EQ::~EQ() {
}
<commit_msg>Fix 'r1' (and r2) may be used uninitialized warning in eq.cpp.<commit_after>/*************************************************************************/
/*  eq.cpp                                                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* 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.                */
/*************************************************************************/

// Author: reduzio@gmail.com (C) 2006

#include "eq.h"
#include "core/error_macros.h"
#include "core/math/math_funcs.h"
#include <math.h>

#define POW2(v) ((v) * (v))

/* Helper */
static int solve_quadratic(double a, double b, double c, double *r1, double *r2) {
	//solves quadractic and returns number of roots

	double base = 2 * a;
	if (base == 0.0f)
		return 0;

	double squared = b * b - 4 * a * c;
	if (squared < 0.0)
		return 0;

	squared = sqrt(squared);

	*r1 = (-b + squared) / base;
	*r2 = (-b - squared) / base;

	if (*r1 == *r2)
		return 1;
	else
		return 2;
}

EQ::BandProcess::BandProcess() {

	c1 = c2 = c3 = history.a1 = history.a2 = history.a3 = 0;
	history.b1 = history.b2 = history.b3 = 0;
}

void EQ::recalculate_band_coefficients() {

#define BAND_LOG(m_f) (log((m_f)) / log(2.))

	for (int i = 0; i < band.size(); i++) {

		double octave_size;

		double frq = band[i].freq;

		if (i == 0) {

			octave_size = BAND_LOG(band[1].freq) - BAND_LOG(frq);
		} else if (i == (band.size() - 1)) {

			octave_size = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq);
		} else {

			double next = BAND_LOG(band[i + 1].freq) - BAND_LOG(frq);
			double prev = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq);
			octave_size = (next + prev) / 2.0;
		}

		double frq_l = round(frq / pow(2.0, octave_size / 2.0));

		double side_gain2 = POW2(Math_SQRT12);
		double th = 2.0 * Math_PI * frq / mix_rate;
		double th_l = 2.0 * Math_PI * frq_l / mix_rate;

		double c2a = side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) + side_gain2 - POW2(sin(th_l));

		double c2b = 2.0 * side_gain2 * POW2(cos(th_l)) + side_gain2 * POW2(cos(th)) - 2.0 * side_gain2 * cos(th_l) * cos(th) - side_gain2 + POW2(sin(th_l));

		double c2c = 0.25 * side_gain2 * POW2(cos(th)) - 0.5 * side_gain2 * cos(th_l) * cos(th) + 0.25 * side_gain2 - 0.25 * POW2(sin(th_l));

		//printf("band %i, precoefs = %f,%f,%f\n",i,c2a,c2b,c2c);

		// Default initializing to silence compiler warning about potential uninitialized use.
		// Both variables are properly set in _solve_quadratic before use, or we continue if roots == 0.
		double r1 = 0, r2 = 0; //roots
		int roots = solve_quadratic(c2a, c2b, c2c, &r1, &r2);

		ERR_CONTINUE(roots == 0);

		band.write[i].c1 = 2.0 * ((0.5 - r1) / 2.0);
		band.write[i].c2 = 2.0 * r1;
		band.write[i].c3 = 2.0 * (0.5 + r1) * cos(th);
		//printf("band %i, coefs = %f,%f,%f\n",i,(float)bands[i].c1,(float)bands[i].c2,(float)bands[i].c3);
	}
}

void EQ::set_preset_band_mode(Preset p_preset) {

	band.clear();

#define PUSH_BANDS(m_bands)             \
	for (int i = 0; i < m_bands; i++) { \
		Band b;                         \
		b.freq = bands[i];              \
		band.push_back(b);              \
	}

	switch (p_preset) {

		case PRESET_6_BANDS: {

			static const double bands[] = { 32, 100, 320, 1e3, 3200, 10e3 };
			PUSH_BANDS(6);

		} break;

		case PRESET_8_BANDS: {

			static const double bands[] = { 32, 72, 192, 512, 1200, 3000, 7500, 16e3 };

			PUSH_BANDS(8);
		} break;

		case PRESET_10_BANDS: {
			static const double bands[] = { 31.25, 62.5, 125, 250, 500, 1e3, 2e3, 4e3, 8e3, 16e3 };

			PUSH_BANDS(10);

		} break;

		case PRESET_21_BANDS: {

			static const double bands[] = { 22, 32, 44, 63, 90, 125, 175, 250, 350, 500, 700, 1e3, 1400, 2e3, 2800, 4e3, 5600, 8e3, 11e3, 16e3, 22e3 };
			PUSH_BANDS(21);

		} break;

		case PRESET_31_BANDS: {

			static const double bands[] = { 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1e3, 1250, 1600, 2e3, 2500, 3150, 4e3, 5e3, 6300, 8e3, 10e3, 12500, 16e3, 20e3 };
			PUSH_BANDS(31);
		} break;
	};

	recalculate_band_coefficients();
}

int EQ::get_band_count() const {

	return band.size();
}
float EQ::get_band_frequency(int p_band) {

	ERR_FAIL_INDEX_V(p_band, band.size(), 0);
	return band[p_band].freq;
}
void EQ::set_bands(const Vector<float> &p_bands) {

	band.resize(p_bands.size());
	for (int i = 0; i < p_bands.size(); i++) {

		band.write[i].freq = p_bands[i];
	}

	recalculate_band_coefficients();
}

void EQ::set_mix_rate(float p_mix_rate) {

	mix_rate = p_mix_rate;
	recalculate_band_coefficients();
}

EQ::BandProcess EQ::get_band_processor(int p_band) const {

	EQ::BandProcess band_proc;

	ERR_FAIL_INDEX_V(p_band, band.size(), band_proc);

	band_proc.c1 = band[p_band].c1;
	band_proc.c2 = band[p_band].c2;
	band_proc.c3 = band[p_band].c3;

	return band_proc;
}

EQ::EQ() {
	mix_rate = 44100;
}

EQ::~EQ() {
}
<|endoftext|>


<commit_before>#include "builtin/nativemethod.hpp"
#include "objectmemory.hpp"
#include "gc/baker.hpp"
#include "capi/capi.hpp"
#include "capi/handles.hpp"

namespace rubinius {
  namespace capi {

    Handle* Handles::allocate(STATE, Object* obj) {
      bool needs_gc = false;
      Handle* handle = allocator_->allocate(&needs_gc);
      handle->set_object(obj);
      handle->validate();
      if(needs_gc) {
        state->memory()->collect_mature_now = true;
      }
      atomic::memory_barrier();
      return handle;
    }

    uintptr_t Handles::allocate_index(STATE, Object* obj) {
      bool needs_gc = false;
      uintptr_t handle_index = allocator_->allocate_index(&needs_gc);
      Handle* handle = allocator_->from_index(handle_index);
      handle->set_object(obj);
      handle->validate();
      if(needs_gc) {
        state->memory()->collect_mature_now = true;
      }
      atomic::memory_barrier();

      if(handle_index > UINT32_MAX) {
        rubinius::bug("Rubinius can't handle more than 4G C-API handles active at the same time");
      }

      return handle_index;
    }

    bool Handles::validate(Handle* handle) {
      return allocator_->validate(handle);
    }

    Handles::~Handles() {
      for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
        Handle* chunk = allocator_->chunks_[i];

        for(size_t j = 0; j < allocator_->cChunkSize; j++) {
          Handle* handle = &chunk[j];
          if(handle->in_use_p()) {
            handle->clear();
          }
        }
      }
      delete allocator_;
    }

    void Handles::deallocate_handles(std::list<Handle*>* cached, int mark, BakerGC* young) {
      std::vector<bool> chunk_marks(allocator_->chunks_.size(), false);

      for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
        Handle* chunk = allocator_->chunks_[i];

        for(size_t j = 0; j < allocator_->cChunkSize; j++) {
          Handle* handle = &chunk[j];

          Object* obj = handle->object();

          if(!handle->in_use_p()) {
            continue;
          }

          // Strong references will already have been updated.
          if(!handle->weak_p()) {
            chunk_marks[i] = true;
            continue;
          }

          if(young) {
            if(obj->young_object_p()) {
              // A weakref pointing to a valid young object
              //
              // TODO this only works because we run prune_handles right after
              // a collection. In this state, valid objects are only in current.
              if(young->in_current_p(obj)) {
                chunk_marks[i] = true;
              // A weakref pointing to a forwarded young object
              } else if(obj->forwarded_p()) {
                handle->set_object(obj->forward());
                chunk_marks[i] = true;
              // A weakref pointing to a dead young object
              } else {
                handle->clear();
              }
            } else {
              // Not a young object, so won't be GC'd so mark
              // chunk as still active
              chunk_marks[i] = true;
            }

          // A weakref pointing to a dead mature object
          } else if(!obj->marked_p(mark)) {
            handle->clear();
          } else {
            chunk_marks[i] = true;
          }
        }
      }

      // Cleanup cached handles
      for(std::list<Handle*>::iterator it = cached->begin(); it != cached->end();) {
        Handle* handle = *it;

        if(handle->in_use_p()) {
          ++it;
        } else {
          it = cached->erase(it);
        }
      }

      allocator_->rebuild_freelist(&chunk_marks);
    }
  }
}
<commit_msg>Also add the size check for C-API handles<commit_after>#include "builtin/nativemethod.hpp"
#include "objectmemory.hpp"
#include "gc/baker.hpp"
#include "capi/capi.hpp"
#include "capi/handles.hpp"

namespace rubinius {
  namespace capi {

    Handle* Handles::allocate(STATE, Object* obj) {
      bool needs_gc = false;
      Handle* handle = allocator_->allocate(&needs_gc);
      handle->set_object(obj);
      handle->validate();
      if(needs_gc) {
        state->memory()->collect_mature_now = true;
      }
      atomic::memory_barrier();
      return handle;
    }

    uintptr_t Handles::allocate_index(STATE, Object* obj) {
      bool needs_gc = false;
      uintptr_t handle_index = allocator_->allocate_index(&needs_gc);
      if(handle_index > UINT32_MAX) {
        rubinius::bug("Rubinius can't handle more than 4G C-API handles active at the same time");
      }
      Handle* handle = allocator_->from_index(handle_index);
      handle->set_object(obj);
      handle->validate();
      if(needs_gc) {
        state->memory()->collect_mature_now = true;
      }
      atomic::memory_barrier();

      if(handle_index > UINT32_MAX) {
        rubinius::bug("Rubinius can't handle more than 4G C-API handles active at the same time");
      }

      return handle_index;
    }

    bool Handles::validate(Handle* handle) {
      return allocator_->validate(handle);
    }

    Handles::~Handles() {
      for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
        Handle* chunk = allocator_->chunks_[i];

        for(size_t j = 0; j < allocator_->cChunkSize; j++) {
          Handle* handle = &chunk[j];
          if(handle->in_use_p()) {
            handle->clear();
          }
        }
      }
      delete allocator_;
    }

    void Handles::deallocate_handles(std::list<Handle*>* cached, int mark, BakerGC* young) {
      std::vector<bool> chunk_marks(allocator_->chunks_.size(), false);

      for(std::vector<int>::size_type i = 0; i < allocator_->chunks_.size(); ++i) {
        Handle* chunk = allocator_->chunks_[i];

        for(size_t j = 0; j < allocator_->cChunkSize; j++) {
          Handle* handle = &chunk[j];

          Object* obj = handle->object();

          if(!handle->in_use_p()) {
            continue;
          }

          // Strong references will already have been updated.
          if(!handle->weak_p()) {
            chunk_marks[i] = true;
            continue;
          }

          if(young) {
            if(obj->young_object_p()) {
              // A weakref pointing to a valid young object
              //
              // TODO this only works because we run prune_handles right after
              // a collection. In this state, valid objects are only in current.
              if(young->in_current_p(obj)) {
                chunk_marks[i] = true;
              // A weakref pointing to a forwarded young object
              } else if(obj->forwarded_p()) {
                handle->set_object(obj->forward());
                chunk_marks[i] = true;
              // A weakref pointing to a dead young object
              } else {
                handle->clear();
              }
            } else {
              // Not a young object, so won't be GC'd so mark
              // chunk as still active
              chunk_marks[i] = true;
            }

          // A weakref pointing to a dead mature object
          } else if(!obj->marked_p(mark)) {
            handle->clear();
          } else {
            chunk_marks[i] = true;
          }
        }
      }

      // Cleanup cached handles
      for(std::list<Handle*>::iterator it = cached->begin(); it != cached->end();) {
        Handle* handle = *it;

        if(handle->in_use_p()) {
          ++it;
        } else {
          it = cached->erase(it);
        }
      }

      allocator_->rebuild_freelist(&chunk_marks);
    }
  }
}
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN
#include <catch.hpp>

#include "managed.h"
#include "glib.h"

TEST_CASE("Types.C", "[C][Types]") {
    BuiltinTypes* bt = BuiltinTypes_new();
    BuiltinTypes_ReturnsVoid(bt);
    REQUIRE(BuiltinTypes_ReturnsBool(bt)   == true);
    REQUIRE(BuiltinTypes_ReturnsSByte(bt)  == -5);
    REQUIRE(BuiltinTypes_ReturnsByte(bt)   ==  5);
    REQUIRE(BuiltinTypes_ReturnsShort(bt)  == -5);
    REQUIRE(BuiltinTypes_ReturnsUShort(bt) ==  5);
    REQUIRE(BuiltinTypes_ReturnsInt(bt)    == -5);
    REQUIRE(BuiltinTypes_ReturnsUInt(bt)   ==  5);
    REQUIRE(BuiltinTypes_ReturnsLong(bt)   == -5);
    REQUIRE(BuiltinTypes_ReturnsULong(bt)  ==  5);
    REQUIRE(BuiltinTypes_ReturnsChar(bt) == 'a');
    REQUIRE(strcmp(BuiltinTypes_ReturnsString(bt), "Mono") == 0);

    REQUIRE(BuiltinTypes_PassAndReturnsBool(bt, true) == true);
    REQUIRE(BuiltinTypes_PassAndReturnsSByte(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsByte(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsShort(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsUShort(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsInt(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsUInt(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsLong(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsULong(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsChar(bt, 'a') == 'a');
    REQUIRE(strcmp(BuiltinTypes_PassAndReturnsString(bt, "Mono"), "Mono") == 0);

    int OutInt = 0;
    BuiltinTypes_PassOutInt(bt, &OutInt);
    REQUIRE(OutInt == 5);

    int RefInt = 0;
    BuiltinTypes_PassRefInt(bt, &RefInt);
    REQUIRE(RefInt == 10);

    GString* RefOut = g_string_new("");
    BuiltinTypes_PassOutString(bt, RefOut);
    REQUIRE(strcmp(RefOut->str, "Mono") == 0);

    GString* RefStr = g_string_new("monomono");
    BuiltinTypes_PassRefString(bt, RefStr);
    REQUIRE(strcmp(RefStr->str, "Mono") == 0);
}

TEST_CASE("Properties", "[C][Properties]") {
    REQUIRE(Platform_get_IsWindows() == false);

    Platform_set_ExitCode(255);
    REQUIRE(Platform_get_ExitCode() == 255);

    REQUIRE(Properties_Query_get_UniversalAnswer() == 42);

    Properties_Query* prop = Properties_Query_new();
    REQUIRE(Properties_Query_get_IsGood(prop) == true);
    REQUIRE(Properties_Query_get_IsBad(prop) == false);
    REQUIRE(Properties_Query_get_Answer(prop) == 42);
    Properties_Query_set_Answer(prop, 911);
    REQUIRE(Properties_Query_get_Answer(prop) == 911);

    REQUIRE(Properties_Query_get_IsSecret(prop) == false);
    Properties_Query_set_Secret(prop, 1);
    REQUIRE(Properties_Query_get_IsSecret(prop) == true);
}

TEST_CASE("Namespaces.C", "[C][Namespaces]") {
    ClassWithoutNamespace* nonamespace = ClassWithoutNamespace_new();
    REQUIRE(strcmp(ClassWithoutNamespace_ToString(nonamespace), "ClassWithoutNamespace") == 0);

    First_ClassWithSingleNamespace* singlenamespace = First_ClassWithSingleNamespace_new();
    REQUIRE(strcmp(First_ClassWithSingleNamespace_ToString(singlenamespace), "First.ClassWithSingleNamespace") == 0);

    First_Second_ClassWithNestedNamespace* nestednamespaces = First_Second_ClassWithNestedNamespace_new();
    REQUIRE(strcmp(First_Second_ClassWithNestedNamespace_ToString(nestednamespaces), "First.Second.ClassWithNestedNamespace") == 0);

    First_Second_Third_ClassWithNestedNamespace* nestednamespaces2 = First_Second_Third_ClassWithNestedNamespace_new();
    REQUIRE(strcmp(First_Second_Third_ClassWithNestedNamespace_ToString(nestednamespaces2), "First.Second.Third.ClassWithNestedNamespace") == 0);
}
TEST_CASE("Enums.C", "[C][Enums]") {
    REQUIRE(Enums_EnumTypes_PassEnum(Enum_Two) == 2);
    REQUIRE(Enums_EnumTypes_PassEnum(Enum_Three) == 3);

    REQUIRE(Enums_EnumTypes_PassEnumByte(EnumByte_Two) == 2);
    REQUIRE(Enums_EnumTypes_PassEnumByte(EnumByte_Three) == 3);

    REQUIRE(Enums_EnumTypes_PassEnumFlags(EnumFlags_FlagOne) == (1 << 0));
    REQUIRE(Enums_EnumTypes_PassEnumFlags(EnumFlags_FlagTwo) == (1 << 2));
}

TEST_CASE("Arrays.C", "[C][Arrays]") {
    char _byte_arr[] = { 1, 2, 3 };
    _UnsignedcharArray _byte;
    _byte.array = g_array_sized_new(/*zero_terminated=*/false,
        /*clear=*/true, sizeof(char), G_N_ELEMENTS(_byte_arr));
    g_array_append_vals (_byte.array, _byte_arr, G_N_ELEMENTS(_byte_arr));

    int _sum = Arrays_ArrayTypes_SumByteArray(_byte);
    REQUIRE(_sum == 6);

    _IntArray _int = Arrays_ArrayTypes_ReturnsIntArray();
    REQUIRE(_int.array->len == 3);
    REQUIRE(g_array_index(_int.array, int, 0) == 1);
    REQUIRE(g_array_index(_int.array, int, 1) == 2);
    REQUIRE(g_array_index(_int.array, int, 2) == 3);

    _CharArray _string = Arrays_ArrayTypes_ReturnsStringArray();
    REQUIRE(_string.array->len == 3);
    REQUIRE(strcmp(g_array_index(_string.array, gchar*, 0), "1") == 0);
    REQUIRE(strcmp(g_array_index(_string.array, gchar*, 1), "2") == 0);
    REQUIRE(strcmp(g_array_index(_string.array, gchar*, 2), "3") == 0);
}
<commit_msg>[tests][c] Added a few more tests for constructors.<commit_after>#define CATCH_CONFIG_MAIN
#include <catch.hpp>

#include "managed.h"
#include "glib.h"

#include "float.h"

TEST_CASE("Types.C", "[C][Types]") {
    BuiltinTypes* bt = BuiltinTypes_new();
    BuiltinTypes_ReturnsVoid(bt);
    REQUIRE(BuiltinTypes_ReturnsBool(bt)   == true);
    REQUIRE(BuiltinTypes_ReturnsSByte(bt)  == -5);
    REQUIRE(BuiltinTypes_ReturnsByte(bt)   ==  5);
    REQUIRE(BuiltinTypes_ReturnsShort(bt)  == -5);
    REQUIRE(BuiltinTypes_ReturnsUShort(bt) ==  5);
    REQUIRE(BuiltinTypes_ReturnsInt(bt)    == -5);
    REQUIRE(BuiltinTypes_ReturnsUInt(bt)   ==  5);
    REQUIRE(BuiltinTypes_ReturnsLong(bt)   == -5);
    REQUIRE(BuiltinTypes_ReturnsULong(bt)  ==  5);
    REQUIRE(BuiltinTypes_ReturnsChar(bt) == 'a');
    REQUIRE(strcmp(BuiltinTypes_ReturnsString(bt), "Mono") == 0);

    REQUIRE(BuiltinTypes_PassAndReturnsBool(bt, true) == true);
    REQUIRE(BuiltinTypes_PassAndReturnsSByte(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsByte(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsShort(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsUShort(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsInt(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsUInt(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsLong(bt, -5) == -5);
    REQUIRE(BuiltinTypes_PassAndReturnsULong(bt, 5) == 5);
    REQUIRE(BuiltinTypes_PassAndReturnsChar(bt, 'a') == 'a');
    REQUIRE(strcmp(BuiltinTypes_PassAndReturnsString(bt, "Mono"), "Mono") == 0);

    int OutInt = 0;
    BuiltinTypes_PassOutInt(bt, &OutInt);
    REQUIRE(OutInt == 5);

    int RefInt = 0;
    BuiltinTypes_PassRefInt(bt, &RefInt);
    REQUIRE(RefInt == 10);

    GString* RefOut = g_string_new("");
    BuiltinTypes_PassOutString(bt, RefOut);
    REQUIRE(strcmp(RefOut->str, "Mono") == 0);

    GString* RefStr = g_string_new("monomono");
    BuiltinTypes_PassRefString(bt, RefStr);
    REQUIRE(strcmp(RefStr->str, "Mono") == 0);
}

TEST_CASE("Properties", "[C][Properties]") {
    REQUIRE(Platform_get_IsWindows() == false);

    Platform_set_ExitCode(255);
    REQUIRE(Platform_get_ExitCode() == 255);

    REQUIRE(Properties_Query_get_UniversalAnswer() == 42);

    Properties_Query* prop = Properties_Query_new();
    REQUIRE(Properties_Query_get_IsGood(prop) == true);
    REQUIRE(Properties_Query_get_IsBad(prop) == false);
    REQUIRE(Properties_Query_get_Answer(prop) == 42);
    Properties_Query_set_Answer(prop, 911);
    REQUIRE(Properties_Query_get_Answer(prop) == 911);

    REQUIRE(Properties_Query_get_IsSecret(prop) == false);
    Properties_Query_set_Secret(prop, 1);
    REQUIRE(Properties_Query_get_IsSecret(prop) == true);
}

TEST_CASE("Namespaces.C", "[C][Namespaces]") {
    ClassWithoutNamespace* nonamespace = ClassWithoutNamespace_new();
    REQUIRE(strcmp(ClassWithoutNamespace_ToString(nonamespace), "ClassWithoutNamespace") == 0);

    First_ClassWithSingleNamespace* singlenamespace = First_ClassWithSingleNamespace_new();
    REQUIRE(strcmp(First_ClassWithSingleNamespace_ToString(singlenamespace), "First.ClassWithSingleNamespace") == 0);

    First_Second_ClassWithNestedNamespace* nestednamespaces = First_Second_ClassWithNestedNamespace_new();
    REQUIRE(strcmp(First_Second_ClassWithNestedNamespace_ToString(nestednamespaces), "First.Second.ClassWithNestedNamespace") == 0);

    First_Second_Third_ClassWithNestedNamespace* nestednamespaces2 = First_Second_Third_ClassWithNestedNamespace_new();
    REQUIRE(strcmp(First_Second_Third_ClassWithNestedNamespace_ToString(nestednamespaces2), "First.Second.Third.ClassWithNestedNamespace") == 0);
}

TEST_CASE("Constructors.C", "[C][Constructors]") {
    Constructors_Unique* unique = Constructors_Unique_new_1();
    REQUIRE(Constructors_Unique_get_Id(unique) == 1);

    Constructors_Unique* unique_init_id = Constructors_Unique_new_2(911);
    REQUIRE(Constructors_Unique_get_Id(unique_init_id) == 911);

    Constructors_SuperUnique* super_unique_default_init = Constructors_SuperUnique_new();
    REQUIRE(Constructors_Unique_get_Id(super_unique_default_init) == 411);

    Constructors_Implicit* implicit = Constructors_Implicit_new();
    REQUIRE(strcmp(Constructors_Implicit_get_TestResult(implicit), "OK") == 0);

    Constructors_AllTypeCode* all1 = Constructors_AllTypeCode_new(true, USHRT_MAX, "Mono");
    REQUIRE(Constructors_AllTypeCode_get_TestResult(all1) == true);

    Constructors_AllTypeCode* all2 = Constructors_AllTypeCode_new_1(SCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX);
    REQUIRE(Constructors_AllTypeCode_get_TestResult(all2) == true);

    Constructors_AllTypeCode* all3 = Constructors_AllTypeCode_new_2(UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX);
    REQUIRE(Constructors_AllTypeCode_get_TestResult(all3) == true);

    Constructors_AllTypeCode* all4 = Constructors_AllTypeCode_new_3(FLT_MAX, DBL_MAX);
    REQUIRE(Constructors_AllTypeCode_get_TestResult(all4) == true);
}

TEST_CASE("Enums.C", "[C][Enums]") {
    REQUIRE(Enums_EnumTypes_PassEnum(Enum_Two) == 2);
    REQUIRE(Enums_EnumTypes_PassEnum(Enum_Three) == 3);

    REQUIRE(Enums_EnumTypes_PassEnumByte(EnumByte_Two) == 2);
    REQUIRE(Enums_EnumTypes_PassEnumByte(EnumByte_Three) == 3);

    REQUIRE(Enums_EnumTypes_PassEnumFlags(EnumFlags_FlagOne) == (1 << 0));
    REQUIRE(Enums_EnumTypes_PassEnumFlags(EnumFlags_FlagTwo) == (1 << 2));
}

TEST_CASE("Arrays.C", "[C][Arrays]") {
    char _byte_arr[] = { 1, 2, 3 };
    _UnsignedcharArray _byte;
    _byte.array = g_array_sized_new(/*zero_terminated=*/false,
        /*clear=*/true, sizeof(char), G_N_ELEMENTS(_byte_arr));
    g_array_append_vals (_byte.array, _byte_arr, G_N_ELEMENTS(_byte_arr));

    int _sum = Arrays_ArrayTypes_SumByteArray(_byte);
    REQUIRE(_sum == 6);

    _IntArray _int = Arrays_ArrayTypes_ReturnsIntArray();
    REQUIRE(_int.array->len == 3);
    REQUIRE(g_array_index(_int.array, int, 0) == 1);
    REQUIRE(g_array_index(_int.array, int, 1) == 2);
    REQUIRE(g_array_index(_int.array, int, 2) == 3);

    _CharArray _string = Arrays_ArrayTypes_ReturnsStringArray();
    REQUIRE(_string.array->len == 3);
    REQUIRE(strcmp(g_array_index(_string.array, gchar*, 0), "1") == 0);
    REQUIRE(strcmp(g_array_index(_string.array, gchar*, 1), "2") == 0);
    REQUIRE(strcmp(g_array_index(_string.array, gchar*, 2), "3") == 0);
}
<|endoftext|>