<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2018)

#ifndef DUNE_GDT_DISCRETEFUNCTION_BOCHNER_HH
#define DUNE_GDT_DISCRETEFUNCTION_BOCHNER_HH

#include <dune/xt/common/memory.hh>
#include <dune/xt/la/container/vector-array/list.hh>
#include <dune/xt/grid/search.hh>

#include <dune/gdt/exceptions.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/spaces/bochner.hh>

namespace Dune {
namespace GDT {

/**
 * \todo Turn this into a parametric LocalizableFunction.
 * \todo add ConstDiscreteBochnerFunction
 */
template <class V, class GV, size_t r = 1, size_t rC = 1, class R = double>
class DiscreteBochnerFunction
{
public:
  DiscreteBochnerFunction(const BochnerSpace<GV, r, rC, R>& bochner_space,
                          XT::LA::ListVectorArray<V>& dof_vectors,
                          const std::string nm = "")
    : bochner_space_(bochner_space)
    , dof_vectors_(dof_vectors)
    , name_(nm.empty() ? "DiscreteBochnerFunction" : nm)
  {
    DUNE_THROW_IF(this->dof_vectors().length() != bochner_space_.temporal_space().mapper().size(),
                  Exceptions::space_error,
                  "\n   this->dof_vectors().length() = " << this->dof_vectors().length() << "\n   "
                                                         << bochner_space_.temporal_space().mapper().size());
    for (const auto& vec : this->dof_vectors())
      DUNE_THROW_IF(vec.vector().size() != bochner_space_.spatial_space().mapper().size(),
                    Exceptions::space_error,
                    "\n   vec.vector().size() = " << vec.vector().size() << "\n   "
                                                  << bochner_space_.spatial_space().mapper().size());
  } // DiscreteBochnerFunction(...)

  DiscreteBochnerFunction(const BochnerSpace<GV, r, rC, R>& bochner_space, const std::string nm = "")
    : bochner_space_(bochner_space)
    , dof_vectors_(new XT::LA::ListVectorArray<V>(bochner_space_.spatial_space().mapper().size(),
                                                  bochner_space_.temporal_space().mapper().size()))
    , name_(nm.empty() ? "DiscreteBochnerFunction" : nm)
  {
  }

  const BochnerSpace<GV, r, rC, R>& space() const
  {
    return bochner_space_;
  }

  const XT::LA::ListVectorArray<V>& dof_vectors() const
  {
    return dof_vectors_.access();
  }

  XT::LA::ListVectorArray<V>& dof_vectors()
  {
    return dof_vectors_.access();
  }

  std::string name() const
  {
    return name_;
  }

  V evaluate(const double& time) const
  {
    const auto search_result = XT::Grid::make_entity_in_level_search(bochner_space_.temporal_space().grid_view())(
        std::vector<double>(1, time));
    DUNE_THROW_IF(!search_result.at(0),
                  Exceptions::finite_element_error,
                  "when evaluating timedependent function: could not find time_interval for time = " << time);
    const auto& time_interval = *search_result.at(0);
    const auto temporal_basis = bochner_space_.temporal_space().basis().localize(time_interval);
    const auto time_in_reference_element = time_interval.geometry().local(time);
    const auto temporal_basis_values = temporal_basis->evaluate_set(time_in_reference_element);
    V result(bochner_space_.spatial_space().mapper().size(), 0.);
    const auto global_dof_indices = bochner_space_.temporal_space().mapper().global_indices(time_interval);
    for (size_t ii = 0; ii < temporal_basis->size(); ++ii)
      result.axpy(temporal_basis_values[ii], this->dof_vectors()[global_dof_indices[ii]].vector());
    return result;
  } // ... evaluate(...)

  void visualize(const std::string filename_prefix, const VTK::OutputType vtk_output_type = VTK::appendedraw) const
  {
    DUNE_THROW_IF(
        filename_prefix.empty(), XT::Common::Exceptions::wrong_input_given, "filename_prefix must not be empty!");
    for (const auto& annotated_vector : dof_vectors_.access()) {
      const double time = annotated_vector.note().get("_t").at(0);
      auto df = make_const_discrete_function(bochner_space_.spatial_space(), annotated_vector.vector(), name_);
      df.visualize(filename_prefix + "_" + XT::Common::to_string(time), vtk_output_type);
    }
  } // ... visualize(...)

private:
  const BochnerSpace<GV, r, rC, R>& bochner_space_;
  XT::Common::StorageProvider<XT::LA::ListVectorArray<V>> dof_vectors_;
  const std::string name_;
}; // class DiscreteBochnerFunction

template <class GV, size_t r, size_t rC, class R, class V>
DiscreteBochnerFunction<V, GV, r, rC, R> make_discrete_bochner_function(const BochnerSpace<GV, r, rC, R>& bochner_space,
                                                                        XT::LA::ListVectorArray<V>& dof_vectors)
{
  return DiscreteBochnerFunction<V, GV, r, rC, R>(bochner_space, dof_vectors);
}

template <class VectorType, class GV, size_t r, size_t rC, class R>
typename std::enable_if<XT::LA::is_vector<VectorType>::value, DiscreteBochnerFunction<VectorType, GV, r, rC, R>>::type
make_discrete_bochner_function(const BochnerSpace<GV, r, rC, R>& bochner_space)
{
  return DiscreteBochnerFunction<VectorType, GV, r, rC, R>(bochner_space);
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_BOCHNER_HH
<commit_msg>[discretefunction.bochner] return function instead of vector in evaluate()<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2018)

#ifndef DUNE_GDT_DISCRETEFUNCTION_BOCHNER_HH
#define DUNE_GDT_DISCRETEFUNCTION_BOCHNER_HH

#include <dune/xt/common/memory.hh>
#include <dune/xt/la/container/vector-array/list.hh>
#include <dune/xt/grid/search.hh>

#include <dune/gdt/exceptions.hh>
#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/spaces/bochner.hh>

namespace Dune {
namespace GDT {

/**
 * \todo Turn this into a parametric LocalizableFunction.
 * \todo add ConstDiscreteBochnerFunction
 */
template <class V, class GV, size_t r = 1, size_t rC = 1, class R = double>
class DiscreteBochnerFunction
{
public:
  DiscreteBochnerFunction(const BochnerSpace<GV, r, rC, R>& bochner_space,
                          XT::LA::ListVectorArray<V>& dof_vectors,
                          const std::string nm = "")
    : bochner_space_(bochner_space)
    , dof_vectors_(dof_vectors)
    , name_(nm.empty() ? "DiscreteBochnerFunction" : nm)
  {
    DUNE_THROW_IF(this->dof_vectors().length() != bochner_space_.temporal_space().mapper().size(),
                  Exceptions::space_error,
                  "\n   this->dof_vectors().length() = " << this->dof_vectors().length() << "\n   "
                                                         << bochner_space_.temporal_space().mapper().size());
    for (const auto& vec : this->dof_vectors())
      DUNE_THROW_IF(vec.vector().size() != bochner_space_.spatial_space().mapper().size(),
                    Exceptions::space_error,
                    "\n   vec.vector().size() = " << vec.vector().size() << "\n   "
                                                  << bochner_space_.spatial_space().mapper().size());
  } // DiscreteBochnerFunction(...)

  DiscreteBochnerFunction(const BochnerSpace<GV, r, rC, R>& bochner_space, const std::string nm = "")
    : bochner_space_(bochner_space)
    , dof_vectors_(new XT::LA::ListVectorArray<V>(bochner_space_.spatial_space().mapper().size(),
                                                  bochner_space_.temporal_space().mapper().size()))
    , name_(nm.empty() ? "DiscreteBochnerFunction" : nm)
  {
  }

  const BochnerSpace<GV, r, rC, R>& space() const
  {
    return bochner_space_;
  }

  const XT::LA::ListVectorArray<V>& dof_vectors() const
  {
    return dof_vectors_.access();
  }

  XT::LA::ListVectorArray<V>& dof_vectors()
  {
    return dof_vectors_.access();
  }

  std::string name() const
  {
    return name_;
  }

  DiscreteFunction<V, GV, r, rC, R> evaluate(const double& time) const
  {
    const auto search_result = XT::Grid::make_entity_in_level_search(bochner_space_.temporal_space().grid_view())(
        std::vector<double>(1, time));
    DUNE_THROW_IF(!search_result.at(0),
                  Exceptions::finite_element_error,
                  "when evaluating timedependent function: could not find time_interval for time = " << time);
    const auto& time_interval = *search_result.at(0);
    const auto temporal_basis = bochner_space_.temporal_space().basis().localize(time_interval);
    const auto time_in_reference_element = time_interval.geometry().local(time);
    const auto temporal_basis_values = temporal_basis->evaluate_set(time_in_reference_element);
    V result(bochner_space_.spatial_space().mapper().size(), 0.);
    const auto global_dof_indices = bochner_space_.temporal_space().mapper().global_indices(time_interval);
    for (size_t ii = 0; ii < temporal_basis->size(); ++ii)
      result.axpy(temporal_basis_values[ii], this->dof_vectors()[global_dof_indices[ii]].vector());
    return make_discrete_function(bochner_space_.spatial_space(), std::move(result));
  } // ... evaluate(...)

