<commit_before>// vi:cin:et:sw=4 ts=4
//
//  drafter.cc
//
//  Created by Jiri Kratochvil on 2015-02-11
//  Copyright (c) 2015 Apiary Inc. All rights reserved.
//
//
//

#include <string>
#include <iostream>
#include <sstream>
#include <fstream>

#include <tr1/memory>
#include <tr1/shared_ptr.h>

#include "cmdline.h"

#include "snowcrash.h"
#include "SectionParserData.h"  // snowcrash::BlueprintParserOptions

#include "sos.h"
#include "sosJSON.h"
#include "sosYAML.h"

#include "SerializeAST.h"
#include "SerializeSourcemap.h"

namespace sc = snowcrash;

namespace config {
    static const std::string Program        = "drafter";

    static const std::string Output         = "output";
    static const std::string Format         = "format";
    static const std::string Render         = "render";
    static const std::string Sourcemap      = "sourcemap";
    static const std::string Validate       = "validate";
    static const std::string Version        = "version";
    static const std::string UseLineNumbers = "use-line-num";
};

struct Config {
    std::string input;
    bool lineNumbers;
    bool validate;
    std::string format;
    std::string sourceMap;
    std::string output;
};

void PrepareCommanLineParser(cmdline::parser& parser)
{
    parser.set_program_name(config::Program);

    parser.add<std::string>(config::Output,    'o', "save output AST into file", false);
    parser.add<std::string>(config::Format,    'f', "output AST format", false, "yaml", cmdline::oneof<std::string>("yaml", "json"));
    parser.add<std::string>(config::Sourcemap, 's', "export sourcemap AST into file", false);
    parser.add("help",                         'h', "display this help message");
    parser.add(config::Version ,               'v', "print Drafter version");
    parser.add(config::Validate,               'l', "validate input only, do not print AST");
    parser.add(config::UseLineNumbers ,        'u', "use line and row number instead of character index when printing annotation");

    std::stringstream ss;

    ss << "<input file>\n\n";
    ss << "API Blueprint Parser\n";
    ss << "If called without <input file>, 'drafter' will listen on stdin.\n";

    parser.footer(ss.str());
}

#define DRAFTER_VERSION_STRING "x.x.x"

void ValidateParsedCommandLine(const cmdline::parser& parser)
{
    if (parser.rest().size() > 1) {
        std::cerr << "one input file expected, got " << parser.rest().size() << std::endl;
        exit(EXIT_FAILURE);
    }

    if (parser.exist(config::Version)) {
        std::cout << DRAFTER_VERSION_STRING << std::endl;
        exit(EXIT_SUCCESS);
    }

}

void ParseCommadLineOptions(int argc, const char *argv[], /* out */Config& conf)
{
    cmdline::parser parser;
    PrepareCommanLineParser(parser);

    parser.parse_check(argc, argv);

    ValidateParsedCommandLine(parser);

    if (!parser.rest().empty()) {
        conf.input = parser.rest().front();
    }

    conf.lineNumbers = parser.exist(config::UseLineNumbers);
    conf.validate    = parser.exist(config::Validate);
    conf.format      = parser.get<std::string>(config::Format);
    conf.output      = parser.get<std::string>(config::Output);
    conf.sourceMap   = parser.get<std::string>(config::Sourcemap);
}

template<typename T>
struct dummy_deleter {
    void operator()(T* obj) const {
      // do nothing
    }
};

template<typename T> struct std_io_selector;

template<>
struct std_io_selector<std::ostream>{
    std::ostream* operator()() { return &std::cout; }
};

template<>
struct std_io_selector<std::istream>{
    std::istream* operator()() { return &std::cin; }
};

template <typename Stream> struct fstream_selector;

template<>
struct fstream_selector<std::istream>{
  typedef std::ifstream stream_type;
};

template<>
struct fstream_selector<std::ostream>{
  typedef std::ofstream stream_type;
};

template<typename T> struct file_io_selector;

template<>
struct file_io_selector<std::ofstream>{
    std::ofstream* operator()(const char* name) { return new std::ofstream(name); }
};

template<>
struct file_io_selector<std::ifstream>{
    std::ifstream* operator()(const char* name) { return new std::ifstream(name); }
};

template<typename T>
std::tr1::shared_ptr<T> CreateStreamFromName(const std::string& file)
{
    if(file.empty()) {
        return std::tr1::shared_ptr<T>(
            std_io_selector<T>()(),
            dummy_deleter<T>()
        );
    }

    typedef typename fstream_selector<T>::stream_type stream_type;
    std::tr1::shared_ptr<stream_type>stream(
        file_io_selector<stream_type>()(file.c_str())
    );
    stream->open(file.c_str());

    if (!stream->is_open()) {
      std::cerr << "fatal: unable to open file '" << file << "'\n";
      exit(EXIT_FAILURE);
    }

    return stream;
}

void Serialize(const std::string& out,
    const sos::Object& object,
    sos::Serialize* serializer)
{
    std::tr1::shared_ptr<std::ostream> stream = CreateStreamFromName<std::ostream>(out);
    serializer->process(object, *stream);
    *stream << std::endl;
}

sos::Serialize* CreateSerializer(const std::string& format)
{
    if(format == "json") {
        return new sos::SerializeJSON;
    } else if(format == "yaml") {
        return new sos::SerializeYAML;
    }

    std::cerr << "fatal: unknow serialization format: '" << format << "'\n";
    exit(EXIT_FAILURE);
}

/** structure contains starting and ending position of a error/warning. */
struct AnnotationPosition {
    size_t fromLine;
    size_t fromColumn;
    size_t toLine;
    size_t toColumn;
};

/**
 *  \brief Convert character index mapping to line and column number
 *  \param linesEndIndex Vector containing indexes of end line characters
 *  \param range Character index mapping as input
 *  \param out Position of the given range as output
 */
void GetLineFromMap(const std::vector<size_t>& linesEndIndex,
                    const mdp::Range& range,
                    AnnotationPosition& out)
{

    std::vector<size_t>::const_iterator annotationPositionIt;

    out.fromLine = 0;
    out.fromColumn = 0;
    out.toLine = 0;
    out.toColumn = 0;

    // Finds starting line and column position
    annotationPositionIt = std::upper_bound(linesEndIndex.begin(), linesEndIndex.end(), range.location) - 1;

    if (annotationPositionIt != linesEndIndex.end()) {

        out.fromLine = std::distance(linesEndIndex.begin(), annotationPositionIt) + 1;
        out.fromColumn = range.location - *annotationPositionIt + 1;
    }

    // Finds ending line and column position
    annotationPositionIt = std::lower_bound(linesEndIndex.begin(), linesEndIndex.end(), range.location + range.length) - 1;

    if (annotationPositionIt != linesEndIndex.end()) {

        out.toLine = std::distance(linesEndIndex.begin(), annotationPositionIt) + 1;
        out.toColumn = (range.location + range.length) - *annotationPositionIt + 1;

        if (*(annotationPositionIt + 1) == (range.location + range.length)) {
            out.toColumn--;
        }
    }
}

/**
 *  \brief Given the source returns the length of all the lines in source as a vector
 *  \param source Source data
 *  \param out Vector containing indexes of all end line character in source
 */
void GetLinesEndIndex(const std::string& source,
                      std::vector<size_t>& out)
{

    out.push_back(0);

    for (size_t i = 0; i < source.length(); i++) {

        if (source[i] == '\n') {
            out.push_back(i + 1);
        }
    }
}

/**
 *  \brief Print Markdown source annotation.
 *  \param prefix A string prefix for the annotation
 *  \param annotation An annotation to print
 *  \param source Source data
 *  \param isUseLineNumbers True if the annotations needs to be printed by line and column number
 */
void PrintAnnotation(const std::string& prefix,
                     const snowcrash::SourceAnnotation& annotation,
                     const std::string& source,
                     const bool isUseLineNumbers)
{

    std::cerr << prefix;

    if (annotation.code != sc::SourceAnnotation::OK) {
        std::cerr << " (" << annotation.code << ") ";
    }

    if (!annotation.message.empty()) {
        std::cerr << " " << annotation.message;
    }

    std::vector<size_t> linesEndIndex;

    if (isUseLineNumbers) {
        GetLinesEndIndex(source, linesEndIndex);
    }

    if (!annotation.location.empty()) {

        for (mdp::CharactersRangeSet::const_iterator it = annotation.location.begin();
             it != annotation.location.end();
             ++it) {

            if (isUseLineNumbers) {

                AnnotationPosition annotationPosition;
                GetLineFromMap(linesEndIndex, *it, annotationPosition);

                std::cerr << "; line " << annotationPosition.fromLine << ", column " << annotationPosition.fromColumn;
                std::cerr << " - line " << annotationPosition.toLine << ", column " << annotationPosition.toColumn;
            }
            else {

                std::cerr << ((it == annotation.location.begin()) ? " :" : ";");
                std::cerr << it->location << ":" << it->length;
            }
        }
    }

    std::cerr << std::endl;
}

/**
 *  \brief Print parser report to stderr.
 *  \param report A parser report to print
 *  \param source Source data
 *  \param isUseLineNumbers True if the annotations needs to be printed by line and column number
 */
void PrintReport(const snowcrash::Report& report,
                 const std::string& source,
                 const bool isUseLineNumbers)
{

    std::cerr << std::endl;

    if (report.error.code == sc::Error::OK) {
        std::cerr << "OK.\n";
    }
    else {
        PrintAnnotation("error:", report.error, source, isUseLineNumbers);
    }

    for (snowcrash::Warnings::const_iterator it = report.warnings.begin(); it != report.warnings.end(); ++it) {
        PrintAnnotation("warning:", *it, source, isUseLineNumbers);
    }
}

int main(int argc, const char *argv[])
{
    Config config;
    ParseCommadLineOptions(argc, argv, config);

    sc::BlueprintParserOptions options = 0;  // Or snowcrash::RequireBlueprintNameOption
    if(!config.sourceMap.empty()) {
        options |= snowcrash::ExportSourcemapOption;
    }

    std::stringstream inputStream;
    std::tr1::shared_ptr<std::istream> in = CreateStreamFromName<std::istream>(config.input);
    inputStream << in->rdbuf();

    sc::ParseResult<sc::Blueprint> blueprint;
    sc::parse(inputStream.str(), options, blueprint);

    if (!config.validate) {
        sos::Serialize* serializer = CreateSerializer(config.format);

        Serialize(config.output,
            snowcrash::WrapBlueprint(blueprint.node),
            serializer
            );

        Serialize(config.sourceMap,
            snowcrash::WrapBlueprintSourcemap(blueprint.sourceMap),
            serializer
            );

        delete serializer;
    }

    PrintReport(blueprint.report, inputStream.str(), config.lineNumbers);

    return blueprint.report.error.code;

}
<commit_msg>* rename Serialize() function to Serialization() dou to troubles on gcc 4.4<commit_after>// vi:cin:et:sw=4 ts=4
//
//  drafter.cc
//
//  Created by Jiri Kratochvil on 2015-02-11
//  Copyright (c) 2015 Apiary Inc. All rights reserved.
//
//
//

#include <string>
#include <iostream>
#include <sstream>
#include <fstream>