  void visualize(const std::string filename_prefix, const VTK::OutputType vtk_output_type = VTK::appendedraw) const
  {
    DUNE_THROW_IF(
        filename_prefix.empty(), XT::Common::Exceptions::wrong_input_given, "filename_prefix must not be empty!");
    for (const auto& annotated_vector : dof_vectors_.access()) {
      const double time = annotated_vector.note().get("_t").at(0);
      auto df = make_const_discrete_function(bochner_space_.spatial_space(), annotated_vector.vector(), name_);
      df.visualize(filename_prefix + "_" + XT::Common::to_string(time), vtk_output_type);
    }
  } // ... visualize(...)

private:
  const BochnerSpace<GV, r, rC, R>& bochner_space_;
  XT::Common::StorageProvider<XT::LA::ListVectorArray<V>> dof_vectors_;
  const std::string name_;
}; // class DiscreteBochnerFunction

template <class GV, size_t r, size_t rC, class R, class V>
DiscreteBochnerFunction<V, GV, r, rC, R> make_discrete_bochner_function(const BochnerSpace<GV, r, rC, R>& bochner_space,
                                                                        XT::LA::ListVectorArray<V>& dof_vectors)
{
  return DiscreteBochnerFunction<V, GV, r, rC, R>(bochner_space, dof_vectors);
}

template <class VectorType, class GV, size_t r, size_t rC, class R>
typename std::enable_if<XT::LA::is_vector<VectorType>::value, DiscreteBochnerFunction<VectorType, GV, r, rC, R>>::type
make_discrete_bochner_function(const BochnerSpace<GV, r, rC, R>& bochner_space)
{
  return DiscreteBochnerFunction<VectorType, GV, r, rC, R>(bochner_space);
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_BOCHNER_HH
<|endoftext|>


<commit_before>#ifndef ERROR_CALC_HH
#define ERROR_CALC_HH

#include <dune/multiscale/common/traits.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/multiscale/msfem/localsolution_proxy.hh>
#include <iosfwd>
#include <memory>

namespace Dune {
namespace Multiscale {

class Elliptic_FEM_Solver;
class LocalsolutionProxy;

class ErrorCalculator {

public:
  ErrorCalculator(const Problem::ProblemContainer& problem, const std::unique_ptr<LocalsolutionProxy>& msfem_solution,
                  CommonTraits::ConstDiscreteFunctionType* fem_solution);

  //! this one runs cg-fem sim if mandated by config
  ErrorCalculator(const Problem::ProblemContainer& problem, const std::unique_ptr<LocalsolutionProxy>& msfem_solution);

  /** Compute and print errors between exact, msfem and fem solution
   *
   *  This computes the errors between the exact solution, the msfem solution
   *  and the fem solution (if they exist respectively). The results are printed
   *  to the given ostream and returned in a std::map.
   *
   *  \param[in] out The ostream for error printing
   *  \return Returns the computed errors as std::map with the following entries:
   *          - "msfem_exact_L2" The L2 error between the msfem solution and the
   *            exact solution
   *          - "msfem_exact_H1" The H1 error between the msfem solution and the
   *            exact solution
   *          - "fem_exact_L2" The L2 error between the fem solution and the
   *            exact solution
   *          - "fem_exact_H1" The H1 error between the fem solution and the
   *            exact solution
   *          - "msfem_fem_L2" The L2 error between the msfem solution and the
   *            fem solution
   *          Here, each entry will only be present if the corresponding error was
   *          computed.
   */
  std::map<std::string, double> print(std::ostream& out);

private:
  const DMP::ProblemContainer& problem_;
  const std::unique_ptr<LocalsolutionProxy>& msfem_solution_;
  std::unique_ptr<CommonTraits::DiscreteFunctionType> fem_solution_ptr_;
  std::unique_ptr<CommonTraits::DiscreteFunctionType> coarse_fem_solution_ptr_;
  CommonTraits::ConstDiscreteFunctionType* fem_solution_;
  std::unique_ptr<Elliptic_FEM_Solver> fem_solver_;
};

} // namespace Multiscale
} // namespace Dune

#endif // ERROR_CALC_HH
<commit_msg>forgot timing member in error_calc<commit_after>#ifndef ERROR_CALC_HH
#define ERROR_CALC_HH

#include <dune/multiscale/common/traits.hh>
#include <dune/multiscale/problems/selector.hh>
#include <dune/multiscale/msfem/localsolution_proxy.hh>
#include <iosfwd>
#include <memory>

namespace Dune {
namespace Multiscale {

class Elliptic_FEM_Solver;
class LocalsolutionProxy;

class ErrorCalculator {

public:
  ErrorCalculator(const Problem::ProblemContainer& problem, const std::unique_ptr<LocalsolutionProxy>& msfem_solution,
                  CommonTraits::ConstDiscreteFunctionType* fem_solution);

  //! this one runs cg-fem sim if mandated by config
  ErrorCalculator(const Problem::ProblemContainer& problem, const std::unique_ptr<LocalsolutionProxy>& msfem_solution);

  /** Compute and print errors between exact, msfem and fem solution
   *
   *  This computes the errors between the exact solution, the msfem solution
   *  and the fem solution (if they exist respectively). The results are printed
   *  to the given ostream and returned in a std::map.
   *
   *  \param[in] out The ostream for error printing
   *  \return Returns the computed errors as std::map with the following entries:
   *          - "msfem_exact_L2" The L2 error between the msfem solution and the
   *            exact solution
   *          - "msfem_exact_H1" The H1 error between the msfem solution and the
   *            exact solution
   *          - "fem_exact_L2" The L2 error between the fem solution and the
   *            exact solution
   *          - "fem_exact_H1" The H1 error between the fem solution and the
   *            exact solution
   *          - "msfem_fem_L2" The L2 error between the msfem solution and the
   *            fem solution
   *          Here, each entry will only be present if the corresponding error was
   *          computed.
   */
  std::map<std::string, double> print(std::ostream& out);

private:
  const DMP::ProblemContainer& problem_;
  const std::unique_ptr<LocalsolutionProxy>& msfem_solution_;
  std::unique_ptr<CommonTraits::DiscreteFunctionType> fem_solution_ptr_;
  std::unique_ptr<CommonTraits::DiscreteFunctionType> coarse_fem_solution_ptr_;
  CommonTraits::ConstDiscreteFunctionType* fem_solution_;
  std::unique_ptr<Elliptic_FEM_Solver> fem_solver_;
  DSC::ScopedTiming timing_;
};

} // namespace Multiscale
} // namespace Dune

#endif // ERROR_CALC_HH
<|endoftext|>


<commit_before>Int_t FindKrClustersRaw(const char *fileName="data.root"){

  //define tree
  TFile *hfile=new TFile("adc.root","RECREATE","ADC file");
  // Create a ROOT Tree
  TTree *mytree = new TTree("Kr","Krypton cluster tree");

  AliRawReader *reader = new AliRawReaderRoot(fileName);
  //AliRawReader *reader = new AliRawReaderDate(fileName);
  reader->Reset();

  TStopwatch timer;
  timer.Start();

  AliAltroRawStreamFast* stream = new AliAltroRawStreamFast(reader);
  stream->SelectRawData("TPC");

  //one general output
  AliTPCclustererKr *clusters = new AliTPCclustererKr();
  clusters->SetOutput(mytree);
  clusters->SetRecoParam(0);

  //only for geometry parameters loading - temporarly
  AliRunLoader* rl = AliRunLoader::Open("galice.root");
  AliTPCParam *param=(AliTPCParamSR *)gDirectory->Get("75x40_100x60_150x60");
  //if (!param) {cerr<<"TPC parameters have not been found !\n"; return 4;}
  clusters->SetParam(param);

  Int_t evtnr=0;
  while (reader->NextEvent()) {
    //output for each event
    //  AliTPCclustererKr *clusters = new AliTPCclustererKr();
    //  clusters->SetOutput(mytree);

    //if(evtnr++<35)continue;
    cout<<"Evt = "<<evtnr<<endl;
    clusters->finderIO(reader);
    evtnr++;

  }

  //mytree->Print();//print rootuple summary
  // Save all objects in this file
  hfile->Write();
  // Close the file
  hfile->Close();

  timer.Stop();
  timer.Print();

  delete stream;

  return 0;
}
<commit_msg>Avoid using of RunLoaders (Marian)<commit_after>Int_t FindKrClustersRaw(const char *fileName="data.root"){

  //define tree
  TFile *hfile=new TFile("KryptonCl.root","RECREATE","ADC file");
  // Create a ROOT Tree
  TTree *mytree = new TTree("Kr","Krypton cluster tree");

  AliRawReader *reader = new AliRawReaderRoot(fileName);
  //AliRawReader *reader = new AliRawReaderDate(fileName);
  reader->Reset();

  TStopwatch timer;
  timer.Start();

  AliAltroRawStreamFast* stream = new AliAltroRawStreamFast(reader);
  stream->SelectRawData("TPC");

  //one general output
  AliTPCclustererKr *clusters = new AliTPCclustererKr();
  clusters->SetOutput(mytree);
  clusters->SetRecoParam(0);

  //only for geometry parameters loading - temporarly
  //AliRunLoader* rl = AliRunLoader::Open("galice.root");
  //AliTPCParam *param=(AliTPCParamSR *)gDirectory->Get("75x40_100x60_150x60");
  AliTPCParam *param=new AliTPCParam;
  param->SetTSample(1.00000002337219485e-07);
  param->Update();
  //if (!param) {cerr<<"TPC parameters have not been found !\n"; return 4;}
  clusters->SetParam(param);

  Int_t evtnr=0;
  while (reader->NextEvent()) {
    //output for each event
    cout<<"Evt = "<<evtnr<<endl;
    clusters->finderIO(reader);
    evtnr++;
  }

  //mytree->Print();//print rootuple summary
  // Save all objects in this file
  hfile->Write();
  // Close the file
  hfile->Close();

  timer.Stop();
  timer.Print();

  delete stream;

  return 0;
}
<|endoftext|>


<commit_before>//Includes.
#include <fstream>
#include <iostream>
#include <string>
#include "game.h"
#include "main.h"
#include "baseFunctions.h"

//We'll just use what we need.
using std::cout;
using std::cin;
using std::string;
using std::getline;
using std::ifstream;
using std::ofstream;

void cls();
void prompt(string tPrompt);
void mainMenu();

//Initialize the saves.
int sLoop = 0;
int amtSaves = 0;

//Game variables.
int code = 0;
int spreadRate = 0;
int speedOfDestruction = 0;
int stealth = 0;
int crypter = 0;
int optimization = 0;

game::game()
{

}

void newGame()
{
    //Start a new game.
    cls();
    cout << "Loading...\n";
    ifstream checkSave("saves.vatk");

    //Check if the save exists, if it does, ask the user to overwrite it. If it doesn't, make it, and write to it.
ifchksv:    if (checkSave)
    {
        int i = 0;
        cout << "Saved game exists, overwrite it?\n";
        cout << " 1 = YES | 2 = NO \n";
        cout << "Overwrite? > ";
        cin >> i;
        if (cin.fail())
        {
            cls();
            cin.clear(); cin.ignore(); cin.sync();
            prompt("Invalid input. Press enter to continue.\n");
            cls();
            goto ifchksv;
        } else
            {
                if (i != 0)
                {
                    checkSave.close();
                    remove("saves.vatk");
                } else
                    {
                        checkSave.close();
                        mainMenu();
                    }
            }
    } else
        {
            checkSave.close();
            ofstream createSave("saves.vatk");
            createSave << "code:" << code << "\n";
            createSave << "spreadRate:" << spreadRate << "\n";
            createSave << "speedOfDestruction:" << speedOfDestruction << "\n";
            createSave << "stealth:" << stealth << "\n";
            createSave << "crypter:" << crypter << "\n";
            createSave << "optimization:" << optimization << "\n";
            createSave.close();
        }

    cout << "Save created.\n";
    prompt("I haven't developed farther yet.");
    cls();
    mainMenu();

}

void saveGame()
{
    //Save the game.

}

void loadGame()
{
    //Load the game.

}
<commit_msg>Just a space<commit_after>//Includes.
#include <fstream>
#include <iostream>
#include <string>
#include "game.h"
#include "main.h"
#include "baseFunctions.h"

//We'll just use what we need.
using std::cout;
using std::cin;
using std::string;
using std::getline;
using std::ifstream;
using std::ofstream;

void cls();
void prompt(string tPrompt);
void mainMenu();

//Initialize the saves.
int sLoop = 0;
int amtSaves = 0;

//Game variables.
int code = 0;
int spreadRate = 0;
int speedOfDestruction = 0;
int stealth = 0;
int crypter = 0;
int optimization = 0;

game::game()
{

}

void newGame()
{
    //Start a new game.
    cls();
    cout << "Loading...\n";
    ifstream checkSave("saves.vatk");

    //Check if the save exists, if it does, ask the user to overwrite it. If it doesn't, make it, and write to it.
ifchksv:    if (checkSave)
    {
        int i = 0;
        cout << "Saved game exists, overwrite it?\n";
        cout << " 1 = YES | 2 = NO \n";
        cout << "Overwrite? > ";
        cin >> i;
        if (cin.fail())
        {
            cls();
            cin.clear(); cin.ignore(); cin.sync();
            prompt("Invalid input. Press enter to continue.\n");
            cls();
            goto ifchksv;
        } else
            {
                if (i != 0)
                {
                    checkSave.close();
                    remove("saves.vatk");
                } else
                    {
                        checkSave.close();
                        mainMenu();
                    }
            }
    } else
        {
            checkSave.close();
            ofstream createSave("saves.vatk");
            createSave << "code:" << code << "\n";
            createSave << "spreadRate:" << spreadRate << "\n";
            createSave << "speedOfDestruction:" << speedOfDestruction << "\n";
            createSave << "stealth:" << stealth << "\n";
            createSave << "crypter:" << crypter << "\n";
            createSave << "optimization:" << optimization << "\n";
            createSave.close();
        }

    cout << "Save created.\n";
    prompt("I haven't developed farther yet.");
    cls();
    mainMenu();

}

void saveGame()
{
    //Save the game.

}

void loadGame()
{
    //Load the game.

}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "file_request.hxx"
#include "static_headers.hxx"
#include "HttpResponseHandler.hxx"
#include "strmap.hxx"
#include "istream/UnusedPtr.hxx"
#include "istream/FileIstream.hxx"
#include "pool/pool.hxx"
#include "io/Open.hxx"
#include "io/UniqueFileDescriptor.hxx"
#include "system/Error.hxx"
#include "http/Status.h"

#include <assert.h>
#include <sys/stat.h>
#include <fcntl.h>

void
static_file_get(EventLoop &event_loop, struct pool &pool,
		const char *path, const char *content_type,
		HttpResponseHandler &handler)
{
	assert(path != nullptr);

	UniqueFileDescriptor fd;
	struct stat st;

	try {
		fd = OpenReadOnly(path, O_NOFOLLOW);
		if (fstat(fd.Get(), &st) < 0)
			throw FormatErrno("Failed to stat %s", path);
	} catch (...) {
		handler.InvokeError(std::current_exception());
		return;
	}

	FdType fd_type = FdType::FD_FILE;
	off_t size = st.st_size;

	if (S_ISCHR(st.st_mode)) {
		fd_type = FdType::FD_CHARDEV;
		size = -1;
	} else if (!S_ISREG(st.st_mode)) {
		handler.InvokeResponse(pool, HTTP_STATUS_NOT_FOUND,
				       "Not a regular file");
		return;
	}

	auto headers = static_response_headers(pool, fd, st, content_type);

	handler.InvokeResponse(HTTP_STATUS_OK,
			       std::move(headers),
			       istream_file_fd_new(event_loop, pool, path,
						   std::move(fd), fd_type,
						   size));
}
<commit_msg>file_request: use FdIstream for FD_CHARDEV<commit_after>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "file_request.hxx"
#include "static_headers.hxx"
#include "HttpResponseHandler.hxx"
#include "strmap.hxx"
#include "istream/UnusedPtr.hxx"
#include "istream/FileIstream.hxx"
#include "istream/FdIstream.hxx"
#include "pool/pool.hxx"
#include "io/Open.hxx"
#include "io/UniqueFileDescriptor.hxx"
#include "system/Error.hxx"
#include "http/Status.h"

#include <assert.h>
#include <sys/stat.h>
#include <fcntl.h>

void
static_file_get(EventLoop &event_loop, struct pool &pool,
		const char *path, const char *content_type,
		HttpResponseHandler &handler)
{
	assert(path != nullptr);

	UniqueFileDescriptor fd;
	struct stat st;

	try {
		fd = OpenReadOnly(path, O_NOFOLLOW);
		if (fstat(fd.Get(), &st) < 0)
			throw FormatErrno("Failed to stat %s", path);
	} catch (...) {
		handler.InvokeError(std::current_exception());
		return;
	}

	if (S_ISCHR(st.st_mode)) {
		handler.InvokeResponse(HTTP_STATUS_OK, {},
				       NewFdIstream(event_loop, pool, path,
						    std::move(fd),
						    FdType::FD_CHARDEV));
		return;
	} else if (!S_ISREG(st.st_mode)) {
		handler.InvokeResponse(pool, HTTP_STATUS_NOT_FOUND,
				       "Not a regular file");
		return;
	}

	auto headers = static_response_headers(pool, fd, st, content_type);

	handler.InvokeResponse(HTTP_STATUS_OK,
			       std::move(headers),
			       istream_file_fd_new(event_loop, pool, path,
						   std::move(fd), FdType::FD_FILE,
						   st.st_size));
}
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2009-2015 Juan Francisco Crespo Galán
*
* 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 "fx/Convolver.h"

#include <math.h>
#include <algorithm>
#include <cstring>

AUD_NAMESPACE_BEGIN
Convolver::Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
	m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_irLength(irLength), m_threadPool(threadPool), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast<unsigned int>(m_irBuffers->size() - 1))), m_tailCounter(0)

{
	m_resetFlag = false;
	m_futures.resize(m_numThreads);
	for(int i = 0; i < m_irBuffers->size(); i++)
	{
		m_fftConvolvers.push_back(std::unique_ptr<FFTConvolver>(new FFTConvolver((*m_irBuffers)[i], plan)));
		m_delayLine.push_front((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
	}

	m_accBuffer = (fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex));
	for(int i = 0; i < m_numThreads; i++)
		m_threadAccBuffers.push_back((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
}

Convolver::~Convolver()
{
	m_resetFlag = true;
	for(auto &fut : m_futures)
		if(fut.valid())
			fut.get();

	std::free(m_accBuffer);
	for(auto buf : m_threadAccBuffers)
		std::free(buf);
	while(!m_delayLine.empty())
	{
		std::free(m_delayLine.front());
		m_delayLine.pop_front();
	}
}

void Convolver::getNext(sample_t* inBuffer, sample_t* outBuffer, int& length, bool& eos)
{
	if(length > m_L)
	{
		length = 0;
		eos = m_tailCounter >= m_delayLine.size();
		return;
	}

	eos = false;
	for(auto &fut : m_futures)
		if(fut.valid())
			fut.get();

	if(inBuffer != nullptr)
		m_fftConvolvers[0]->getNextFDL(inBuffer, m_accBuffer, length, m_delayLine[0]);
	else
	{
		m_tailCounter++;
		std::memset(m_delayLine[0], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
	}
	m_delayLine.push_front(m_delayLine.back());
	m_delayLine.pop_back();
	m_fftConvolvers[0]->IFFT_FDL(m_accBuffer, outBuffer, length);
	std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));

	if(m_tailCounter >= m_delayLine.size() -1 && inBuffer == nullptr)
	{
		eos = true;
		/*length = m_irLength%m_M;
		if(m_tailCounter > m_delayLine.size() - 1)
			length = 0;*/
	}
	else
		for(int i = 0; i < m_futures.size(); i++)
			m_futures[i] = m_threadPool->enqueue(&Convolver::threadFunction, this, i);
}

void Convolver::reset()
{
	m_resetFlag = true;
	for(auto &fut : m_futures)
		if(fut.valid())
			fut.get();

	for(int i = 0; i < m_delayLine.size();i++)
		std::memset(m_delayLine[i], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
	for(int i = 0; i < m_fftConvolvers.size(); i++)
		m_fftConvolvers[i]->clear();
	std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
	m_tailCounter = 0;

	m_resetFlag = false;
}

std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>> Convolver::getImpulseResponse()
{
	return m_irBuffers;
}

void Convolver::setImpulseResponse(std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>> ir)
{
	reset();
	m_irBuffers = ir;
	for(int i = 0; i < m_irBuffers->size(); i++)
		m_fftConvolvers[i]->setImpulseResponse((*m_irBuffers)[i]);
}

bool Convolver::threadFunction(int id)
{
	int total = m_irBuffers->size();
	int share = std::ceil(((float)total - 1) / (float)m_numThreads);
	int start = id*share + 1;
	int end = std::min(start + share, total);

	std::memset(m_threadAccBuffers[id], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));

	for(int i = start; i < end && !m_resetFlag; i++)
		m_fftConvolvers[i]->getNextFDL(m_delayLine[i], m_threadAccBuffers[id]);

	m_sumMutex.lock();
	for(int i = 0; (i < m_N / 2 + 1) && !m_resetFlag; i++)
	{
		m_accBuffer[i][0] += m_threadAccBuffers[id][i][0];
		m_accBuffer[i][1] += m_threadAccBuffers[id][i][1];
	}
	m_sumMutex.unlock();
	return true;
}
AUD_NAMESPACE_END
<commit_msg>Some fixes to the Convolver class<commit_after>/*******************************************************************************
* Copyright 2009-2015 Juan Francisco Crespo Galán
*
* 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 "fx/Convolver.h"

#include <math.h>
#include <algorithm>
#include <cstring>

AUD_NAMESPACE_BEGIN
Convolver::Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
	m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_irLength(irLength), m_threadPool(threadPool), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast<unsigned int>(m_irBuffers->size() - 1))), m_tailCounter(0)

{
	m_resetFlag = false;
	m_futures.resize(m_numThreads);
	for(int i = 0; i < m_irBuffers->size(); i++)
	{
		m_fftConvolvers.push_back(std::unique_ptr<FFTConvolver>(new FFTConvolver((*m_irBuffers)[i], plan)));
		m_delayLine.push_front((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
	}

	m_accBuffer = (fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex));
	for(int i = 0; i < m_numThreads; i++)
		m_threadAccBuffers.push_back((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
}

Convolver::~Convolver()
{
	m_resetFlag = true;
	for(auto &fut : m_futures)
		if(fut.valid())
			fut.get();

	std::free(m_accBuffer);
	for(auto buf : m_threadAccBuffers)
		std::free(buf);
	while(!m_delayLine.empty())
	{
		std::free(m_delayLine.front());
		m_delayLine.pop_front();
	}
}

void Convolver::getNext(sample_t* inBuffer, sample_t* outBuffer, int& length, bool& eos)
{
	if(length > m_L)
	{
		length = 0;
		eos = m_tailCounter >= m_delayLine.size();
		return;
	}

	eos = false;
	for(auto &fut : m_futures)
		if(fut.valid())
			fut.get();

	if(inBuffer != nullptr)
		m_fftConvolvers[0]->getNextFDL(inBuffer, m_accBuffer, length, m_delayLine[0]);
	else
	{
		m_tailCounter++;
		std::memset(outBuffer, 0, m_L*sizeof(sample_t));
		m_fftConvolvers[0]->getNextFDL(outBuffer, m_accBuffer, length, m_delayLine[0]);
		//std::memset(m_delayLine[0], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
	}
	m_delayLine.push_front(m_delayLine.back());
	m_delayLine.pop_back();
	length = m_L;
	m_fftConvolvers[0]->IFFT_FDL(m_accBuffer, outBuffer, length);
	std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));

	if(m_tailCounter >= m_delayLine.size() && inBuffer == nullptr)
	{
		eos = true;
		/*length = m_irLength%m_M;
		if(m_tailCounter > m_delayLine.size() - 1)
			length = 0;*/
	}
	else
		for(int i = 0; i < m_futures.size(); i++)
			m_futures[i] = m_threadPool->enqueue(&Convolver::threadFunction, this, i);
}

void Convolver::reset()
{
	m_resetFlag = true;
	for(auto &fut : m_futures)
		if(fut.valid())
			fut.get();

	for(int i = 0; i < m_delayLine.size();i++)
		std::memset(m_delayLine[i], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
	for(int i = 0; i < m_fftConvolvers.size(); i++)
		m_fftConvolvers[i]->clear();
	std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
	m_tailCounter = 0;

	m_resetFlag = false;
}

std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>> Convolver::getImpulseResponse()
{
	return m_irBuffers;
}

void Convolver::setImpulseResponse(std::shared_ptr<std::vector<std::shared_ptr<std::vector<fftwf_complex>>>> ir)
{
	reset();
	m_irBuffers = ir;
	for(int i = 0; i < m_irBuffers->size(); i++)
		m_fftConvolvers[i]->setImpulseResponse((*m_irBuffers)[i]);
}

bool Convolver::threadFunction(int id)
{
	int total = m_irBuffers->size();
	int share = std::ceil(((float)total - 1) / (float)m_numThreads);
	int start = id*share + 1;
	int end = std::min(start + share, total);

	std::memset(m_threadAccBuffers[id], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));

	for(int i = start; i < end && !m_resetFlag; i++)
		m_fftConvolvers[i]->getNextFDL(m_delayLine[i], m_threadAccBuffers[id]);

	m_sumMutex.lock();
	for(int i = 0; (i < m_N / 2 + 1) && !m_resetFlag; i++)
	{
		m_accBuffer[i][0] += m_threadAccBuffers[id][i][0];
		m_accBuffer[i][1] += m_threadAccBuffers[id][i][1];
	}
	m_sumMutex.unlock();
	return true;
}
AUD_NAMESPACE_END
<|endoftext|>


<commit_before>/*
 * GAMS - General Algebraic Modeling System C++ API
 *
 * Copyright (c) 2017-2020 GAMS Software GmbH <support@gams.com>
 * Copyright (c) 2017-2020 GAMS Development Corp. <support@gams.com>
 *
 * 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.
 */

#ifdef _WIN32
#include "Windows.h"
#endif

#include "gamsplatform.h"
#include <QDir>
#include <QStandardPaths>
#include <QStringList>
#include <QSettings>
#include <QProcess>
#include <string>
#include <iostream>
#include <sstream>
#include "gamspath.h"
#include "gamsenum.h"
#include "gamslog.h"
#include "gamsexception.h"

namespace gams {

using namespace std;

#ifdef __linux__ // Linux
const char cEnvSep = ':';
const char *cPathSep = "/";
const char *cCmpFileName = "gmscmpun.txt";
const int cExitCodeDiv = 256;
const char *cExeSuffix = "";
const char *cLibPrefix = "lib";
const char *cLibSuffix = ".so";
const char *cLibEnv = "LD_LIBRARY_PATH";
#elif __APPLE__ // Apple iOS
const char cEnvSep = ':';
const char *cPathSep = "/";
const char *cCmpFileName = "gmscmpun.txt";
const int cExitCodeDiv = 256;
const char *cExeSuffix = "";
const char *cLibPrefix = "lib";
const char *cLibSuffix = ".dylib";
const char *cLibEnv = "DYLD_LIBRARY_PATH";
#elif __unix__ // other *nix
const char cEnvSep = ':';
const char *cPathSep = "/";
const char *cCmpFileName = "gmscmpun.txt";
const int cExitCodeDiv = 256;
const char *cExeSuffix = "";
const char *cLibPrefix = "lib";
const char *cLibSuffix = ".so";
const char *cLibEnv = "LD_LIBRARY_PATH";
#else // Windows
const char cEnvSep = ';';
const char *cLibEnv = "";                   // JM: unused until now
const char *cPathSep = "\\";
const char *cCmpFileName = "gmscmpnt.txt";
const int cExitCodeDiv = 1;
const char *cExeSuffix = ".exe";
const char *cLibPrefix = "";
const char *cLibSuffix = ".dll";
#endif

std::string GAMSPlatform::findGams(LogId logId)
{
#ifdef __linux__
    return findGamsOnLinux(logId);
#elif __APPLE__
    return findGamsOnApple(logId);
#elif __unix__
    return findGamsOnLinux(logId);
#else
    return findGamsOnWindows(logId);
#endif
}

void GAMSPlatform::ensureEnvPathContains(const char *dirName)
{
#ifdef __linux__
    ensureEnvPathSetOnLinux(dirName);
#elif __APPLE__
    ensureEnvPathSetOnApple(dirName);
#elif __unix__
    ensureEnvPathSetOnLinux(dirName);
#else
    ensureEnvPathSetOnWindows(dirName);
#endif
}

bool GAMSPlatform::interrupt(long pid)
{
#ifdef __linux__
    return interruptOnNonWindows(pid);
#elif __APPLE__
    return interruptOnNonWindows(pid);
#elif __unix__
    return interruptOnNonWindows(pid);
#else
    return interruptOnWindows(pid);
#endif
}

std::string GAMSPlatform::findGamsOnLinux(LogId logId)
{
    QString gamsDir;
    QString gamsDirLD;

    QStringList envSplit = QString(qgetenv("PATH")).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDir = envStr;
            break;
        }
    }
    if (!gamsDir.isEmpty() && LoggerPool::instance().debug(logId) == GAMSEnum::DebugLevel::Off)
        return gamsDir.toStdString();

    envSplit = QString(qgetenv(cLibEnv)).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDirLD = envStr;
            break;
        }
    }
    if (gamsDir.isEmpty())
        return gamsDirLD.toStdString();
    else if (!gamsDirLD.isEmpty() && gamsDir != gamsDirLD) {
        DEB_S(logId) << "--- Warning: Found GAMS system directory " << gamsDir << " in PATH and a different one" << endl
                     << "---          in (DY)LD_LIBRARY_PATH (" << gamsDirLD << "). The latter is ignored.";
    }

    return gamsDir.toStdString();

}

void GAMSPlatform::ensureEnvPathSetOnLinux(const char *dirName)
{
    Q_UNUSED(dirName)
}

bool GAMSPlatform::interruptOnNonWindows(long pid)
{
    QProcess proc;
    proc.setProgram("/bin/bash");

    //start "kill" with List of children PID
    proc.setProgram("/bin/bash");
    QStringList s2 { "-c", "kill -2 " + QString::number(pid)};
    proc.setArguments(s2);
    proc.start();

    proc.waitForFinished(-1);
    return true;
}

std::string GAMSPlatform::findGamsOnApple(LogId logId)
{
    QString gamsDir;
    QString gamsDirLD;

    QStringList envSplit = QString(qgetenv("PATH")).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDir = envStr;
            break;
        }
    }
    if (!gamsDir.isEmpty() && LoggerPool::instance().debug(logId) == GAMSEnum::DebugLevel::Off)
        return gamsDir.toStdString();

    envSplit = QString(qgetenv(cLibEnv)).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDirLD = envStr;
            break;
        }
    }
    if (gamsDir.isEmpty())
        return gamsDirLD.toStdString();
    else if (!gamsDirLD.isEmpty() && gamsDir != gamsDirLD) {
        DEB_S(logId) << "--- Warning: Found GAMS system directory " << gamsDir << " in PATH and a different one" << endl
                     << "---          in (DY)LD_LIBRARY_PATH (" << gamsDirLD << "). The latter is ignored.";
    }

    return gamsDir.toStdString();

}