#include <tr1/memory>
#include <tr1/shared_ptr.h>

#include "cmdline.h"

#include "snowcrash.h"
#include "SectionParserData.h"  // snowcrash::BlueprintParserOptions

#include "sos.h"
#include "sosJSON.h"
#include "sosYAML.h"

#include "SerializeAST.h"
#include "SerializeSourcemap.h"

namespace sc = snowcrash;

namespace config {
    static const std::string Program        = "drafter";

    static const std::string Output         = "output";
    static const std::string Format         = "format";
    static const std::string Render         = "render";
    static const std::string Sourcemap      = "sourcemap";
    static const std::string Validate       = "validate";
    static const std::string Version        = "version";
    static const std::string UseLineNumbers = "use-line-num";
};

struct Config {
    std::string input;
    bool lineNumbers;
    bool validate;
    std::string format;
    std::string sourceMap;
    std::string output;
};

void PrepareCommanLineParser(cmdline::parser& parser)
{
    parser.set_program_name(config::Program);

    parser.add<std::string>(config::Output,    'o', "save output AST into file", false);
    parser.add<std::string>(config::Format,    'f', "output AST format", false, "yaml", cmdline::oneof<std::string>("yaml", "json"));
    parser.add<std::string>(config::Sourcemap, 's', "export sourcemap AST into file", false);
    parser.add("help",                         'h', "display this help message");
    parser.add(config::Version ,               'v', "print Drafter version");
    parser.add(config::Validate,               'l', "validate input only, do not print AST");
    parser.add(config::UseLineNumbers ,        'u', "use line and row number instead of character index when printing annotation");

    std::stringstream ss;

    ss << "<input file>\n\n";
    ss << "API Blueprint Parser\n";
    ss << "If called without <input file>, 'drafter' will listen on stdin.\n";

    parser.footer(ss.str());
}

#define DRAFTER_VERSION_STRING "x.x.x"

void ValidateParsedCommandLine(const cmdline::parser& parser)
{
    if (parser.rest().size() > 1) {
        std::cerr << "one input file expected, got " << parser.rest().size() << std::endl;
        exit(EXIT_FAILURE);
    }

    if (parser.exist(config::Version)) {
        std::cout << DRAFTER_VERSION_STRING << std::endl;
        exit(EXIT_SUCCESS);
    }

}

void ParseCommadLineOptions(int argc, const char *argv[], /* out */Config& conf)
{
    cmdline::parser parser;
    PrepareCommanLineParser(parser);

    parser.parse_check(argc, argv);

    ValidateParsedCommandLine(parser);

    if (!parser.rest().empty()) {
        conf.input = parser.rest().front();
    }

    conf.lineNumbers = parser.exist(config::UseLineNumbers);
    conf.validate    = parser.exist(config::Validate);
    conf.format      = parser.get<std::string>(config::Format);
    conf.output      = parser.get<std::string>(config::Output);
    conf.sourceMap   = parser.get<std::string>(config::Sourcemap);
}

template<typename T>
struct dummy_deleter {
    void operator()(T* obj) const {
      // do nothing
    }
};

template<typename T> struct std_io_selector;

template<>
struct std_io_selector<std::ostream>{
    std::ostream* operator()() { return &std::cout; }
};

template<>
struct std_io_selector<std::istream>{
    std::istream* operator()() { return &std::cin; }
};

template <typename Stream> struct fstream_selector;

template<>
struct fstream_selector<std::istream>{
  typedef std::ifstream stream_type;
};

template<>
struct fstream_selector<std::ostream>{
  typedef std::ofstream stream_type;
};

template<typename T> struct file_io_selector;

template<>
struct file_io_selector<std::ofstream>{
    std::ofstream* operator()(const char* name) { return new std::ofstream(name); }
};

template<>
struct file_io_selector<std::ifstream>{
    std::ifstream* operator()(const char* name) { return new std::ifstream(name); }
};

template<typename T>
std::tr1::shared_ptr<T> CreateStreamFromName(const std::string& file)
{
    if(file.empty()) {
        return std::tr1::shared_ptr<T>(
            std_io_selector<T>()(),
            dummy_deleter<T>()
        );
    }

    typedef typename fstream_selector<T>::stream_type stream_type;
    std::tr1::shared_ptr<stream_type>stream(
        file_io_selector<stream_type>()(file.c_str())
    );
    stream->open(file.c_str());

    if (!stream->is_open()) {
      std::cerr << "fatal: unable to open file '" << file << "'\n";
      exit(EXIT_FAILURE);
    }

    return stream;
}

void Serialization(const std::string& out,
    const sos::Object& object,
    sos::Serialize* serializer)
{
    std::tr1::shared_ptr<std::ostream> stream = CreateStreamFromName<std::ostream>(out);
    serializer->process(object, *stream);
    *stream << std::endl;
}

sos::Serialize* CreateSerializer(const std::string& format)
{
    if(format == "json") {
        return new sos::SerializeJSON;
    } else if(format == "yaml") {
        return new sos::SerializeYAML;
    }

    std::cerr << "fatal: unknow serialization format: '" << format << "'\n";
    exit(EXIT_FAILURE);
}

/** structure contains starting and ending position of a error/warning. */
struct AnnotationPosition {
    size_t fromLine;
    size_t fromColumn;
    size_t toLine;
    size_t toColumn;
};

/**
 *  \brief Convert character index mapping to line and column number
 *  \param linesEndIndex Vector containing indexes of end line characters
 *  \param range Character index mapping as input
 *  \param out Position of the given range as output
 */
void GetLineFromMap(const std::vector<size_t>& linesEndIndex,
                    const mdp::Range& range,
                    AnnotationPosition& out)
{

    std::vector<size_t>::const_iterator annotationPositionIt;

    out.fromLine = 0;
    out.fromColumn = 0;
    out.toLine = 0;
    out.toColumn = 0;

    // Finds starting line and column position
    annotationPositionIt = std::upper_bound(linesEndIndex.begin(), linesEndIndex.end(), range.location) - 1;

    if (annotationPositionIt != linesEndIndex.end()) {

        out.fromLine = std::distance(linesEndIndex.begin(), annotationPositionIt) + 1;
        out.fromColumn = range.location - *annotationPositionIt + 1;
    }

    // Finds ending line and column position
    annotationPositionIt = std::lower_bound(linesEndIndex.begin(), linesEndIndex.end(), range.location + range.length) - 1;

    if (annotationPositionIt != linesEndIndex.end()) {

        out.toLine = std::distance(linesEndIndex.begin(), annotationPositionIt) + 1;
        out.toColumn = (range.location + range.length) - *annotationPositionIt + 1;

        if (*(annotationPositionIt + 1) == (range.location + range.length)) {
            out.toColumn--;
        }
    }
}

/**
 *  \brief Given the source returns the length of all the lines in source as a vector
 *  \param source Source data
 *  \param out Vector containing indexes of all end line character in source
 */
void GetLinesEndIndex(const std::string& source,
                      std::vector<size_t>& out)
{

    out.push_back(0);

    for (size_t i = 0; i < source.length(); i++) {

        if (source[i] == '\n') {
            out.push_back(i + 1);
        }
    }
}

/**
 *  \brief Print Markdown source annotation.
 *  \param prefix A string prefix for the annotation
 *  \param annotation An annotation to print
 *  \param source Source data
 *  \param isUseLineNumbers True if the annotations needs to be printed by line and column number
 */
void PrintAnnotation(const std::string& prefix,
                     const snowcrash::SourceAnnotation& annotation,
                     const std::string& source,
                     const bool isUseLineNumbers)
{

    std::cerr << prefix;

    if (annotation.code != sc::SourceAnnotation::OK) {
        std::cerr << " (" << annotation.code << ") ";
    }

    if (!annotation.message.empty()) {
        std::cerr << " " << annotation.message;
    }

    std::vector<size_t> linesEndIndex;

    if (isUseLineNumbers) {
        GetLinesEndIndex(source, linesEndIndex);
    }

    if (!annotation.location.empty()) {

        for (mdp::CharactersRangeSet::const_iterator it = annotation.location.begin();
             it != annotation.location.end();
             ++it) {

            if (isUseLineNumbers) {

                AnnotationPosition annotationPosition;
                GetLineFromMap(linesEndIndex, *it, annotationPosition);

                std::cerr << "; line " << annotationPosition.fromLine << ", column " << annotationPosition.fromColumn;
                std::cerr << " - line " << annotationPosition.toLine << ", column " << annotationPosition.toColumn;
            }
            else {

                std::cerr << ((it == annotation.location.begin()) ? " :" : ";");
                std::cerr << it->location << ":" << it->length;
            }
        }
    }

    std::cerr << std::endl;
}

/**
 *  \brief Print parser report to stderr.
 *  \param report A parser report to print
 *  \param source Source data
 *  \param isUseLineNumbers True if the annotations needs to be printed by line and column number
 */
void PrintReport(const snowcrash::Report& report,
                 const std::string& source,
                 const bool isUseLineNumbers)
{

    std::cerr << std::endl;

    if (report.error.code == sc::Error::OK) {
        std::cerr << "OK.\n";
    }
    else {
        PrintAnnotation("error:", report.error, source, isUseLineNumbers);
    }

    for (snowcrash::Warnings::const_iterator it = report.warnings.begin(); it != report.warnings.end(); ++it) {
        PrintAnnotation("warning:", *it, source, isUseLineNumbers);
    }
}

int main(int argc, const char *argv[])
{
    Config config;
    ParseCommadLineOptions(argc, argv, config);

    sc::BlueprintParserOptions options = 0;  // Or snowcrash::RequireBlueprintNameOption
    if(!config.sourceMap.empty()) {
        options |= snowcrash::ExportSourcemapOption;
    }

    std::stringstream inputStream;
    std::tr1::shared_ptr<std::istream> in = CreateStreamFromName<std::istream>(config.input);
    inputStream << in->rdbuf();

    sc::ParseResult<sc::Blueprint> blueprint;
    sc::parse(inputStream.str(), options, blueprint);

    if (!config.validate) {
        sos::Serialize* serializer = CreateSerializer(config.format);

        Serialization(config.output,
            snowcrash::WrapBlueprint(blueprint.node),
            serializer
            );

        Serialization(config.sourceMap,
            snowcrash::WrapBlueprintSourcemap(blueprint.sourceMap),
            serializer
            );

        delete serializer;
    }

    PrintReport(blueprint.report, inputStream.str(), config.lineNumbers);

    return blueprint.report.error.code;

}
<|endoftext|>


<commit_before>//
// File:   csg_update.cc
// Author: ruehle
//
// Created on June 11, 2008, 10:31 AM
//

/// this is the most dirtyest program, clean it up, don't copy anything from here!!!

#define kB  8.3109*0.01

#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
#include <boost/program_options.hpp>
#include <tools/table.h>

using namespace std;

namespace po = boost::program_options;

int DoIBM(const string &in, const string &out, const string &target, const string &current, double T, double scalem, int Nsmooth);

int main(int argc, char** argv)
{
    string method, type;
    string action;
    string in, out;
    string target, current;
    int Nsmooth;
    double T, scale;

    // lets read in some program options
    // Declare the supported options.
    po::options_description desc("Allowed options");

    desc.add_options()
    ("help", "produce this help message")
    //("version", "show version info")
    ("in", boost::program_options::value<string>(&in), "file containing current potential")
    ("out", boost::program_options::value<string>(&out)->default_value("out.dat"), "file to write the new potential")
    ("cur", boost::program_options::value<string>(&current), "file containing current rdf")
    ("target", boost::program_options::value<string>(&target), "file containing target rdf")
    ("action", boost::program_options::value<string>(&action)->default_value("ibm"), "ibm (to do: smooth, imc,...)")
    ("T", boost::program_options::value<double>(&T)->default_value(300.), "temperature")
    ("scale", boost::program_options::value<double>(&scale)->default_value(1.), "correction scaling")
    ("Nsmooth", boost::program_options::value<int>(&Nsmooth)->default_value(0), "smooth Nsmooth times before writing table")
    //("type", boost::program_options::value<string>()->default_value("nb"), "nb, bond, ang, dih")
    ;

    // now read in the command line
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    // does the user want help?
    if (vm.count("help")) {
        cout << "csg_update \n\n";
        cout << desc << endl;
        return 0;
    }

    if(action == "ibm") {
        return DoIBM(in, out, target, current, T, scale, Nsmooth);
    }
    else
        cerr << "unknown action\n";

    return -1;
}

// do inverse boltzmann
int DoIBM(const string &in, const string &out, const string &target_dist, const string &current, double T, double scale, int Nsmooth)
{
    Table target;
    Table pout;
    //
    if(target_dist=="") {
        cerr << "error, not target given for iterative inverse boltzmann";
        return -1;
    }

    target.Load(target_dist);

    // if no input potential is given, do initial guess
    if(in=="") {
        pout.resize(target.size());
        pout.x() = target.x();
	pout.flags() = ub::scalar_vector<unsigned short>(target.size(), 0);

        for(int i=0; i<pout.size(); ++i) {
            if(target.y(i) == 0) {
                pout.y(i) = 0;
                pout.flags(i) |= TBL_INVALID;
            }
            else
                pout.y(i) = -kB*T*log(target.y(i));
        }
    }
    // otherwise do ibm update
    else {
        Table pin;

        if(current == "") {
            cerr << "error, give current distribution";
            return -1;
	}

        // read in the current potential
        pin.Load(in);
        // read the current distribution
        Table cur;
        cur.Load(current);

        pout = pin;

        for(int i=0; i<pout.size(); ++i) {
            if(target.y(i) == 0 || cur.y(i) == 0) {
                pout.y(i) = 0;
                pout.flags(i) |= TBL_INVALID;
            }
            else
                pout.y(i) += -kB*T*log(cur.y(i) / target.y(i));
        }
    }

pout.Smooth(Nsmooth);
    pout.Save(out);
    // should not get here
    return 0;
}

<commit_msg>added a few comments<commit_after>//
// File:   csg_update.cc
// Author: ruehle
//
// Created on June 11, 2008, 10:31 AM
//

/// this is the most dirtyest program, clean it up, don't copy anything from here!!!

#define kB  8.3109*0.01

#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
#include <boost/program_options.hpp>
#include <tools/table.h>

using namespace std;

namespace po = boost::program_options;

int DoIBM(const string &in, const string &out, const string &target, const string &current, double T, double scalem, int Nsmooth);

int main(int argc, char** argv)
{
    string method, type;
    string action;
    string in, out;
    string target, current;
    int Nsmooth;
    double T, scale;

    // lets read in some program options
    // Declare the supported options.
    po::options_description desc("Allowed options");

    desc.add_options()
    ("help", "produce this help message")
    //("version", "show version info")
    ("in", boost::program_options::value<string>(&in), "file containing current potential")
    ("out", boost::program_options::value<string>(&out)->default_value("out.dat"), "file to write the new potential")
    ("cur", boost::program_options::value<string>(&current), "file containing current rdf")
    ("target", boost::program_options::value<string>(&target), "file containing target rdf")
    ("action", boost::program_options::value<string>(&action)->default_value("ibm"), "ibm (to do: smooth, imc,...)")
    ("T", boost::program_options::value<double>(&T)->default_value(300.), "temperature")
    ("scale", boost::program_options::value<double>(&scale)->default_value(1.), "correction scaling")
    ("Nsmooth", boost::program_options::value<int>(&Nsmooth)->default_value(0), "smooth Nsmooth times before writing table")
    //("type", boost::program_options::value<string>()->default_value("nb"), "nb, bond, ang, dih")
    ;

    // changing the grid
    // cut off, shift
    // what to do at the ends
    // Pressure correction

    // now read in the command line
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    // does the user want help?
    if (vm.count("help")) {
        cout << "csg_update \n\n";
        cout << desc << endl;
        return 0;
    }

    if(action == "ibm") {
        return DoIBM(in, out, target, current, T, scale, Nsmooth);
    }
    else
        cerr << "unknown action\n";

    return -1;
}

// do inverse boltzmann
int DoIBM(const string &in, const string &out, const string &target_dist, const string &current, double T, double scale, int Nsmooth)
{
    Table target;
    Table pout;
    //
    if(target_dist=="") {
        cerr << "error, not target given for iterative inverse boltzmann";
        return -1;
    }

    target.Load(target_dist);

    // if no input potential is given, do initial guess
    if(in=="") {
        pout.resize(target.size());
        pout.x() = target.x();
	pout.flags() = ub::scalar_vector<unsigned short>(target.size(), 0);

        for(int i=0; i<pout.size(); ++i) {
            if(target.y(i) == 0) {
                pout.y(i) = 0;
                pout.flags(i) |= TBL_INVALID;
            }
            else
                pout.y(i) = -kB*T*log(target.y(i));
        }
    }
    // otherwise do ibm update
    else {
        Table pin;

        if(current == "") {
            cerr << "error, give current distribution";
            return -1;
	}

        // read in the current potential
        pin.Load(in);
        // read the current distribution
        Table cur;
        cur.Load(current);

        pout = pin;

        for(int i=0; i<pout.size(); ++i) {
            if(target.y(i) == 0 || cur.y(i) == 0) {
                pout.y(i) = 0;
                pout.flags(i) |= TBL_INVALID;
            }
            else
                pout.y(i) += -scale*kB*T*log(cur.y(i) / target.y(i));
        }
    }

    pout.Smooth(Nsmooth);
    pout.Save(out);
    // should not get here
    return 0;
}

<|endoftext|>


<commit_before>#include <vector>
#include <algorithm>
#include <thread>
#include <atomic>
#include "scene.h"
#include "samplers/sampler.h"
#include "film/render_target.h"
#include "film/camera.h"
#include "renderer/renderer.h"
#include "integrator/whitted_integrator.h"
#include "geometry/geometry.h"
#include "linalg/ray.h"
#include "linalg/transform.h"
#include "memory_pool.h"
#include "driver.h"

Worker::Worker(Scene &scene, BlockQueue &queue)
	: scene(scene), queue(queue), status(STATUS::NOT_STARTED)
{}
Worker::Worker(Worker &&w) : scene(w.scene), queue(w.queue),
	thread(std::move(w.thread)), status(w.status.load(std::memory_order_acquire))
{}
void Worker::render(){
	status.store(STATUS::WORKING, std::memory_order_release);
	Node &root = scene.get_root();
	RenderTarget &target = scene.get_render_target();
	Camera &camera = scene.get_camera();
	auto renderer = std::make_unique<Renderer>(std::make_unique<WhittedIntegrator>(scene.get_max_depth()));
	MemoryPool pool;
	//Counter so we can check if we've been canceled, check after every 32 pixels rendered
	int check_cancel = 0;
	while (true){
		Sampler *sampler = queue.get_block();
		if (!sampler){
			break;
		}
		std::vector<Sample> samples;
		std::vector<RayDifferential> rays;
		std::vector<Colorf> colors;
		while (sampler->has_samples()){
			sampler->get_samples(samples);
			rays.reserve(samples.size());
			colors.reserve(samples.size());
			for (const auto &s : samples){
				rays.push_back(camera.generate_raydifferential(s));
				rays.back().scale_differentials(1.f / std::sqrt(sampler->get_max_spp()));
				colors.push_back(renderer->illumination(rays.back(), scene, *sampler, pool));
				//If we didn't hit anything and the scene has a background use that
				if (scene.get_background() && rays.back().max_t == std::numeric_limits<float>::infinity()){
					DifferentialGeometry dg;
					dg.u = s.img[0] / target.get_width();
					dg.v = s.img[1] / target.get_height();
					colors.back() = scene.get_background()->sample(dg);
				}
				colors.back().normalize();

				++check_cancel;
				if (check_cancel >= 32){
					check_cancel = 0;
					int canceled = STATUS::CANCELED;
					if (status.compare_exchange_strong(canceled, STATUS::DONE, std::memory_order_acq_rel)){
						return;
					}
				}
			}
			if (sampler->report_results(samples, rays, colors)){
				for (size_t i = 0; i < samples.size(); ++i){
					target.write_pixel(samples[i].img[0], samples[i].img[1], colors[i]);
					target.write_float(samples[i].img[0], samples[i].img[1], samples.size());
				}
			}
			rays.clear();
			colors.clear();
			pool.free_blocks();
		}
	}
	status.store(STATUS::DONE, std::memory_order_release);
}

Driver::Driver(Scene &scene, int nworkers, int bwidth, int bheight)
	: scene(scene), queue(scene.get_sampler(), bwidth, bheight)
{
	for (int i = 0; i < nworkers; ++i){
		workers.emplace_back(Worker{scene, queue});
	}
}
Driver::~Driver(){
	//Tell all the threads to cancel
	cancel();
}
void Driver::render(){
	//Run through and launch each thread
	for (auto &w : workers){
		w.thread = std::thread(&Worker::render, std::ref(w));
	}
}
bool Driver::done(){
	//Check which workers have finished and join them, if all are done
	//report that we're done
	bool all_done = true;
	for (auto &w : workers){
		int status = w.status.load(std::memory_order_acquire);
		if (status == STATUS::DONE){
			w.thread.join();
			w.status.store(STATUS::JOINED, std::memory_order_release);
		}
		else if (status != STATUS::JOINED){
			all_done = false;
		}
	}
	return all_done;
}
void Driver::cancel(){
	//Inform all the threads they should quit
	for (auto &w : workers){
		int status = STATUS::WORKING;
		if (w.status.compare_exchange_strong(status, STATUS::CANCELED, std::memory_order_acq_rel)){
			w.thread.join();
			w.status.store(STATUS::JOINED, std::memory_order_release);
		}
		else if (status == STATUS::DONE){
			w.thread.join();
			w.status.store(STATUS::JOINED, std::memory_order_release);
		}
	}
}
const Scene& Driver::get_scene() const {
	return scene;
}

<commit_msg>Free the blocks after each sample not after all the samples<commit_after>#include <vector>
#include <algorithm>
#include <thread>
#include <atomic>
#include "scene.h"
#include "samplers/sampler.h"
#include "film/render_target.h"
#include "film/camera.h"
#include "renderer/renderer.h"
#include "integrator/whitted_integrator.h"
#include "geometry/geometry.h"
#include "linalg/ray.h"
#include "linalg/transform.h"
#include "memory_pool.h"
#include "driver.h"