void GAMSPlatform::ensureEnvPathSetOnApple(const char *dirName)
{
    Q_UNUSED(dirName)
}

std::string GAMSPlatform::findGamsOnWindows(LogId logId)
{
#ifdef NO_WINDOWS_REGISTRY
    Q_UNUSED(logId)
    QString gamsPath = QFileInfo(QStandardPaths::findExecutable("gams")).absolutePath();
    return QDir::cleanPath(gamsPath).toStdString();
#else
    QString firstFound("");
    QStringList locations;
    locations << "HKEY_CURRENT_USER\\" << "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\";
    for (QString loc: locations) {
        QString gamsPath = QSettings(loc + "gams.location", QSettings::NativeFormat).value(".").toString();
        if (!gamsPath.isEmpty()) {

            if (LoggerPool::instance().debug(logId) == GAMSEnum::DebugLevel::Off) {
                return gamsPath.toStdString();
            } else if (firstFound.isNull()) {
                firstFound = gamsPath;
            } else {
                // compare second key
                if (firstFound.isEmpty()) {
                    return gamsPath.toStdString();
                } else if (!gamsPath.isEmpty() && (gamsPath != firstFound)) {
                    DEB_S(logId) << "--- Warning: Found GAMS system directory " << firstFound.toStdString() << " at HKEY_CURRENT_USER and a different one\n"
                                 << "---          in HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\ (" << gamsPath.toStdString() << "). The latter is ignored.";
                }
                return firstFound.toStdString();
            }
        }
    }
    return firstFound.toStdString();

#endif
}