Worker::Worker(Scene &scene, BlockQueue &queue)
	: scene(scene), queue(queue), status(STATUS::NOT_STARTED)
{}
Worker::Worker(Worker &&w) : scene(w.scene), queue(w.queue),
	thread(std::move(w.thread)), status(w.status.load(std::memory_order_acquire))
{}
void Worker::render(){
	status.store(STATUS::WORKING, std::memory_order_release);
	Node &root = scene.get_root();
	RenderTarget &target = scene.get_render_target();
	Camera &camera = scene.get_camera();
	auto renderer = std::make_unique<Renderer>(std::make_unique<WhittedIntegrator>(scene.get_max_depth()));
	MemoryPool pool;
	//Counter so we can check if we've been canceled, check after every 32 pixels rendered
	int check_cancel = 0;
	while (true){
		Sampler *sampler = queue.get_block();
		if (!sampler){
			break;
		}
		std::vector<Sample> samples(sampler->get_max_spp());
		std::vector<RayDifferential> rays(sampler->get_max_spp());
		std::vector<Colorf> colors(sampler->get_max_spp());
		while (sampler->has_samples()){
			sampler->get_samples(samples);
			for (const auto &s : samples){
				rays.push_back(camera.generate_raydifferential(s));
				rays.back().scale_differentials(1.f / std::sqrt(sampler->get_max_spp()));
				colors.push_back(renderer->illumination(rays.back(), scene, *sampler, pool));
				//If we didn't hit anything and the scene has a background use that
				if (scene.get_background() && rays.back().max_t == std::numeric_limits<float>::infinity()){
					DifferentialGeometry dg;
					dg.u = s.img[0] / target.get_width();
					dg.v = s.img[1] / target.get_height();
					colors.back() = scene.get_background()->sample(dg);
				}
				colors.back().normalize();

				++check_cancel;
				if (check_cancel >= 32){
					check_cancel = 0;
					int canceled = STATUS::CANCELED;
					if (status.compare_exchange_strong(canceled, STATUS::DONE, std::memory_order_acq_rel)){
						return;
					}
				}
				pool.free_blocks();
			}
			if (sampler->report_results(samples, rays, colors)){
				for (size_t i = 0; i < samples.size(); ++i){
					target.write_pixel(samples[i].img[0], samples[i].img[1], colors[i]);
					target.write_float(samples[i].img[0], samples[i].img[1], samples.size());
				}
			}
			rays.clear();
			colors.clear();
		}
	}
	status.store(STATUS::DONE, std::memory_order_release);
}

Driver::Driver(Scene &scene, int nworkers, int bwidth, int bheight)
	: scene(scene), queue(scene.get_sampler(), bwidth, bheight)
{
	for (int i = 0; i < nworkers; ++i){
		workers.emplace_back(Worker{scene, queue});
	}
}
Driver::~Driver(){
	//Tell all the threads to cancel
	cancel();
}
void Driver::render(){
	//Run through and launch each thread
	for (auto &w : workers){
		w.thread = std::thread(&Worker::render, std::ref(w));
	}
}
bool Driver::done(){
	//Check which workers have finished and join them, if all are done
	//report that we're done
	bool all_done = true;
	for (auto &w : workers){
		int status = w.status.load(std::memory_order_acquire);
		if (status == STATUS::DONE){
			w.thread.join();
			w.status.store(STATUS::JOINED, std::memory_order_release);
		}
		else if (status != STATUS::JOINED){
			all_done = false;
		}
	}
	return all_done;
}
void Driver::cancel(){
	//Inform all the threads they should quit
	for (auto &w : workers){
		int status = STATUS::WORKING;
		if (w.status.compare_exchange_strong(status, STATUS::CANCELED, std::memory_order_acq_rel)){
			w.thread.join();
			w.status.store(STATUS::JOINED, std::memory_order_release);
		}
		else if (status == STATUS::DONE){
			w.thread.join();
			w.status.store(STATUS::JOINED, std::memory_order_release);
		}
	}
}
const Scene& Driver::get_scene() const {
	return scene;
}

<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <chrono>
#include <thread>
#include <xmmintrin.h>

#include "engine.hpp"
#include "util.hpp"

namespace rack {

float sampleRate;
float sampleTime;
bool gPaused = false;

static bool running = false;

static std::mutex mutex;
static std::thread thread;
static VIPMutex vipMutex;

static std::vector<Module*> modules;
static std::vector<Wire*> wires;

// Parameter interpolation
static Module *smoothModule = NULL;
static int smoothParamId;
static float smoothValue;

float Light::getBrightness() {
	return sqrtf(fmaxf(0.0, value));
}

void Light::setBrightnessSmooth(float brightness) {
	float v = (brightness > 0.0) ? brightness * brightness : 0.0;
	if (v < value) {
		// Fade out light with lambda = 2 * framerate
		value += (v - value) * sampleTime * (60.0 * 2.0);
	}
	else {
		// Immediately illuminate light
		value = v;
	}
}

void Wire::step() {
	float value = outputModule->outputs[outputId].value;
	inputModule->inputs[inputId].value = value;
}

void engineInit() {
	engineSetSampleRate(44100.0);
}

void engineDestroy() {
	// Make sure there are no wires or modules in the rack on destruction. This suggests that a module failed to remove itself before the GUI was destroyed.
	assert(wires.empty());
	assert(modules.empty());
}

static void engineStep() {
	// Param interpolation
	if (smoothModule) {
		float value = smoothModule->params[smoothParamId].value;
		const float lambda = 60.0; // decay rate is 1 graphics frame
		const float snap = 0.0001;
		float delta = smoothValue - value;
		if (fabsf(delta) < snap) {
			smoothModule->params[smoothParamId].value = smoothValue;
			smoothModule = NULL;
		}
		else {
			value += delta * lambda * sampleTime;
			smoothModule->params[smoothParamId].value = value;
		}
	}

	// Step modules
	for (Module *module : modules) {
		module->step();

		// TODO skip this step when plug lights are disabled
		// Step ports
		for (Input &input : module->inputs) {
			if (input.active) {
				float value = input.value / 10.0;
				input.plugLights[0].setBrightnessSmooth(value);
				input.plugLights[1].setBrightnessSmooth(-value);
			}
		}
		for (Output &output : module->outputs) {
			if (output.active) {
				float value = output.value / 10.0;
				output.plugLights[0].setBrightnessSmooth(value);
				output.plugLights[1].setBrightnessSmooth(-value);
			}
		}
	}

	// Step cables by moving their output values to inputs
	for (Wire *wire : wires) {
		wire->step();
	}
}

static void engineRun() {
	// Set CPU to denormals-are-zero mode
	// http://carlh.net/plugins/denormals.php
	_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);

	// Every time the engine waits and locks a mutex, it steps this many frames
	const int mutexSteps = 64;
	// Time in seconds that the engine is rushing ahead of the estimated clock time
	double ahead = 0.0;
	auto lastTime = std::chrono::high_resolution_clock::now();

	while (running) {
		vipMutex.wait();

		if (!gPaused) {
			std::lock_guard<std::mutex> lock(mutex);
			for (int i = 0; i < mutexSteps; i++) {
				engineStep();
			}
		}

		double stepTime = mutexSteps * sampleTime;
		ahead += stepTime;
		auto currTime = std::chrono::high_resolution_clock::now();
		const double aheadFactor = 2.0;
		ahead -= aheadFactor * std::chrono::duration<double>(currTime - lastTime).count();
		lastTime = currTime;
		ahead = fmaxf(ahead, 0.0);

		// Avoid pegging the CPU at 100% when there are no "blocking" modules like AudioInterface, but still step audio at a reasonable rate
		// The number of steps to wait before possibly sleeping
		const double aheadMax = 1.0; // seconds
		if (ahead > aheadMax) {
			std::this_thread::sleep_for(std::chrono::duration<double>(stepTime));
		}
	}
}

void engineStart() {
	running = true;
	thread = std::thread(engineRun);
}

void engineStop() {
	running = false;
	thread.join();
}

void engineAddModule(Module *module) {
	assert(module);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Check that the module is not already added
	auto it = std::find(modules.begin(), modules.end(), module);
	assert(it == modules.end());
	modules.push_back(module);
}

void engineRemoveModule(Module *module) {
	assert(module);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// If a param is being smoothed on this module, stop smoothing it immediately
	if (module == smoothModule) {
		smoothModule = NULL;
	}
	// Check that all wires are disconnected
	for (Wire *wire : wires) {
		assert(wire->outputModule != module);
		assert(wire->inputModule != module);
	}
	// Check that the module actually exists
	auto it = std::find(modules.begin(), modules.end(), module);
	assert(it != modules.end());
	// Remove it
	modules.erase(it);
}

static void updateActive() {
	// Set everything to inactive
	for (Module *module : modules) {
		for (Input &input : module->inputs) {
			input.active = false;
		}
		for (Output &output : module->outputs) {
			output.active = false;
		}
	}
	// Set inputs/outputs to active
	for (Wire *wire : wires) {
		wire->outputModule->outputs[wire->outputId].active = true;
		wire->inputModule->inputs[wire->inputId].active = true;
	}
}

void engineAddWire(Wire *wire) {
	assert(wire);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Check wire properties
	assert(wire->outputModule);
	assert(wire->inputModule);
	// Check that the wire is not already added, and that the input is not already used by another cable
	for (Wire *wire2 : wires) {
		assert(wire2 != wire);
		assert(!(wire2->inputModule == wire->inputModule && wire2->inputId == wire->inputId));
	}
	// Add the wire
	wires.push_back(wire);
	updateActive();
}

void engineRemoveWire(Wire *wire) {
	assert(wire);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Check that the wire is already added
	auto it = std::find(wires.begin(), wires.end(), wire);
	assert(it != wires.end());
	// Set input to 0V
	wire->inputModule->inputs[wire->inputId].value = 0.0;
	// Remove the wire
	wires.erase(it);
	updateActive();
}

void engineSetParam(Module *module, int paramId, float value) {
	module->params[paramId].value = value;
}

void engineSetParamSmooth(Module *module, int paramId, float value) {
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Since only one param can be smoothed at a time, if another param is currently being smoothed, skip to its final state
	if (smoothModule && !(smoothModule == module && smoothParamId == paramId)) {
		smoothModule->params[smoothParamId].value = smoothValue;
	}
	smoothModule = module;
	smoothParamId = paramId;
	smoothValue = value;
}

void engineSetSampleRate(float newSampleRate) {
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	sampleRate = newSampleRate;
	sampleTime = 1.0 / sampleRate;
	// onSampleRateChange
	for (Module *module : modules) {
		module->onSampleRateChange();
	}
}

float engineGetSampleRate() {
	return sampleRate;
}

float engineGetSampleTime() {
	return sampleTime;
}

} // namespace rack
<commit_msg>Enable denormals-are-zero (DAZ) mode in engine<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <chrono>
#include <thread>
#include <xmmintrin.h>
#include <pmmintrin.h>

#include "engine.hpp"
#include "util.hpp"

namespace rack {

float sampleRate;
float sampleTime;
bool gPaused = false;

static bool running = false;

static std::mutex mutex;
static std::thread thread;
static VIPMutex vipMutex;

static std::vector<Module*> modules;
static std::vector<Wire*> wires;

// Parameter interpolation
static Module *smoothModule = NULL;
static int smoothParamId;
static float smoothValue;

float Light::getBrightness() {
	return sqrtf(fmaxf(0.0, value));
}

void Light::setBrightnessSmooth(float brightness) {
	float v = (brightness > 0.0) ? brightness * brightness : 0.0;
	if (v < value) {
		// Fade out light with lambda = 2 * framerate
		value += (v - value) * sampleTime * (60.0 * 2.0);
	}
	else {
		// Immediately illuminate light
		value = v;
	}
}

void Wire::step() {
	float value = outputModule->outputs[outputId].value;
	inputModule->inputs[inputId].value = value;
}

void engineInit() {
	engineSetSampleRate(44100.0);
}

void engineDestroy() {
	// Make sure there are no wires or modules in the rack on destruction. This suggests that a module failed to remove itself before the GUI was destroyed.
	assert(wires.empty());
	assert(modules.empty());
}

static void engineStep() {
	// Param interpolation
	if (smoothModule) {
		float value = smoothModule->params[smoothParamId].value;
		const float lambda = 60.0; // decay rate is 1 graphics frame
		const float snap = 0.0001;
		float delta = smoothValue - value;
		if (fabsf(delta) < snap) {
			smoothModule->params[smoothParamId].value = smoothValue;
			smoothModule = NULL;
		}
		else {
			value += delta * lambda * sampleTime;
			smoothModule->params[smoothParamId].value = value;
		}
	}

	// Step modules
	for (Module *module : modules) {
		module->step();

		// TODO skip this step when plug lights are disabled
		// Step ports
		for (Input &input : module->inputs) {
			if (input.active) {
				float value = input.value / 10.0;
				input.plugLights[0].setBrightnessSmooth(value);
				input.plugLights[1].setBrightnessSmooth(-value);
			}
		}
		for (Output &output : module->outputs) {
			if (output.active) {
				float value = output.value / 10.0;
				output.plugLights[0].setBrightnessSmooth(value);
				output.plugLights[1].setBrightnessSmooth(-value);
			}
		}
	}

	// Step cables by moving their output values to inputs
	for (Wire *wire : wires) {
		wire->step();
	}
}

static void engineRun() {
	// Set CPU to flush-to-zero (FTZ) and denormals-are-zero (DAZ) mode
	// https://software.intel.com/en-us/node/682949
	_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
	_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);

	// Every time the engine waits and locks a mutex, it steps this many frames
	const int mutexSteps = 64;
	// Time in seconds that the engine is rushing ahead of the estimated clock time
	double ahead = 0.0;
	auto lastTime = std::chrono::high_resolution_clock::now();

	while (running) {
		vipMutex.wait();

		if (!gPaused) {
			std::lock_guard<std::mutex> lock(mutex);
			for (int i = 0; i < mutexSteps; i++) {
				engineStep();
			}
		}

		double stepTime = mutexSteps * sampleTime;
		ahead += stepTime;
		auto currTime = std::chrono::high_resolution_clock::now();
		const double aheadFactor = 2.0;
		ahead -= aheadFactor * std::chrono::duration<double>(currTime - lastTime).count();
		lastTime = currTime;
		ahead = fmaxf(ahead, 0.0);

		// Avoid pegging the CPU at 100% when there are no "blocking" modules like AudioInterface, but still step audio at a reasonable rate
		// The number of steps to wait before possibly sleeping
		const double aheadMax = 1.0; // seconds
		if (ahead > aheadMax) {
			std::this_thread::sleep_for(std::chrono::duration<double>(stepTime));
		}
	}
}

void engineStart() {
	running = true;
	thread = std::thread(engineRun);
}

void engineStop() {
	running = false;
	thread.join();
}

void engineAddModule(Module *module) {
	assert(module);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Check that the module is not already added
	auto it = std::find(modules.begin(), modules.end(), module);
	assert(it == modules.end());
	modules.push_back(module);
}

void engineRemoveModule(Module *module) {
	assert(module);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// If a param is being smoothed on this module, stop smoothing it immediately
	if (module == smoothModule) {
		smoothModule = NULL;
	}
	// Check that all wires are disconnected
	for (Wire *wire : wires) {
		assert(wire->outputModule != module);
		assert(wire->inputModule != module);
	}
	// Check that the module actually exists
	auto it = std::find(modules.begin(), modules.end(), module);
	assert(it != modules.end());
	// Remove it
	modules.erase(it);
}

static void updateActive() {
	// Set everything to inactive
	for (Module *module : modules) {
		for (Input &input : module->inputs) {
			input.active = false;
		}
		for (Output &output : module->outputs) {
			output.active = false;
		}
	}
	// Set inputs/outputs to active
	for (Wire *wire : wires) {
		wire->outputModule->outputs[wire->outputId].active = true;
		wire->inputModule->inputs[wire->inputId].active = true;
	}
}

void engineAddWire(Wire *wire) {
	assert(wire);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Check wire properties
	assert(wire->outputModule);
	assert(wire->inputModule);
	// Check that the wire is not already added, and that the input is not already used by another cable
	for (Wire *wire2 : wires) {
		assert(wire2 != wire);
		assert(!(wire2->inputModule == wire->inputModule && wire2->inputId == wire->inputId));
	}
	// Add the wire
	wires.push_back(wire);
	updateActive();
}

void engineRemoveWire(Wire *wire) {
	assert(wire);
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Check that the wire is already added
	auto it = std::find(wires.begin(), wires.end(), wire);
	assert(it != wires.end());
	// Set input to 0V
	wire->inputModule->inputs[wire->inputId].value = 0.0;
	// Remove the wire
	wires.erase(it);
	updateActive();
}

void engineSetParam(Module *module, int paramId, float value) {
	module->params[paramId].value = value;
}

void engineSetParamSmooth(Module *module, int paramId, float value) {
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	// Since only one param can be smoothed at a time, if another param is currently being smoothed, skip to its final state
	if (smoothModule && !(smoothModule == module && smoothParamId == paramId)) {
		smoothModule->params[smoothParamId].value = smoothValue;
	}
	smoothModule = module;
	smoothParamId = paramId;
	smoothValue = value;
}

void engineSetSampleRate(float newSampleRate) {
	VIPLock vipLock(vipMutex);
	std::lock_guard<std::mutex> lock(mutex);
	sampleRate = newSampleRate;
	sampleTime = 1.0 / sampleRate;
	// onSampleRateChange
	for (Module *module : modules) {
		module->onSampleRateChange();
	}
}

float engineGetSampleRate() {
	return sampleRate;
}

float engineGetSampleTime() {
	return sampleTime;
}

} // namespace rack
<|endoftext|>


<commit_before>#include <vector>

template <typename T>
std::vector<T> esieve(const T &n) {
    auto primes = std::vector<T>(n, 0);

    for (T i = 2; i < n; ++i) {
        if (primes[i] != 0) {continue;}

        for (T j = i; j < n; j += i) {
            primes[j] = i;
        }
    }

    return primes;
}
<commit_msg>Sieve of Eratosthenes: minor style changes<commit_after>#include <vector>

template <typename T>
std::vector<T> esieve(const T &n) {
    auto xs = std::vector<T>(n, 0);

    for (T i = 2; i < n; ++i) {
        if (xs[i] != 0) continue;

        for (T j = i; j < n; j += i) {
            xs[j] = i;
        }
    }

    return xs;
}
<|endoftext|>


<commit_before>#include <algorithm>

#include "source/Thread.h"
#include "tests/mocks/MockTransporter.h"

using ::testing::_;
using ::testing::Exactly;
using ::testing::Return;

namespace BeamMeUp {
    class TestThreader : public Thread {
    public:
        TestThreader();

        TestThreader(unsigned int delayInMicroseconds);

        void run() override;

        ~TestThreader() override;

        unsigned int delay;
        static std::mutex mutex;
        static std::vector<TestThreader *> deletedThreads;
    };

    std::mutex TestThreader::mutex;
    std::vector<TestThreader *> TestThreader::deletedThreads;

    TestThreader::TestThreader() : Thread() {
        this->delay = 0;
    }

    TestThreader::TestThreader(unsigned int delayInMicroseconds) : Thread() {
        this->delay = delayInMicroseconds;
    }

    void TestThreader::run() {
        // Wait until finished is true
        while (!isStopping()) {

            // Sleep for 5 μs
            std::this_thread::sleep_for(std::chrono::microseconds(5));
        }

        if (delay > 0) {

            // Wait for delay ms before actually shutting down
            std::this_thread::sleep_for(std::chrono::microseconds(delay));
        }
    }

    TestThreader::~TestThreader() {

        // Stop it!
        stop();

        // Join is also called in the parent destructor, but we want to ensure shut
        // down is actually complete before we add to our collection of shut down
        // threads
        join();

        // Lock mutex
        mutex.lock();

        // Add to collection
        // This data is used in TEST(Thread, ShutdownCompletedFromDestructor)
        deletedThreads.push_back(this);

        // Unlock mutex
        mutex.unlock();
    }