void GAMSPlatform::ensureEnvPathSetOnWindows(const char *dirName)
{
    QByteArray envPath = qgetenv("PATH");
    if (!envPath.contains(dirName)) {
        qputenv("PATH", envPath + ";" + dirName);
    }
}

bool GAMSPlatform::interruptOnWindows(long pid)
{
#ifdef _WIN32
    COPYDATASTRUCT cds;

    string stem = "___GAMSMSGWINDOW___";
    string pidStr = QString::number(pid).toUtf8().constData();
    string windowName = stem + pidStr;

    HWND receiver = FindWindow(nullptr, windowName.c_str());
    if (!receiver)
        return false;

    char lpData[] = "GAMS Message Interrupt";
    cds.dwData = 1;
    cds.lpData = lpData;
    cds.cbData = sizeof(lpData);

    SendMessageA(receiver, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds);

    return true;
#else
    Q_UNUSED(pid)
    throw GAMSException("interruptOnWindows only impemented on Windows");
#endif
}

} // namespace gams
<commit_msg>Adapted to changed registry usage of installer<commit_after>/*
 * GAMS - General Algebraic Modeling System C++ API
 *
 * Copyright (c) 2017-2020 GAMS Software GmbH <support@gams.com>
 * Copyright (c) 2017-2020 GAMS Development Corp. <support@gams.com>
 *
 * 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.
 */

#ifdef _WIN32
#include "Windows.h"
#endif

#include "gamsplatform.h"
#include <QDir>
#include <QStandardPaths>
#include <QStringList>
#include <QSettings>
#include <QProcess>
#include <string>
#include <iostream>
#include <sstream>
#include "gamspath.h"
#include "gamsenum.h"
#include "gamslog.h"
#include "gamsexception.h"

namespace gams {

using namespace std;

#ifdef __linux__ // Linux
const char cEnvSep = ':';
const char *cPathSep = "/";
const char *cCmpFileName = "gmscmpun.txt";
const int cExitCodeDiv = 256;
const char *cExeSuffix = "";
const char *cLibPrefix = "lib";
const char *cLibSuffix = ".so";
const char *cLibEnv = "LD_LIBRARY_PATH";
#elif __APPLE__ // Apple iOS
const char cEnvSep = ':';
const char *cPathSep = "/";
const char *cCmpFileName = "gmscmpun.txt";
const int cExitCodeDiv = 256;
const char *cExeSuffix = "";
const char *cLibPrefix = "lib";
const char *cLibSuffix = ".dylib";
const char *cLibEnv = "DYLD_LIBRARY_PATH";
#elif __unix__ // other *nix
const char cEnvSep = ':';
const char *cPathSep = "/";
const char *cCmpFileName = "gmscmpun.txt";
const int cExitCodeDiv = 256;
const char *cExeSuffix = "";
const char *cLibPrefix = "lib";
const char *cLibSuffix = ".so";
const char *cLibEnv = "LD_LIBRARY_PATH";
#else // Windows
const char cEnvSep = ';';
const char *cLibEnv = "";                   // JM: unused until now
const char *cPathSep = "\\";
const char *cCmpFileName = "gmscmpnt.txt";
const int cExitCodeDiv = 1;
const char *cExeSuffix = ".exe";
const char *cLibPrefix = "";
const char *cLibSuffix = ".dll";
#endif

std::string GAMSPlatform::findGams(LogId logId)
{
#ifdef __linux__
    return findGamsOnLinux(logId);
#elif __APPLE__
    return findGamsOnApple(logId);
#elif __unix__
    return findGamsOnLinux(logId);
#else
    return findGamsOnWindows(logId);
#endif
}

void GAMSPlatform::ensureEnvPathContains(const char *dirName)
{
#ifdef __linux__
    ensureEnvPathSetOnLinux(dirName);
#elif __APPLE__
    ensureEnvPathSetOnApple(dirName);
#elif __unix__
    ensureEnvPathSetOnLinux(dirName);
#else
    ensureEnvPathSetOnWindows(dirName);
#endif
}

bool GAMSPlatform::interrupt(long pid)
{
#ifdef __linux__
    return interruptOnNonWindows(pid);
#elif __APPLE__
    return interruptOnNonWindows(pid);
#elif __unix__
    return interruptOnNonWindows(pid);
#else
    return interruptOnWindows(pid);
#endif
}

std::string GAMSPlatform::findGamsOnLinux(LogId logId)
{
    QString gamsDir;
    QString gamsDirLD;

    QStringList envSplit = QString(qgetenv("PATH")).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDir = envStr;
            break;
        }
    }
    if (!gamsDir.isEmpty() && LoggerPool::instance().debug(logId) == GAMSEnum::DebugLevel::Off)
        return gamsDir.toStdString();

    envSplit = QString(qgetenv(cLibEnv)).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDirLD = envStr;
            break;
        }
    }
    if (gamsDir.isEmpty())
        return gamsDirLD.toStdString();
    else if (!gamsDirLD.isEmpty() && gamsDir != gamsDirLD) {
        DEB_S(logId) << "--- Warning: Found GAMS system directory " << gamsDir << " in PATH and a different one" << endl
                     << "---          in (DY)LD_LIBRARY_PATH (" << gamsDirLD << "). The latter is ignored.";
    }

    return gamsDir.toStdString();

}

void GAMSPlatform::ensureEnvPathSetOnLinux(const char *dirName)
{
    Q_UNUSED(dirName)
}

bool GAMSPlatform::interruptOnNonWindows(long pid)
{
    QProcess proc;
    proc.setProgram("/bin/bash");

    //start "kill" with List of children PID
    proc.setProgram("/bin/bash");
    QStringList s2 { "-c", "kill -2 " + QString::number(pid)};
    proc.setArguments(s2);
    proc.start();

    proc.waitForFinished(-1);
    return true;
}

std::string GAMSPlatform::findGamsOnApple(LogId logId)
{
    QString gamsDir;
    QString gamsDirLD;

    QStringList envSplit = QString(qgetenv("PATH")).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDir = envStr;
            break;
        }
    }
    if (!gamsDir.isEmpty() && LoggerPool::instance().debug(logId) == GAMSEnum::DebugLevel::Off)
        return gamsDir.toStdString();

    envSplit = QString(qgetenv(cLibEnv)).split(cEnvSep);
    for (QString envStr: envSplit) {
        if ((GAMSPath(envStr) / "gams").exists()) {
            gamsDirLD = envStr;
            break;
        }
    }
    if (gamsDir.isEmpty())
        return gamsDirLD.toStdString();
    else if (!gamsDirLD.isEmpty() && gamsDir != gamsDirLD) {
        DEB_S(logId) << "--- Warning: Found GAMS system directory " << gamsDir << " in PATH and a different one" << endl
                     << "---          in (DY)LD_LIBRARY_PATH (" << gamsDirLD << "). The latter is ignored.";
    }

    return gamsDir.toStdString();

}

void GAMSPlatform::ensureEnvPathSetOnApple(const char *dirName)
{
    Q_UNUSED(dirName)
}

std::string GAMSPlatform::findGamsOnWindows(LogId logId)
{
#ifdef NO_WINDOWS_REGISTRY
    Q_UNUSED(logId)
    QString gamsPath = QFileInfo(QStandardPaths::findExecutable("gams")).absolutePath();
    return QDir::cleanPath(gamsPath).toStdString();
#else
    QString firstFound("");
    QStringList locations;
    locations << "HKEY_CURRENT_USER\\Software\\Classes\\" << "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\";
    for (QString loc: locations) {
        QString gamsPath = QSettings(loc + "gams.location", QSettings::NativeFormat).value(".").toString();
        if (!gamsPath.isEmpty()) {

            if (LoggerPool::instance().debug(logId) == GAMSEnum::DebugLevel::Off) {
                return gamsPath.toStdString();
            } else if (firstFound.isNull()) {
                firstFound = gamsPath;
            } else {
                // compare second key
                if (firstFound.isEmpty()) {
                    return gamsPath.toStdString();
                } else if (!gamsPath.isEmpty() && (gamsPath != firstFound)) {
                    DEB_S(logId) << "--- Warning: Found GAMS system directory " << firstFound.toStdString() << " at "
                                 << locations.first() << " and a different one\n"
                                 << "---          in "
                                 << locations.last() << " (" << gamsPath.toStdString() << "). The latter is ignored.";
                }
                return firstFound.toStdString();
            }
        }
    }
    return firstFound.toStdString();

#endif
}

void GAMSPlatform::ensureEnvPathSetOnWindows(const char *dirName)
{
    QByteArray envPath = qgetenv("PATH");
    if (!envPath.contains(dirName)) {
        qputenv("PATH", envPath + ";" + dirName);
    }
}

bool GAMSPlatform::interruptOnWindows(long pid)
{
#ifdef _WIN32
    COPYDATASTRUCT cds;

    string stem = "___GAMSMSGWINDOW___";
    string pidStr = QString::number(pid).toUtf8().constData();
    string windowName = stem + pidStr;

    HWND receiver = FindWindow(nullptr, windowName.c_str());
    if (!receiver)
        return false;

    char lpData[] = "GAMS Message Interrupt";
    cds.dwData = 1;
    cds.lpData = lpData;
    cds.cbData = sizeof(lpData);

    SendMessageA(receiver, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds);

    return true;
#else
    Q_UNUSED(pid)
    throw GAMSException("interruptOnWindows only impemented on Windows");
#endif
}

} // namespace gams
<|endoftext|>


<commit_before>#include "ANGLETest.h"

class BufferDataTest : public ANGLETest
{
protected:
    BufferDataTest()
        : mBuffer(0),
          mProgram(0),
          mAttribLocation(-1)
    {
        setWindowWidth(16);
        setWindowHeight(16);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
    }

    virtual void SetUp()
    {
        ANGLETest::SetUp();

        const char * vsSource = SHADER_SOURCE
        (
            attribute vec4 position;
            attribute float in_attrib;
            varying float v_attrib;
            void main()
            {
                v_attrib = in_attrib;
                gl_Position = position;
            }
        );

        const char * fsSource = SHADER_SOURCE
        (
            precision mediump float;
            varying float v_attrib;
            void main()
            {
                gl_FragColor = vec4(v_attrib, 0, 0, 1);
            }
        );

        glGenBuffers(1, &mBuffer);
        ASSERT_NE(mBuffer, 0U);

        mProgram = compileProgram(vsSource, fsSource);
        ASSERT_NE(mProgram, 0U);

        mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
        ASSERT_NE(mAttribLocation, -1);

        glClearColor(0, 0, 0, 0);
        glClearDepthf(0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDisable(GL_DEPTH_TEST);

        ASSERT_GL_NO_ERROR();
    }

    virtual void TearDown()
    {
        glDeleteBuffers(1, &mBuffer);
        glDeleteProgram(mProgram);

        ANGLETest::TearDown();
    }

    GLuint mBuffer;
    GLuint mProgram;
    GLint mAttribLocation;
};

TEST_F(BufferDataTest, null_data)
{
    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    EXPECT_GL_NO_ERROR();

    const int numIterations = 128;
    for (int i = 0; i < numIterations; ++i)
    {
        GLsizei bufferSize = sizeof(GLfloat) * (i + 1);
        glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW);
        EXPECT_GL_NO_ERROR();

        for (int j = 0; j < bufferSize; j++)
        {
            for (int k = 0; k < bufferSize - j; k++)
            {
                glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL);
                EXPECT_GL_NO_ERROR();
            }
        }
    }
}

TEST_F(BufferDataTest, zero_nonnull_data)
{
    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    EXPECT_GL_NO_ERROR();

    char *zeroData = new char[0];
    glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
    EXPECT_GL_NO_ERROR();

    delete [] zeroData;
}

TEST_F(BufferDataTest, huge_setdata_should_not_crash)
{
    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    EXPECT_GL_NO_ERROR();

    // use as large a size as possible without causing an exception
    GLsizei hugeSize = (1 << 30);

    // on x64, use as large a GLsizei value as possible
    if (sizeof(size_t) > 4)
    {
        hugeSize = std::numeric_limits<GLsizei>::max();
    }

    char *data = new (std::nothrow) char[hugeSize];
    EXPECT_NE((char * const)NULL, data);

    if (data == NULL)
    {
        return;
    }

    memset(data, 0, hugeSize);

    float * fValue = reinterpret_cast<float*>(data);
    for (unsigned int f = 0; f < 6; f++)
    {
        fValue[f] = 1.0f;
    }

    glBufferData(GL_ARRAY_BUFFER, hugeSize, data, GL_STATIC_DRAW);

    GLenum error = glGetError();
    if (error == GL_NO_ERROR)
    {
        // If we didn't fail because of an out of memory error, try drawing a quad
        // using the large buffer

        // DISABLED because it takes a long time, but left for posterity

        //glUseProgram(mProgram);
        //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
        //glEnableVertexAttribArray(mAttribLocation);
        //glBindBuffer(GL_ARRAY_BUFFER, 0);
        //drawQuad(mProgram, "position", 0.5f);
        //swapBuffers();

        //// Draw operations can also generate out-of-memory, which is in-spec
        //error = glGetError();
        //if (error == GL_NO_ERROR)
        //{
        //    GLint viewportSize[4];
        //    glGetIntegerv(GL_VIEWPORT, viewportSize);

        //    GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
        //    GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;

        //    EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
        //}
        //else
        //{
        //    EXPECT_EQ(GL_OUT_OF_MEMORY, error);
        //}
    }
    else
    {
        EXPECT_EQ(GL_OUT_OF_MEMORY, error);
    }

    delete[] data;
}

<commit_msg>Fix buffer tests.<commit_after>#include "ANGLETest.h"

class BufferDataTest : public ANGLETest
{
protected:
    BufferDataTest()
        : mBuffer(0),
          mProgram(0),
          mAttribLocation(-1)
    {
        setWindowWidth(16);
        setWindowHeight(16);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
    }

    virtual void SetUp()
    {
        ANGLETest::SetUp();

        const char * vsSource = SHADER_SOURCE
        (
            attribute vec4 position;
            attribute float in_attrib;
            varying float v_attrib;
            void main()
            {
                v_attrib = in_attrib;
                gl_Position = position;
            }
        );

        const char * fsSource = SHADER_SOURCE
        (
            precision mediump float;
            varying float v_attrib;
            void main()
            {
                gl_FragColor = vec4(v_attrib, 0, 0, 1);
            }
        );

        glGenBuffers(1, &mBuffer);
        ASSERT_NE(mBuffer, 0U);

        mProgram = compileProgram(vsSource, fsSource);
        ASSERT_NE(mProgram, 0U);

        mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
        ASSERT_NE(mAttribLocation, -1);

        glClearColor(0, 0, 0, 0);
        glClearDepthf(0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDisable(GL_DEPTH_TEST);

        ASSERT_GL_NO_ERROR();
    }

    virtual void TearDown()
    {
        glDeleteBuffers(1, &mBuffer);
        glDeleteProgram(mProgram);

        ANGLETest::TearDown();
    }

    GLuint mBuffer;
    GLuint mProgram;
    GLint mAttribLocation;
};

TEST_F(BufferDataTest, NULLData)
{
    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    EXPECT_GL_NO_ERROR();

    const int numIterations = 128;
    for (int i = 0; i < numIterations; ++i)
    {
        GLsizei bufferSize = sizeof(GLfloat) * (i + 1);
        glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW);
        EXPECT_GL_NO_ERROR();

        for (int j = 0; j < bufferSize; j++)
        {
            for (int k = 0; k < bufferSize - j; k++)
            {
                glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL);
                EXPECT_GL_NO_ERROR();
            }
        }
    }
}

TEST_F(BufferDataTest, ZeroNonNULLData)
{
    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    EXPECT_GL_NO_ERROR();

    char *zeroData = new char[0];
    glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData);
    EXPECT_GL_NO_ERROR();

    delete [] zeroData;
}

TEST_F(BufferDataTest, HugeSetDataShouldNotCrash)
{
    glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    EXPECT_GL_NO_ERROR();

    // use as large a size as possible without causing an exception
    GLsizei hugeSize = (1 << 29);

    // on x64, use as large a GLsizei value as possible
    if (sizeof(size_t) > 4)
    {
        hugeSize = std::numeric_limits<GLsizei>::max();
    }

    char *data = new (std::nothrow) char[hugeSize];
    ASSERT_NE((char * const)NULL, data);

    if (data == NULL)
    {
        return;
    }

    memset(data, 0, hugeSize);

    float * fValue = reinterpret_cast<float*>(data);
    for (unsigned int f = 0; f < 6; f++)
    {
        fValue[f] = 1.0f;
    }

    glBufferData(GL_ARRAY_BUFFER, hugeSize, data, GL_STATIC_DRAW);

    GLenum error = glGetError();
    if (error == GL_NO_ERROR)
    {
        // If we didn't fail because of an out of memory error, try drawing a quad
        // using the large buffer

        // DISABLED because it takes a long time, but left for posterity

        //glUseProgram(mProgram);
        //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL);
        //glEnableVertexAttribArray(mAttribLocation);
        //glBindBuffer(GL_ARRAY_BUFFER, 0);
        //drawQuad(mProgram, "position", 0.5f);
        //swapBuffers();

        //// Draw operations can also generate out-of-memory, which is in-spec
        //error = glGetError();
        //if (error == GL_NO_ERROR)
        //{
        //    GLint viewportSize[4];
        //    glGetIntegerv(GL_VIEWPORT, viewportSize);

        //    GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2;
        //    GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2;

        //    EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255);
        //}
        //else
        //{
        //    EXPECT_EQ(GL_OUT_OF_MEMORY, error);
        //}
    }
    else
    {
        EXPECT_EQ(GL_OUT_OF_MEMORY, error);
    }

    delete[] data;
}

<|endoftext|>


<commit_before>#include <QtTest/QtTest>

#include "debug.h"

#include <TSettings.h>

class TestConsoleLog : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();

    void basic();
    void saveMessage();
};

void TestConsoleLog::initTestCase()
{
    QCoreApplication::setOrganizationName(TEST_NAME);
}

void TestConsoleLog::cleanupTestCase()
{
    TSettings::destroy();
}

void TestConsoleLog::basic()
{
    ConsoleLog &log = ConsoleLog::instance();
    (void)log;
}

void TestConsoleLog::saveMessage()
{
    ConsoleLog &log = ConsoleLog::instance();
    TSettings   settings;

    // Don't record this message
    log << "don't write this";

    // Save a message
    settings.setValue("app/save_console_log", true);
    log << "write this";

    // Disable saving again
    settings.setValue("app/save_console_log", false);
    log << "don't write this";
}

QTEST_MAIN(TestConsoleLog)
#include "test-consolelog.moc"
<commit_msg>tests/consolelog: add initializeConsoleLog()<commit_after>#include <QtTest/QtTest>

#include "debug.h"

#include <TSettings.h>

class TestConsoleLog : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();

    void basic();
    void initializeConsoleLog();
    void saveMessage();
};

void TestConsoleLog::initTestCase()
{
    QCoreApplication::setOrganizationName(TEST_NAME);
}