    // Tests that the thread has shut down successfully
    TEST(TestThread, ShutdownCompleted) {
        // Initialize a thread
        TestThreader thread;

        // Start the thread
        thread.start();

        // Ensure thread is not finished
        ASSERT_FALSE(thread.isFinished());

        // Tell it to stop and block until it does so
        thread.stop(true);

        // Check if the thread has actually stopped
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the thread has shut down successfully when shut down actually
    // takes time
    TEST(TestThread, ShutdownCompletedAfterTime) {
        // Initialize a thread with a 2 μs shutdown time
        TestThreader thread(2);

        // Start the thread
        thread.start();

        // Sleep for 1 μs to ensure that the thread has actually started running
        std::this_thread::sleep_for(std::chrono::microseconds(1));

        // Tell the thread to stop
        thread.stop(false);

        // The thread takes at least 2 μs to shut down, so it should still be
        // running
        ASSERT_FALSE(thread.isFinished());

        // Sleep for enough time for the thread to shut down. 50 μs?
        std::this_thread::sleep_for(std::chrono::microseconds(50));

        // The thread should definitely be finished now
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the start method throws an exception if the thread is already running
    TEST(TestThread, DoubleStartThrowsException) {
        // Initialize a thread with a 2 μs shutdown time
        TestThreader thread(2);

        // Start the thread
        thread.start();
        ASSERT_THROW(thread.start(), std::runtime_error);

        // Sleep for 1 μs to ensure that the thread has actually started running
        std::this_thread::sleep_for(std::chrono::microseconds(1));

        // Tell the thread to stop
        thread.stop(false);

        // The thread takes at least 2 μs to shut down, so it should still be
        // running
        ASSERT_FALSE(thread.isFinished());

        // Sleep for enough time for the thread to shut down. 50 μs?
        std::this_thread::sleep_for(std::chrono::microseconds(50));

        // The thread should definitely be finished now
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the start method waits for the thread to complete and then restarts it if it is shutting down already
    TEST(TestThread, DoubleStartWhileStoppingWaitsAndThenRestarts) {
        // Initialize a thread with a 2 μs shutdown time
        TestThreader thread(2);

        // Start the thread
        thread.start();
        thread.stop(false);
        thread.start();

        // Sleep for 1 μs to ensure that the thread has actually started running
        std::this_thread::sleep_for(std::chrono::microseconds(1));

        // Tell the thread to stop
        thread.stop(false);

        // The thread takes at least 2 μs to shut down, so it should still be
        // running
        ASSERT_FALSE(thread.isFinished());

        // Sleep for enough time for the thread to shut down. 50 μs?
        std::this_thread::sleep_for(std::chrono::microseconds(50));

        // The thread should definitely be finished now
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the thread has shut down successfully when shut down by the
    // application. This is to ensure that an infinite loop isn't created on a child
    // thread.
    TEST(TestThread, ShutdownCompletedFromDestructor) {
        // Initialize a thread
        TestThreader *thread = new TestThreader();

        // Start it up
        thread->start();

        // Shut down thread
        delete thread;

        // Lock mutex
        TestThreader::mutex.lock();

        // Make a copy of the deleted threads vector
        auto vector = TestThreader::deletedThreads;

        // Unlock mutex
        TestThreader::mutex.unlock();

        // Ensure that the thread in question was in fact shut down
        ASSERT_NE(std::find(vector.begin(), vector.end(), thread), vector.end());
    }
}

<commit_msg>BMU-8: slow down thread tests due to slow vm<commit_after>#include <algorithm>

#include "source/Thread.h"
#include "tests/mocks/MockTransporter.h"

using ::testing::_;
using ::testing::Exactly;
using ::testing::Return;

namespace BeamMeUp {
    class TestThreader : public Thread {

    public:
        static const int DELAY_MULTIPLIER;

        TestThreader();

        TestThreader(unsigned int delayInMicroseconds);

        void run() override;

        ~TestThreader() override;

        unsigned int delay;
        static std::mutex mutex;
        static std::vector<TestThreader *> deletedThreads;
    };
    const int TestThreader::DELAY_MULTIPLIER = 200;

    std::mutex TestThreader::mutex;
    std::vector<TestThreader *> TestThreader::deletedThreads;

    TestThreader::TestThreader() : Thread() {
        this->delay = 0;
    }

    TestThreader::TestThreader(unsigned int delayInMicroseconds) : Thread() {
        // Multiply delay by DELAY_MULTIPLIER (the number is somewhat arbitrary really) to reduce edge cases caused by slow VMs
        this->delay = delayInMicroseconds * DELAY_MULTIPLIER;
    }

    void TestThreader::run() {
        // Wait until finished is true
        while (!isStopping()) {

            // Sleep for 5 μs
            std::this_thread::sleep_for(std::chrono::microseconds(5 * DELAY_MULTIPLIER));
        }

        if (delay > 0) {

            // Wait for delay ms before actually shutting down
            std::this_thread::sleep_for(std::chrono::microseconds(delay));
        }
    }

    TestThreader::~TestThreader() {

        // Stop it!
        stop();

        // Join is also called in the parent destructor, but we want to ensure shut
        // down is actually complete before we add to our collection of shut down
        // threads
        join();

        // Lock mutex
        mutex.lock();

        // Add to collection
        // This data is used in TEST(Thread, ShutdownCompletedFromDestructor)
        deletedThreads.push_back(this);

        // Unlock mutex
        mutex.unlock();
    }

    // Tests that the thread has shut down successfully
    TEST(TestThread, ShutdownCompleted) {
        // Initialize a thread
        TestThreader thread;

        // Start the thread
        thread.start();

        // Ensure thread is not finished
        ASSERT_FALSE(thread.isFinished());

        // Tell it to stop and block until it does so
        thread.stop(true);

        // Check if the thread has actually stopped
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the thread has shut down successfully when shut down actually
    // takes time
    TEST(TestThread, ShutdownCompletedAfterTime) {
        // Initialize a thread with a 2 μs shutdown time
        TestThreader thread(2);

        // Start the thread
        thread.start();

        // Sleep for 1 μs to ensure that the thread has actually started running
        std::this_thread::sleep_for(std::chrono::microseconds(TestThreader::DELAY_MULTIPLIER));

        // Tell the thread to stop
        thread.stop(false);

        // The thread takes at least 2 μs to shut down, so it should still be
        // running
        ASSERT_FALSE(thread.isFinished());

        // Sleep for enough time for the thread to shut down. 50 μs?
        std::this_thread::sleep_for(std::chrono::microseconds(50 * TestThreader::DELAY_MULTIPLIER));

        // The thread should definitely be finished now
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the start method throws an exception if the thread is already running
    TEST(TestThread, DoubleStartThrowsException) {
        // Initialize a thread with a 2 μs shutdown time
        TestThreader thread(2);

        // Start the thread
        thread.start();
        ASSERT_THROW(thread.start(), std::runtime_error);

        // Sleep for 1 μs to ensure that the thread has actually started running
        std::this_thread::sleep_for(std::chrono::microseconds(1 * TestThreader::DELAY_MULTIPLIER));

        // Tell the thread to stop
        thread.stop(false);

        // The thread takes at least 2 μs to shut down, so it should still be
        // running
        ASSERT_FALSE(thread.isFinished());

        // Sleep for enough time for the thread to shut down. 50 μs?
        std::this_thread::sleep_for(std::chrono::microseconds(50 * TestThreader::DELAY_MULTIPLIER));

        // The thread should definitely be finished now
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the start method waits for the thread to complete and then restarts it if it is shutting down already
    TEST(TestThread, DoubleStartWhileStoppingWaitsAndThenRestarts) {
        // Initialize a thread with a 2 μs shutdown time
        TestThreader thread(2);

        // Start the thread
        thread.start();
        thread.stop(false);
        thread.start();

        // Sleep for 1 μs to ensure that the thread has actually started running
        std::this_thread::sleep_for(std::chrono::microseconds(1 * TestThreader::DELAY_MULTIPLIER));

        // Tell the thread to stop
        thread.stop(false);

        // The thread takes at least 2 μs to shut down, so it should still be
        // running
        ASSERT_FALSE(thread.isFinished());

        // Sleep for enough time for the thread to shut down. 50 μs?
        std::this_thread::sleep_for(std::chrono::microseconds(50 * TestThreader::DELAY_MULTIPLIER));

        // The thread should definitely be finished now
        ASSERT_TRUE(thread.isFinished());
    }

    // Tests that the thread has shut down successfully when shut down by the
    // application. This is to ensure that an infinite loop isn't created on a child
    // thread.
    TEST(TestThread, ShutdownCompletedFromDestructor) {
        // Initialize a thread
        TestThreader *thread = new TestThreader();

        // Start it up
        thread->start();

        // Shut down thread
        delete thread;

        // Lock mutex
        TestThreader::mutex.lock();

        // Make a copy of the deleted threads vector
        auto vector = TestThreader::deletedThreads;

        // Unlock mutex
        TestThreader::mutex.unlock();

        // Ensure that the thread in question was in fact shut down
        ASSERT_NE(std::find(vector.begin(), vector.end(), thread), vector.end());
    }
}

<|endoftext|>


<commit_before>#include <yamail/resource_pool/async/detail/queue.hpp>

#include "tests.hpp"

namespace {

using namespace tests;
using namespace yamail::resource_pool;
using namespace yamail::resource_pool::async::detail;

struct mocked_timer {
    mocked_timer(mocked_io_service&) {}

    MOCK_CONST_METHOD0(expires_at, time_traits::time_point ());
    MOCK_CONST_METHOD1(expires_at, void (const time_traits::time_point&));
    MOCK_CONST_METHOD1(async_wait, void (boost::function<void (boost::system::error_code)>));
};

typedef queue<request, mocked_io_service, mocked_timer> request_queue;
typedef boost::shared_ptr<request_queue> request_queue_ptr;

using boost::system::error_code;

struct mocked_callback {
    MOCK_CONST_METHOD0(call, void ());
};

typedef boost::shared_ptr<mocked_callback> mocked_callback_ptr;

struct async_request_queue : Test {
    mocked_io_service ios;
    mocked_callback_ptr expired;
    boost::function<void (error_code)> on_async_wait;

    async_request_queue() : expired(make_shared<mocked_callback>()) {}

    request_queue_ptr make_queue(std::size_t capacity) {
        return make_shared<request_queue>(ref(ios), capacity);
    }
};

TEST_F(async_request_queue, create_const_with_capacity_1_then_check_capacity_should_be_1) {
    const request_queue queue(ios, 1);
    EXPECT_EQ(queue.capacity(), 1);
}

TEST_F(async_request_queue, create_const_then_check_size_should_be_0) {
    const request_queue queue(ios, 1);
    EXPECT_EQ(queue.size(), 0);
}

TEST_F(async_request_queue, create_const_then_check_empty_should_be_true) {
    const request_queue queue(ios, 1);
    EXPECT_EQ(queue.empty(), true);
}

TEST_F(async_request_queue, create_const_then_call_timer_should_succeed) {
    const request_queue queue(ios, 1);
    EXPECT_NO_THROW(queue.timer());
}

TEST_F(async_request_queue, create_ptr_then_call_shared_from_this_should_return_equal) {
    const request_queue_ptr queue = make_queue(1);
    EXPECT_EQ(queue->shared_from_this(), queue);
}

class callback {
public:
    typedef void result_type;

    callback(const mocked_callback_ptr& impl) : impl(impl) {}

    result_type operator ()() const { return impl->call(); }

private:
    mocked_callback_ptr impl;
};

TEST_F(async_request_queue, push_then_timeout_request_queue_should_be_empty) {
    request_queue_ptr queue = make_queue(1);

    time_traits::time_point expire_time;

    InSequence s;

    EXPECT_CALL(queue->timer(), expires_at(_)).WillOnce(SaveArg<0>(&expire_time));
    EXPECT_CALL(queue->timer(), async_wait(_)).WillOnce(SaveArg<0>(&on_async_wait));

    ASSERT_TRUE(queue->push(request {0}, callback(expired), time_traits::duration(0)));

    EXPECT_CALL(queue->timer(), expires_at()).WillOnce(Return(expire_time));
    EXPECT_CALL(ios, post(_)).WillOnce(InvokeArgument<0>());
    EXPECT_CALL(*expired, call()).WillOnce(Return());

    on_async_wait(error_code());

    EXPECT_TRUE(queue->empty());
}

TEST_F(async_request_queue, push_then_pop_should_return_request) {
    request_queue_ptr queue = make_queue(1);

    InSequence s;

    EXPECT_CALL(queue->timer(), expires_at(_)).WillOnce(Return());
    EXPECT_CALL(queue->timer(), async_wait(_)).WillOnce(SaveArg<0>(&on_async_wait));
    EXPECT_CALL(*expired, call()).Times(0);

    EXPECT_TRUE(queue->push(request {42}, callback(expired), time_traits::duration(1)));

    using namespace boost::system::errc;

    on_async_wait(error_code(make_error_code(operation_canceled)));

    EXPECT_FALSE(queue->empty());
    request_queue::value_type result {0};
    EXPECT_TRUE(queue->pop(result));
    EXPECT_EQ(result.value, 42);
}

TEST_F(async_request_queue, push_into_queue_with_null_capacity_should_return_error) {
    request_queue_ptr queue = make_queue(0);

    const bool result = queue->push(request {0}, callback(expired), time_traits::duration(0));
    EXPECT_FALSE(result);
}

TEST_F(async_request_queue, pop_from_empty_should_return_error) {
    request_queue_ptr queue = make_queue(1);

    EXPECT_TRUE(queue->empty());
    request_queue::value_type result {0};
    EXPECT_FALSE(queue->pop(result));
}

}
<commit_msg>Fix build tests<commit_after>#include <yamail/resource_pool/async/detail/queue.hpp>

#include "tests.hpp"

namespace {

using namespace tests;
using namespace yamail::resource_pool;
using namespace yamail::resource_pool::async::detail;

struct mocked_timer {
    mocked_timer(mocked_io_service&) {}

    MOCK_CONST_METHOD0(expires_at, time_traits::time_point ());
    MOCK_CONST_METHOD1(expires_at, void (const time_traits::time_point&));
    MOCK_CONST_METHOD1(async_wait, void (boost::function<void (boost::system::error_code)>));
};

typedef queue<request, mocked_io_service, mocked_timer> request_queue;
typedef boost::shared_ptr<request_queue> request_queue_ptr;

using boost::system::error_code;

struct mocked_callback {
    MOCK_CONST_METHOD0(call, void ());
};

typedef boost::shared_ptr<mocked_callback> mocked_callback_ptr;

struct async_request_queue : Test {
    mocked_io_service ios;
    mocked_callback_ptr expired;
    boost::function<void (error_code)> on_async_wait;

    async_request_queue() : expired(make_shared<mocked_callback>()) {}

    request_queue_ptr make_queue(std::size_t capacity) {
        return make_shared<request_queue>(ref(ios), capacity);
    }
};

TEST_F(async_request_queue, create_const_with_capacity_1_then_check_capacity_should_be_1) {
    const request_queue queue(ios, 1);
    EXPECT_EQ(queue.capacity(), 1);
}

TEST_F(async_request_queue, create_const_then_check_size_should_be_0) {
    const request_queue queue(ios, 1);
    EXPECT_EQ(queue.size(), 0);
}

TEST_F(async_request_queue, create_const_then_check_empty_should_be_true) {
    const request_queue queue(ios, 1);
    EXPECT_EQ(queue.empty(), true);
}

TEST_F(async_request_queue, create_const_then_call_timer_should_succeed) {
    const request_queue queue(ios, 1);
    EXPECT_NO_THROW(queue.timer());
}

TEST_F(async_request_queue, create_ptr_then_call_shared_from_this_should_return_equal) {
    const request_queue_ptr queue = make_queue(1);
    EXPECT_EQ(queue->shared_from_this(), queue);
}

class callback {
public:
    typedef void result_type;

    callback(const mocked_callback_ptr& impl) : impl(impl) {}

    result_type operator ()() const { return impl->call(); }

private:
    mocked_callback_ptr impl;
};

TEST_F(async_request_queue, push_then_timeout_request_queue_should_be_empty) {
    request_queue_ptr queue = make_queue(1);

    time_traits::time_point expire_time;

    InSequence s;

    EXPECT_CALL(queue->timer(), expires_at(_)).WillOnce(SaveArg<0>(&expire_time));
    EXPECT_CALL(queue->timer(), async_wait(_)).WillOnce(SaveArg<0>(&on_async_wait));

    request req;
    req.value = 0;
    ASSERT_TRUE(queue->push(req, callback(expired), time_traits::duration(0)));

    EXPECT_CALL(queue->timer(), expires_at()).WillOnce(Return(expire_time));
    EXPECT_CALL(ios, post(_)).WillOnce(InvokeArgument<0>());
    EXPECT_CALL(*expired, call()).WillOnce(Return());

    on_async_wait(error_code());

    EXPECT_TRUE(queue->empty());
}

TEST_F(async_request_queue, push_then_pop_should_return_request) {
    request_queue_ptr queue = make_queue(1);

    InSequence s;

    EXPECT_CALL(queue->timer(), expires_at(_)).WillOnce(Return());
    EXPECT_CALL(queue->timer(), async_wait(_)).WillOnce(SaveArg<0>(&on_async_wait));
    EXPECT_CALL(*expired, call()).Times(0);

    request req;
    req.value = 42;
    EXPECT_TRUE(queue->push(req, callback(expired), time_traits::duration(1)));

    using namespace boost::system::errc;

    on_async_wait(error_code(make_error_code(operation_canceled)));

    EXPECT_FALSE(queue->empty());
    request_queue::value_type result;
    EXPECT_TRUE(queue->pop(result));
    EXPECT_EQ(result.value, req.value);
}

TEST_F(async_request_queue, push_into_queue_with_null_capacity_should_return_error) {
    request_queue_ptr queue = make_queue(0);

    request req;
    req.value = 0;
    const bool result = queue->push(req, callback(expired), time_traits::duration(0));
    EXPECT_FALSE(result);
}

TEST_F(async_request_queue, pop_from_empty_should_return_error) {
    request_queue_ptr queue = make_queue(1);

    EXPECT_TRUE(queue->empty());
    request_queue::value_type result;
    EXPECT_FALSE(queue->pop(result));
}

}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

#include <UnitTest++/UnitTest++.h>
#include <gsl/gsl_byte>

#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>

using namespace std;
using namespace gsl;

namespace
{

SUITE(byte_tests)
{
    TEST(construction)
    {
        {
            byte b = static_cast<byte>(4);
            CHECK(static_cast<unsigned char>(b) == 4);
        }

        {
            byte b = byte(12);
            CHECK(static_cast<unsigned char>(b) == 12);
        }

        {
            byte b = to_byte<12>();
            CHECK(static_cast<unsigned char>(b) == 12);
        }
        {
            unsigned char uc = 12;
            byte b = to_byte(uc);
            CHECK(static_cast<unsigned char>(b) == 12);
        }

        // waiting for C++17 enum class direct initializer support
        //{
        //    byte b { 14 };
        //    CHECK(static_cast<unsigned char>(b) == 14);
        //}
    }

    TEST(bitwise_operations)
    {
        byte b = to_byte<0xFF>();

        byte a = to_byte<0x00>();
        CHECK((b | a) == to_byte<0xFF>());
        CHECK(a == to_byte<0x00>());

        a |= b;
        CHECK(a == to_byte<0xFF>());

        a = to_byte<0x01>();
        CHECK((b & a) == to_byte<0x01>());

        a &= b;
        CHECK(a == to_byte<0x01>());

        CHECK((b ^ a) == to_byte<0xFE>());

        CHECK(a == to_byte<0x01>());
        a ^= b;
        CHECK(a == to_byte<0xFE>());

        a = to_byte<0x01>();
        CHECK(~a == to_byte<0xFE>());

        a = to_byte<0xFF>();
        CHECK((a << 4) == to_byte<0xF0>());
        CHECK((a >> 4) == to_byte<0x0F>());

        a <<= 4;
        CHECK(a == to_byte<0xF0>());
        a >>= 4;
        CHECK(a == to_byte<0x0F>());
    }
}

}

int main(int, const char* []) { return UnitTest::RunAllTests(); }
<commit_msg>Add tests for to_integer(): they fail<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

#include <UnitTest++/UnitTest++.h>
#include <gsl/gsl_byte>

#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>

using namespace std;
using namespace gsl;

namespace
{

SUITE(byte_tests)
{
    TEST(construction)
    {
        {
            byte b = static_cast<byte>(4);
            CHECK(static_cast<unsigned char>(b) == 4);
        }

        {
            byte b = byte(12);
            CHECK(static_cast<unsigned char>(b) == 12);
        }

        {
            byte b = to_byte<12>();
            CHECK(static_cast<unsigned char>(b) == 12);
        }
        {
            unsigned char uc = 12;
            byte b = to_byte(uc);
            CHECK(static_cast<unsigned char>(b) == 12);
        }

        // waiting for C++17 enum class direct initializer support
        //{
        //    byte b { 14 };
        //    CHECK(static_cast<unsigned char>(b) == 14);
        //}
    }

    TEST(bitwise_operations)
    {
        byte b = to_byte<0xFF>();

        byte a = to_byte<0x00>();
        CHECK((b | a) == to_byte<0xFF>());
        CHECK(a == to_byte<0x00>());

        a |= b;
        CHECK(a == to_byte<0xFF>());

        a = to_byte<0x01>();
        CHECK((b & a) == to_byte<0x01>());

        a &= b;
        CHECK(a == to_byte<0x01>());

        CHECK((b ^ a) == to_byte<0xFE>());

        CHECK(a == to_byte<0x01>());
        a ^= b;
        CHECK(a == to_byte<0xFE>());

        a = to_byte<0x01>();
        CHECK(~a == to_byte<0xFE>());

        a = to_byte<0xFF>();
        CHECK((a << 4) == to_byte<0xF0>());
        CHECK((a >> 4) == to_byte<0x0F>());

        a <<= 4;
        CHECK(a == to_byte<0xF0>());
        a >>= 4;
        CHECK(a == to_byte<0x0F>());
    }

    TEST(to_integer)
    {
        byte b = to_byte<0x12>();

        CHECK(0x12 == gsl::to_integer<char>(b));
        CHECK(0x12 == gsl::to_integer<short>(b));
        CHECK(0x12 == gsl::to_integer<long>(b));
        CHECK(0x12 == gsl::to_integer<long long>(b));

        CHECK(0x12 == gsl::to_integer<unsigned char>(b));
        CHECK(0x12 == gsl::to_integer<unsigned short>(b));
        CHECK(0x12 == gsl::to_integer<unsigned long>(b));
        CHECK(0x12 == gsl::to_integer<unsigned long long>(b));

//      CHECK(0x12 == gsl::to_integer<float>(b));   // expect compile-time error
//      CHECK(0x12 == gsl::to_integer<double>(b));  // expect compile-time error
    }
}

}

int main(int, const char* []) { return UnitTest::RunAllTests(); }
<|endoftext|>


<commit_before>// Module:  Log4CPLUS
// File:    filter.cxx
// Created: 5/2003
// Author:  Tad E. Smith
//
//
// Copyright 2003-2015 Tad E. Smith
//
// 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 <log4cplus/spi/filter.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/spi/loggingevent.h>
#include <log4cplus/thread/syncprims-pub-impl.h>

namespace log4cplus { namespace spi {

///////////////////////////////////////////////////////////////////////////////
// global methods
///////////////////////////////////////////////////////////////////////////////

FilterResult
checkFilter(const Filter* filter, const InternalLoggingEvent& event)
{
    const Filter* currentFilter = filter;
    while(currentFilter) {
        FilterResult result = currentFilter->decide(event);
        if(result != NEUTRAL) {
            return result;
        }

        currentFilter = currentFilter->next.get();
    }

    return ACCEPT;
}

///////////////////////////////////////////////////////////////////////////////
// Filter implementation
///////////////////////////////////////////////////////////////////////////////

Filter::Filter()
{
}

Filter::~Filter()
{
}

void
Filter::appendFilter(FilterPtr filter)
{
    if (! next)
        next = filter;
    else
        next->appendFilter(filter);
}

///////////////////////////////////////////////////////////////////////////////
// DenyAllFilter implementation
///////////////////////////////////////////////////////////////////////////////

DenyAllFilter::DenyAllFilter ()
{ }

DenyAllFilter::DenyAllFilter (const helpers::Properties&)
{ }

FilterResult
DenyAllFilter::decide(const InternalLoggingEvent&) const
{
    return DENY;
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelMatchFilter::LogLevelMatchFilter()
{
    init();
}

LogLevelMatchFilter::LogLevelMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch, LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_to_match
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelToMatch") );
    logLevelToMatch = getLogLevelManager().fromString(log_level_to_match);
}

void
LogLevelMatchFilter::init()
{
    acceptOnMatch = true;
    logLevelToMatch = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelMatchFilter::decide(const InternalLoggingEvent& event) const
{
    if(logLevelToMatch == NOT_SET_LOG_LEVEL) {
        return NEUTRAL;
    }

    bool matchOccured = (logLevelToMatch == event.getLogLevel());

    if(matchOccured) {
        return (acceptOnMatch ? ACCEPT : DENY);
    }
    else {
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelRangeFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelRangeFilter::LogLevelRangeFilter()
{
    init();
}

LogLevelRangeFilter::LogLevelRangeFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_min
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMin") );
    logLevelMin = getLogLevelManager().fromString(log_level_min);

    tstring const & log_level_max
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMax") );
    logLevelMax = getLogLevelManager().fromString(log_level_max);
}

void
LogLevelRangeFilter::init()
{
    acceptOnMatch = true;
    logLevelMin = NOT_SET_LOG_LEVEL;
    logLevelMax = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelRangeFilter::decide(const InternalLoggingEvent& event) const
{
    if((logLevelMin != NOT_SET_LOG_LEVEL) && (event.getLogLevel() < logLevelMin)) {
        // priority of event is less than minimum
        return DENY;
    }

    if((logLevelMax != NOT_SET_LOG_LEVEL) && (event.getLogLevel() > logLevelMax)) {
        // priority of event is greater than maximum
        return DENY;
    }

    if(acceptOnMatch) {
        // this filter set up to bypass later filters and always return
        // accept if priority in range
        return ACCEPT;
    }
    else {
        // event is ok for this filter; allow later filters to have a look...
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// StringMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

StringMatchFilter::StringMatchFilter()
{
    init();
}

StringMatchFilter::StringMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));
    stringToMatch = properties.getProperty( LOG4CPLUS_TEXT("StringToMatch") );
}

void
StringMatchFilter::init()
{
    acceptOnMatch = true;
}

FilterResult
StringMatchFilter::decide(const InternalLoggingEvent& event) const
{
    const tstring& message = event.getMessage();

    if(stringToMatch.empty () || message.empty ()) {
        return NEUTRAL;
    }

    if(message.find(stringToMatch) == tstring::npos) {
        return NEUTRAL;
    }
    else {  // we've got a match
        return (acceptOnMatch ? ACCEPT : DENY);
    }
}

} } // namespace log4cplus { namespace spi {
<commit_msg>Fix StringMatchFilter bug when AcceptOnMatch is not provided. It should default to true but was false.<commit_after>// Module:  Log4CPLUS
// File:    filter.cxx
// Created: 5/2003
// Author:  Tad E. Smith
//
//
// Copyright 2003-2015 Tad E. Smith
//
// 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 <log4cplus/spi/filter.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/spi/loggingevent.h>
#include <log4cplus/thread/syncprims-pub-impl.h>

namespace log4cplus { namespace spi {

///////////////////////////////////////////////////////////////////////////////
// global methods
///////////////////////////////////////////////////////////////////////////////

FilterResult
checkFilter(const Filter* filter, const InternalLoggingEvent& event)
{
    const Filter* currentFilter = filter;
    while(currentFilter) {
        FilterResult result = currentFilter->decide(event);
        if(result != NEUTRAL) {
            return result;
        }

        currentFilter = currentFilter->next.get();
    }

    return ACCEPT;
}

///////////////////////////////////////////////////////////////////////////////
// Filter implementation
///////////////////////////////////////////////////////////////////////////////

Filter::Filter()
{
}

Filter::~Filter()
{
}

void
Filter::appendFilter(FilterPtr filter)
{
    if (! next)
        next = filter;
    else
        next->appendFilter(filter);
}

///////////////////////////////////////////////////////////////////////////////
// DenyAllFilter implementation
///////////////////////////////////////////////////////////////////////////////

DenyAllFilter::DenyAllFilter ()
{ }

DenyAllFilter::DenyAllFilter (const helpers::Properties&)
{ }

FilterResult
DenyAllFilter::decide(const InternalLoggingEvent&) const
{
    return DENY;
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelMatchFilter::LogLevelMatchFilter()
{
    init();
}

LogLevelMatchFilter::LogLevelMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch, LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_to_match
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelToMatch") );
    logLevelToMatch = getLogLevelManager().fromString(log_level_to_match);
}

void
LogLevelMatchFilter::init()
{
    acceptOnMatch = true;
    logLevelToMatch = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelMatchFilter::decide(const InternalLoggingEvent& event) const
{
    if(logLevelToMatch == NOT_SET_LOG_LEVEL) {
        return NEUTRAL;
    }

    bool matchOccured = (logLevelToMatch == event.getLogLevel());

    if(matchOccured) {
        return (acceptOnMatch ? ACCEPT : DENY);
    }
    else {
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// LogLevelRangeFilter implementation
///////////////////////////////////////////////////////////////////////////////

LogLevelRangeFilter::LogLevelRangeFilter()
{
    init();
}

LogLevelRangeFilter::LogLevelRangeFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch = false,
        LOG4CPLUS_TEXT("AcceptOnMatch"));

    tstring const & log_level_min
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMin") );
    logLevelMin = getLogLevelManager().fromString(log_level_min);

    tstring const & log_level_max
        = properties.getProperty( LOG4CPLUS_TEXT("LogLevelMax") );
    logLevelMax = getLogLevelManager().fromString(log_level_max);
}

void
LogLevelRangeFilter::init()
{
    acceptOnMatch = true;
    logLevelMin = NOT_SET_LOG_LEVEL;
    logLevelMax = NOT_SET_LOG_LEVEL;
}

FilterResult
LogLevelRangeFilter::decide(const InternalLoggingEvent& event) const
{
    if((logLevelMin != NOT_SET_LOG_LEVEL) && (event.getLogLevel() < logLevelMin)) {
        // priority of event is less than minimum
        return DENY;
    }

    if((logLevelMax != NOT_SET_LOG_LEVEL) && (event.getLogLevel() > logLevelMax)) {
        // priority of event is greater than maximum
        return DENY;
    }

    if(acceptOnMatch) {
        // this filter set up to bypass later filters and always return
        // accept if priority in range
        return ACCEPT;
    }
    else {
        // event is ok for this filter; allow later filters to have a look...
        return NEUTRAL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// StringMatchFilter implementation
///////////////////////////////////////////////////////////////////////////////

StringMatchFilter::StringMatchFilter()
{
    init();
}

StringMatchFilter::StringMatchFilter(const helpers::Properties& properties)
{
    init();

    properties.getBool (acceptOnMatch, LOG4CPLUS_TEXT("AcceptOnMatch"));
    stringToMatch = properties.getProperty( LOG4CPLUS_TEXT("StringToMatch") );
}

void
StringMatchFilter::init()
{
    acceptOnMatch = true;
}

FilterResult
StringMatchFilter::decide(const InternalLoggingEvent& event) const
{
    const tstring& message = event.getMessage();

    if(stringToMatch.empty () || message.empty ()) {
        return NEUTRAL;
    }

    if(message.find(stringToMatch) == tstring::npos) {
        return NEUTRAL;
    }
    else {  // we've got a match
        return (acceptOnMatch ? ACCEPT : DENY);
    }
}

} } // namespace log4cplus { namespace spi {
<|endoftext|>


<commit_before>#pragma once

#include <random>
#include <functional>

namespace dust
{
    template<class State, class Observation>
    class filter
    {
    public:
        using motion_model = std::function<std::pair<float, State>(const State&,
                                                                   const Observation&,
                                                                   float)>;
        using uniform_state = std::function<State()>;

        filter(motion_model motion, uniform_state uniform, unsigned int num_particles)
            : motion(motion),
              uniform(uniform),
              num_particles(num_particles),
              resample_dist(0, 1.0f / num_particles)
        {
            reset();
            sampled_particles.resize(num_particles);
        }

        void reset()
        {
            particles.clear();
            particles.reserve(num_particles);
            std::generate_n(std::back_inserter(particles), num_particles, uniform);
        }

        void update(const Observation& z, float dt)
        {
            sampled_particles.clear();
            sampled_particles.reserve(num_particles);
            std::transform(particles.begin(), particles.end(),
                           std::back_inserter(sampled_particles),
                           [&](const State& particle) {
                               return motion(particle, z, dt);
                           });

            particles.clear();
            auto r = resample_dist(gen);
            auto c = sampled_particles.front().second;
            unsigned int i = 0;
            for (unsigned int m = 0; m < num_particles; m++)
            {
                auto U = r + (m - 1.0f) / num_particles;
                while (U > c)
                {
                    i++;
                    c += sampled_particles[i].second;
                }
                particles.push_back(sampled_particles[i].first);
            }
        }

    protected:
        std::mt19937 gen;

    private:
        motion_model motion;
        uniform_state uniform;
        unsigned int num_particles;
        std::vector<State> particles;
        std::vector<std::pair<State, float>> sampled_particles;
        std::uniform_real_distribution<float> resample_dist;
    };
}
<commit_msg>made the random number generator private again<commit_after>#pragma once

#include <random>
#include <functional>

namespace dust
{
    template<class State, class Observation>
    class filter
    {
    public:
        using motion_model = std::function<std::pair<float, State>(const State&,
                                                                   const Observation&,
                                                                   float)>;
        using uniform_state = std::function<State()>;

        filter(motion_model motion, uniform_state uniform, unsigned int num_particles)
            : motion(motion),
              uniform(uniform),
              num_particles(num_particles),
              resample_dist(0, 1.0f / num_particles)
        {
            reset();
            sampled_particles.resize(num_particles);
        }

        void reset()
        {
            particles.clear();
            particles.reserve(num_particles);
            std::generate_n(std::back_inserter(particles), num_particles, uniform);
        }

        void update(const Observation& z, float dt)
        {
            sampled_particles.clear();
            sampled_particles.reserve(num_particles);
            std::transform(particles.begin(), particles.end(),
                           std::back_inserter(sampled_particles),
                           [&](const State& particle) {
                               return motion(particle, z, dt);
                           });

            particles.clear();
            auto r = resample_dist(gen);
            auto c = sampled_particles.front().second;
            unsigned int i = 0;
            for (unsigned int m = 0; m < num_particles; m++)
            {
                auto U = r + (m - 1.0f) / num_particles;
                while (U > c)
                {
                    i++;
                    c += sampled_particles[i].second;
                }
                particles.push_back(sampled_particles[i].first);
            }
        }

    private:
        motion_model motion;
        uniform_state uniform;
        unsigned int num_particles;
        std::vector<State> particles;
        std::vector<std::pair<State, float>> sampled_particles;
        std::mt19937 gen;
        std::uniform_real_distribution<float> resample_dist;
    };
}
<|endoftext|>