void TestConsoleLog::cleanupTestCase()
{
    TSettings::destroy();
}

void TestConsoleLog::basic()
{
    ConsoleLog &log = ConsoleLog::instance();
    (void)log;
}

void TestConsoleLog::initializeConsoleLog()
{
    ConsoleLog::instance().initializeConsoleLog();
}

void TestConsoleLog::saveMessage()
{
    ConsoleLog &log = ConsoleLog::instance();
    TSettings   settings;

    // Don't record this message
    log << "don't write this";

    // Save a message
    settings.setValue("app/save_console_log", true);
    log << "write this";

    // Disable saving again
    settings.setValue("app/save_console_log", false);
    log << "don't write this";
}

QTEST_MAIN(TestConsoleLog)
#include "test-consolelog.moc"
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors

// 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.

#ifndef SOL_STATE_VIEW_HPP
#define SOL_STATE_VIEW_HPP

#include "error.hpp"
#include "table.hpp"
#include "load_result.hpp"
#include <memory>

namespace sol {
enum class lib : char {
    base,
    package,
    coroutine,
    string,
    os,
    math,
    table,
    debug,
    bit32,
    io,
    ffi,
    jit,
    count
};

class state_view {
private:
    lua_State* L;
    table reg;
    global_table global;
public:
    typedef typename global_table::iterator iterator;
    typedef typename global_table::const_iterator const_iterator;

    state_view(lua_State* L):
    L(L),
    reg(L, LUA_REGISTRYINDEX),
    global(L, detail::global_) {

    }

    lua_State* lua_state() const {
        return L;
    }

    template<typename... Args>
    void open_libraries(Args&&... args) {
        static_assert(meta::are_same<lib, Args...>::value, "all types must be libraries");
        if(sizeof...(args) == 0) {
            luaL_openlibs(L);
            return;
        }

        lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };

        for(auto&& library : libraries) {
            switch(library) {
#if SOL_LUA_VERSION <= 501 && defined(SOL_LUAJIT)
            case lib::coroutine:
#endif // luajit opens coroutine base stuff
            case lib::base:
                luaL_requiref(L, "base", luaopen_base, 1);
                lua_pop(L, 1);
                break;
            case lib::package:
                luaL_requiref(L, "package", luaopen_package, 1);
                lua_pop(L, 1);
                break;
#if !defined(SOL_LUAJIT)
            case lib::coroutine:
#if SOL_LUA_VERSION > 501
                luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
                lua_pop(L, 1);
#endif // Lua 5.2+ only
                break;
#endif // Not LuaJIT
            case lib::string:
                luaL_requiref(L, "string", luaopen_string, 1);
                lua_pop(L, 1);
                break;
            case lib::table:
                luaL_requiref(L, "table", luaopen_table, 1);
                lua_pop(L, 1);
                break;
            case lib::math:
                luaL_requiref(L, "math", luaopen_math, 1);
                lua_pop(L, 1);
                break;
            case lib::bit32:
#ifdef SOL_LUAJIT
                luaL_requiref(L, "bit32", luaopen_bit, 1);
                lua_pop(L, 1);
#elif SOL_LUA_VERSION == 502
                luaL_requiref(L, "bit32", luaopen_bit32, 1);
                lua_pop(L, 1);
#else
#endif // Lua 5.2 only (deprecated in 5.3 (503))
                break;
            case lib::io:
                luaL_requiref(L, "io", luaopen_io, 1);
                lua_pop(L, 1);
                break;
            case lib::os:
                luaL_requiref(L, "os", luaopen_os, 1);
                lua_pop(L, 1);
                break;
            case lib::debug:
                luaL_requiref(L, "debug", luaopen_debug, 1);
                lua_pop(L, 1);
                break;
            case lib::ffi:
#ifdef SOL_LUAJIT
                luaL_requiref(L, "ffi", luaopen_ffi, 1);
#endif
                break;
            case lib::jit:
#ifdef SOL_LUAJIT
                luaL_requiref(L, "jit", luaopen_jit, 1);
#endif
                break;
            case lib::count:
            default:
                break;
            }
        }
    }

    void script(const std::string& code) {
        if(luaL_dostring(L, code.c_str())) {
            lua_error(L);
        }
    }

    void script_file(const std::string& filename) {
        if(luaL_dofile(L, filename.c_str())) {
            lua_error(L);
        }
    }

    load_result load(const std::string& code) {
        load_status x = static_cast<load_status>(luaL_loadstring(L, code.c_str()));
        return load_result(L, -1, 1, 1, x);
    }

    load_result load_file(const std::string& filename) {
        load_status x = static_cast<load_status>(luaL_loadfile(L, filename.c_str()));
        return load_result(L, -1, 1, 1, x);
    }

	load_result load_buffer(const char *buff, size_t size, const char *name)
	{
		load_status x = static_cast<load_status>(luaL_loadbuffer(L, buff, size, name));
		return load_result(L, -1, 1, 1, x);
	}

    iterator begin () const {
        return global.begin();
    }

    iterator end() const {
        return global.end();
    }

    const_iterator cbegin() const {
        return global.cbegin();
    }

    const_iterator cend() const {
        return global.cend();
    }

    global_table globals() const {
        return global;
    }

    table registry() const {
        return reg;
    }

    operator lua_State* () const {
        return lua_state();
    }

    void set_panic(lua_CFunction panic){
        lua_atpanic(L, panic);
    }

    template<typename... Args, typename... Keys>
    decltype(auto) get(Keys&&... keys) const {
        return global.get<Args...>(std::forward<Keys>(keys)...);
    }

    template<typename T, typename Key>
    decltype(auto) get_or(Key&& key, T&& otherwise) const {
        return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
    }

    template<typename T, typename Key, typename D>
    decltype(auto) get_or(Key&& key, D&& otherwise) const {
        return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
    }

    template<typename... Args>
    state_view& set(Args&&... args) {
        global.set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T, typename... Keys>
    decltype(auto) traverse_get(Keys&&... keys) const {
        return global.traverse_get<T>(std::forward<Keys>(keys)...);
    }

    template<typename... Args>
    state_view& traverse_set(Args&&... args) {
        global.traverse_set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T>
    state_view& set_usertype(usertype<T>& user) {
        return set_usertype(usertype_traits<T>::name, user);
    }

    template<typename Key, typename T>
    state_view& set_usertype(Key&& key, usertype<T>& user) {
        global.set_usertype(std::forward<Key>(key), user);
        return *this;
    }

    template<typename Class, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename CTor0, typename... CTor, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename... CArgs, typename... Args>
    state_view& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
        global.new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
        return *this;
    }

    template <typename Fx>
    void for_each(Fx&& fx) {
        global.for_each(std::forward<Fx>(fx));
    }

    template<typename T>
    proxy<global_table&, T> operator[](T&& key) {
        return global[std::forward<T>(key)];
    }

    template<typename T>
    proxy<const global_table&, T> operator[](T&& key) const {
        return global[std::forward<T>(key)];
    }

    template<typename Sig, typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template<typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template <typename Name>
    table create_table(Name&& name, int narr = 0, int nrec = 0) {
        return global.create(std::forward<Name>(name), narr, nrec);
    }

    template <typename Name, typename Key, typename Value, typename... Args>
    table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename Name, typename... Args>
    table create_named_table(Name&& name, Args&&... args) {
        table x = global.create_with(std::forward<Args>(args)...);
        global.set(std::forward<Name>(name), x);
        return x;
    }

    table create_table(int narr = 0, int nrec = 0) {
        return create_table(lua_state(), narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    table create_table_with(Args&&... args) {
        return create_table_with(lua_state(), std::forward<Args>(args)...);
    }

    static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
        return global_table::create(L, narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    static inline table create_table_with(lua_State* L, Args&&... args) {
        return global_table::create_with(L, std::forward<Args>(args)...);
    }
};
} // sol

#endif // SOL_STATE_VIEW_HPP
<commit_msg>flesh out load buffer a little bit<commit_after>// The MIT License (MIT)

// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors

// 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.

#ifndef SOL_STATE_VIEW_HPP
#define SOL_STATE_VIEW_HPP

#include "error.hpp"
#include "table.hpp"
#include "load_result.hpp"
#include <memory>

namespace sol {
enum class lib : char {
    base,
    package,
    coroutine,
    string,
    os,
    math,
    table,
    debug,
    bit32,
    io,
    ffi,
    jit,
    count
};

class state_view {
private:
    lua_State* L;
    table reg;
    global_table global;
public:
    typedef typename global_table::iterator iterator;
    typedef typename global_table::const_iterator const_iterator;

    state_view(lua_State* L):
    L(L),
    reg(L, LUA_REGISTRYINDEX),
    global(L, detail::global_) {

    }

    lua_State* lua_state() const {
        return L;
    }

    template<typename... Args>
    void open_libraries(Args&&... args) {
        static_assert(meta::are_same<lib, Args...>::value, "all types must be libraries");
        if(sizeof...(args) == 0) {
            luaL_openlibs(L);
            return;
        }

        lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };

        for(auto&& library : libraries) {
            switch(library) {
#if SOL_LUA_VERSION <= 501 && defined(SOL_LUAJIT)
            case lib::coroutine:
#endif // luajit opens coroutine base stuff
            case lib::base:
                luaL_requiref(L, "base", luaopen_base, 1);
                lua_pop(L, 1);
                break;
            case lib::package:
                luaL_requiref(L, "package", luaopen_package, 1);
                lua_pop(L, 1);
                break;
#if !defined(SOL_LUAJIT)
            case lib::coroutine:
#if SOL_LUA_VERSION > 501
                luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
                lua_pop(L, 1);
#endif // Lua 5.2+ only
                break;
#endif // Not LuaJIT
            case lib::string:
                luaL_requiref(L, "string", luaopen_string, 1);
                lua_pop(L, 1);
                break;
            case lib::table:
                luaL_requiref(L, "table", luaopen_table, 1);
                lua_pop(L, 1);
                break;
            case lib::math:
                luaL_requiref(L, "math", luaopen_math, 1);
                lua_pop(L, 1);
                break;
            case lib::bit32:
#ifdef SOL_LUAJIT
                luaL_requiref(L, "bit32", luaopen_bit, 1);
                lua_pop(L, 1);
#elif SOL_LUA_VERSION == 502
                luaL_requiref(L, "bit32", luaopen_bit32, 1);
                lua_pop(L, 1);
#else
#endif // Lua 5.2 only (deprecated in 5.3 (503))
                break;
            case lib::io:
                luaL_requiref(L, "io", luaopen_io, 1);
                lua_pop(L, 1);
                break;
            case lib::os:
                luaL_requiref(L, "os", luaopen_os, 1);
                lua_pop(L, 1);
                break;
            case lib::debug:
                luaL_requiref(L, "debug", luaopen_debug, 1);
                lua_pop(L, 1);
                break;
            case lib::ffi:
#ifdef SOL_LUAJIT
                luaL_requiref(L, "ffi", luaopen_ffi, 1);
#endif
                break;
            case lib::jit:
#ifdef SOL_LUAJIT
                luaL_requiref(L, "jit", luaopen_jit, 1);
#endif
                break;
            case lib::count:
            default:
                break;
            }
        }
    }

    void script(const std::string& code) {
        if(luaL_dostring(L, code.c_str())) {
            lua_error(L);
        }
    }

    void script_file(const std::string& filename) {
        if(luaL_dofile(L, filename.c_str())) {
            lua_error(L);
        }
    }

    load_result load(const std::string& code) {
        load_status x = static_cast<load_status>(luaL_loadstring(L, code.c_str()));
        return load_result(L, -1, 1, 1, x);
    }

    load_result load_file(const std::string& filename) {
        load_status x = static_cast<load_status>(luaL_loadfile(L, filename.c_str()));
        return load_result(L, -1, 1, 1, x);
    }

    load_result load_buffer(const char *buff, size_t size, const char *name, const char* mode = nullptr) {
        load_status x = static_cast<load_status>(luaL_loadbufferx(L, buff, size, name, mode));
        return load_result(L, -1, 1, 1, x);
    }

    iterator begin () const {
        return global.begin();
    }

    iterator end() const {
        return global.end();
    }

    const_iterator cbegin() const {
        return global.cbegin();
    }

    const_iterator cend() const {
        return global.cend();
    }

    global_table globals() const {
        return global;
    }

    table registry() const {
        return reg;
    }

    operator lua_State* () const {
        return lua_state();
    }

    void set_panic(lua_CFunction panic){
        lua_atpanic(L, panic);
    }

    template<typename... Args, typename... Keys>
    decltype(auto) get(Keys&&... keys) const {
        return global.get<Args...>(std::forward<Keys>(keys)...);
    }

    template<typename T, typename Key>
    decltype(auto) get_or(Key&& key, T&& otherwise) const {
        return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
    }

    template<typename T, typename Key, typename D>
    decltype(auto) get_or(Key&& key, D&& otherwise) const {
        return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
    }

    template<typename... Args>
    state_view& set(Args&&... args) {
        global.set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T, typename... Keys>
    decltype(auto) traverse_get(Keys&&... keys) const {
        return global.traverse_get<T>(std::forward<Keys>(keys)...);
    }

    template<typename... Args>
    state_view& traverse_set(Args&&... args) {
        global.traverse_set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T>
    state_view& set_usertype(usertype<T>& user) {
        return set_usertype(usertype_traits<T>::name, user);
    }

    template<typename Key, typename T>
    state_view& set_usertype(Key&& key, usertype<T>& user) {
        global.set_usertype(std::forward<Key>(key), user);
        return *this;
    }

    template<typename Class, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename CTor0, typename... CTor, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename... CArgs, typename... Args>
    state_view& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
        global.new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
        return *this;
    }

    template <typename Fx>
    void for_each(Fx&& fx) {
        global.for_each(std::forward<Fx>(fx));
    }

    template<typename T>
    proxy<global_table&, T> operator[](T&& key) {
        return global[std::forward<T>(key)];
    }

    template<typename T>
    proxy<const global_table&, T> operator[](T&& key) const {
        return global[std::forward<T>(key)];
    }

    template<typename Sig, typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template<typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template <typename Name>
    table create_table(Name&& name, int narr = 0, int nrec = 0) {
        return global.create(std::forward<Name>(name), narr, nrec);
    }

    template <typename Name, typename Key, typename Value, typename... Args>
    table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename Name, typename... Args>
    table create_named_table(Name&& name, Args&&... args) {
        table x = global.create_with(std::forward<Args>(args)...);
        global.set(std::forward<Name>(name), x);
        return x;
    }

    table create_table(int narr = 0, int nrec = 0) {
        return create_table(lua_state(), narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    table create_table_with(Args&&... args) {
        return create_table_with(lua_state(), std::forward<Args>(args)...);
    }

    static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
        return global_table::create(L, narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    static inline table create_table_with(lua_State* L, Args&&... args) {
        return global_table::create_with(L, std::forward<Args>(args)...);
    }
};
} // sol

#endif // SOL_STATE_VIEW_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2019-2021 Morwenn
 * SPDX-License-Identifier: MIT
 */
#include <algorithm>
#include <forward_list>
#include <iterator>
#include <list>
#include <vector>
#include <catch2/catch.hpp>
#include <cpp-sort/sorters.h>
#include <testing-tools/distributions.h>
#include <testing-tools/memory_exhaustion.h>

//
// Specific tests to check that a selection of sorters still run fine
// even when there isn't any extra heap memory available
//
// These tests shouldn't be part of the main test suite executable
//

TEMPLATE_TEST_CASE( "test heap exhaustion for random-access sorters", "[sorters][heap_exhaustion]",
                    cppsort::grail_sorter<>,
                    cppsort::heap_sorter,
                    cppsort::insertion_sorter,
                    cppsort::merge_sorter,
                    cppsort::pdq_sorter,
                    cppsort::quick_merge_sorter,
                    cppsort::quick_sorter,
                    cppsort::selection_sorter,
                    cppsort::ska_sorter,
                    cppsort::smooth_sorter,
                    cppsort::split_sorter,
                    cppsort::std_sorter,
                    cppsort::wiki_sorter<> )
{
    std::vector<int> collection; collection.reserve(491);
    auto distribution = dist::shuffled{};
    distribution(std::back_inserter(collection), 491, -125);

    using sorter = TestType;
    {
        scoped_memory_exhaustion _;
        sorter{}(collection);
    }
    CHECK( std::is_sorted(std::begin(collection), std::end(collection)) );
}

TEMPLATE_TEST_CASE( "test heap exhaustion for bidirectional sorters", "[sorters][heap_exhaustion]",
                    cppsort::insertion_sorter,
                    cppsort::merge_sorter,
                    cppsort::quick_merge_sorter,
                    cppsort::quick_sorter,
                    cppsort::selection_sorter )
{
    std::list<int> collection;
    auto distribution = dist::shuffled{};
    distribution(std::back_inserter(collection), 491, -125);

    using sorter = TestType;
    {
        scoped_memory_exhaustion _;
        sorter{}(collection);
    }
    CHECK( std::is_sorted(std::begin(collection), std::end(collection)) );
}

TEMPLATE_TEST_CASE( "test heap exhaustion for forward sorters", "[sorters][heap_exhaustion]",
                    cppsort::merge_sorter,
                    cppsort::quick_merge_sorter,
                    cppsort::quick_sorter,
                    cppsort::selection_sorter )
{
    std::forward_list<int> collection;
    auto distribution = dist::shuffled{};
    distribution(std::front_inserter(collection), 491, -125);

    using sorter = TestType;
    {
        scoped_memory_exhaustion _;
        sorter{}(collection);
    }
    CHECK( std::is_sorted(std::begin(collection), std::end(collection)) );
}
<commit_msg>Slightly more consistent test names<commit_after>/*
 * Copyright (c) 2019-2021 Morwenn
 * SPDX-License-Identifier: MIT
 */
#include <algorithm>
#include <forward_list>
#include <iterator>
#include <list>
#include <vector>
#include <catch2/catch.hpp>
#include <cpp-sort/sorters.h>
#include <testing-tools/distributions.h>
#include <testing-tools/memory_exhaustion.h>

//
// Specific tests to check that a selection of sorters still run fine
// even when there isn't any extra heap memory available
//
// These tests shouldn't be part of the main test suite executable
//

TEMPLATE_TEST_CASE( "heap exhaustion for random-access sorters", "[sorters][heap_exhaustion]",
                    cppsort::grail_sorter<>,
                    cppsort::heap_sorter,
                    cppsort::insertion_sorter,
                    cppsort::merge_sorter,
                    cppsort::pdq_sorter,
                    cppsort::quick_merge_sorter,
                    cppsort::quick_sorter,
                    cppsort::selection_sorter,
                    cppsort::ska_sorter,
                    cppsort::smooth_sorter,
                    cppsort::split_sorter,
                    cppsort::std_sorter,
                    cppsort::wiki_sorter<> )
{
    std::vector<int> collection; collection.reserve(491);
    auto distribution = dist::shuffled{};
    distribution(std::back_inserter(collection), 491, -125);

    using sorter = TestType;
    {
        scoped_memory_exhaustion _;
        sorter{}(collection);
    }
    CHECK( std::is_sorted(std::begin(collection), std::end(collection)) );
}

TEMPLATE_TEST_CASE( "heap exhaustion for bidirectional sorters", "[sorters][heap_exhaustion]",
                    cppsort::insertion_sorter,
                    cppsort::merge_sorter,
                    cppsort::quick_merge_sorter,
                    cppsort::quick_sorter,
                    cppsort::selection_sorter )
{
    std::list<int> collection;
    auto distribution = dist::shuffled{};
    distribution(std::back_inserter(collection), 491, -125);

    using sorter = TestType;
    {
        scoped_memory_exhaustion _;
        sorter{}(collection);
    }
    CHECK( std::is_sorted(std::begin(collection), std::end(collection)) );
}

TEMPLATE_TEST_CASE( "heap exhaustion for forward sorters", "[sorters][heap_exhaustion]",
                    cppsort::merge_sorter,
                    cppsort::quick_merge_sorter,
                    cppsort::quick_sorter,
                    cppsort::selection_sorter )
{
    std::forward_list<int> collection;
    auto distribution = dist::shuffled{};
    distribution(std::front_inserter(collection), 491, -125);

    using sorter = TestType;
    {
        scoped_memory_exhaustion _;
        sorter{}(collection);
    }
    CHECK( std::is_sorted(std::begin(collection), std::end(collection)) );
}
<|endoftext|>