<commit_before>#include <QSettings>
#include <QDebug>
#include <QCoreApplication>
#include <QFile>
#include <QRegularExpression>

#include "QGC.h"
#include "QGCAudioWorker.h"
#include "GAudioOutput.h"

#if defined Q_OS_MAC && defined QGC_SPEECH_ENABLED
#include <ApplicationServices/ApplicationServices.h>
#endif

// Speech synthesis is only supported with MSVC compiler
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx
#include <sapi.h>
#endif

#if defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
// Using eSpeak for speech synthesis: following https://github.com/mondhs/espeak-sample/blob/master/sampleSpeak.cpp
#include <espeak/speak_lib.h>
#endif

#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_")

QGCAudioWorker::QGCAudioWorker(QObject *parent) :
    QObject(parent),
    voiceIndex(0),
    #if defined _MSC_VER && defined QGC_SPEECH_ENABLED
    pVoice(NULL),
    #endif
    #ifdef QGC_NOTIFY_TUNES_ENABLED
    sound(NULL),
    #endif
    emergency(false),
    muted(false)
{
    // Load settings
    QSettings settings;
    muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool();
}

void QGCAudioWorker::init()
{
#ifdef QGC_NOTIFY_TUNES_ENABLED
    sound = new QSound(":/files/audio/alert.wav");
#endif

#if defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
    espeak_Initialize(AUDIO_OUTPUT_SYNCH_PLAYBACK, 500, NULL, 0); // initialize for playback with 500ms buffer and no options (see speak_lib.h)
    espeak_VOICE *espeak_voice = espeak_GetCurrentVoice();
    espeak_voice->languages = "en-uk"; // Default to British English
    espeak_voice->identifier = NULL; // no specific voice file specified
    espeak_voice->name = "klatt"; // espeak voice name
    espeak_voice->gender = 2; // Female
    espeak_voice->age = 0; // age not specified
    espeak_SetVoiceByProperties(espeak_voice);
#endif

#if defined _MSC_VER && defined QGC_SPEECH_ENABLED

    if (FAILED(::CoInitialize(NULL)))
    {
        qDebug() << "ERROR: Creating COM object for audio output failed!";
    }
    else
    {

        HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

        if (FAILED(hr))
        {
            qDebug() << "ERROR: Initializing voice for audio output failed!";
        }
    }

#endif
}

QGCAudioWorker::~QGCAudioWorker()
{
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
	if (pVoice) {
		pVoice->Release();
		pVoice = NULL;
	}
    ::CoUninitialize();
#endif
}

void QGCAudioWorker::say(QString inText, int severity)
{
	static bool threadInit = false;
	if (!threadInit) {
		threadInit = true;
		init();
	}

    if (!muted)
    {
        QString text = _fixMillisecondString(inText);
        // Prepend high priority text with alert beep
        if (severity < GAudioOutput::AUDIO_SEVERITY_CRITICAL) {
            beep();
        }

#ifdef QGC_NOTIFY_TUNES_ENABLED
        // Wait for the last sound to finish
        while (!sound->isFinished()) {
            QGC::SLEEP::msleep(100);
        }
#endif

#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
        HRESULT hr = pVoice->Speak(text.toStdWString().c_str(), SPF_DEFAULT, NULL);
		if (FAILED(hr)) {
			qDebug() << "Speak failed, HR:" << QString("%1").arg(hr, 0, 16);
		}
#elif defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
        // Set size of string for espeak: +1 for the null-character
        unsigned int espeak_size = strlen(text.toStdString().c_str()) + 1;
        espeak_Synth(text.toStdString().c_str(), espeak_size, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL);

#elif defined Q_OS_MAC && defined QGC_SPEECH_ENABLED
        // Slashes necessary to have the right start to the sentence
        // copying data prevents SpeakString from reading additional chars
        text = "\\" + text;
        std::wstring str = text.toStdWString();
        unsigned char str2[1024] = {};
        memcpy(str2, text.toLatin1().data(), str.length());
        SpeakString(str2);

        // Block the thread while busy
        // because we run in our own thread, this doesn't
        // halt the main application
        while (SpeechBusy()) {
            QGC::SLEEP::msleep(100);
        }

#else
        // Make sure there isn't an unused variable warning when speech output is disabled
        Q_UNUSED(inText);
#endif
    }
}

void QGCAudioWorker::mute(bool mute)
{
    if (mute != muted)
    {
        this->muted = mute;
        QSettings settings;
        settings.setValue(QGC_GAUDIOOUTPUT_KEY + "muted", this->muted);
//        emit mutedChanged(muted);
    }
}

void QGCAudioWorker::beep()
{

    if (!muted)
    {
#ifdef QGC_NOTIFY_TUNES_ENABLED
        sound->play(":/files/audio/alert.wav");
#endif
    }
}

bool QGCAudioWorker::isMuted()
{
    return this->muted;
}

bool QGCAudioWorker::_getMillisecondString(const QString& string, QString& match, int& number) {
    QRegularExpression re("([0-9]*ms)");
    QRegularExpressionMatchIterator i = re.globalMatch(string);
    while (i.hasNext()) {
        QRegularExpressionMatch qmatch = i.next();
        if (qmatch.hasMatch()) {
            match = qmatch.captured(0);
            number = qmatch.captured(0).replace("ms", "").toInt();
            return true;
        }
    }
    return false;
}

QString QGCAudioWorker::_fixMillisecondString(const QString& string) {
    QString match;
    QString newNumber;
    QString result = string;
    int number;
    if(_getMillisecondString(string, match, number) && number > 1000) {
        if(number < 60000) {
            int seconds = number / 1000;
            newNumber = QString("%1 second%2").arg(seconds).arg(seconds > 1 ? "s" : "");
        } else {
            int minutes = number / 60000;
            int seconds = (number - (minutes * 60000)) / 1000;
            if (!seconds) {
                newNumber = QString("%1 minute%2").arg(minutes).arg(minutes > 1 ? "s" : "");
            } else {
                newNumber = QString("%1 minute%2 and %3 second%4").arg(minutes).arg(minutes > 1 ? "s" : "").arg(seconds).arg(seconds > 1 ? "s" : "");
            }
        }
        result.replace(match, newNumber);
    }
    return result;
}
<commit_msg>Text to speech tweak.<commit_after>#include <QSettings>
#include <QDebug>
#include <QCoreApplication>
#include <QFile>
#include <QRegularExpression>

#include "QGC.h"
#include "QGCAudioWorker.h"
#include "GAudioOutput.h"

#if defined Q_OS_MAC && defined QGC_SPEECH_ENABLED
#include <ApplicationServices/ApplicationServices.h>
#endif

// Speech synthesis is only supported with MSVC compiler
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx
#include <sapi.h>
#endif

#if defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
// Using eSpeak for speech synthesis: following https://github.com/mondhs/espeak-sample/blob/master/sampleSpeak.cpp
#include <espeak/speak_lib.h>
#endif

#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_")

QGCAudioWorker::QGCAudioWorker(QObject *parent) :
    QObject(parent),
    voiceIndex(0),
    #if defined _MSC_VER && defined QGC_SPEECH_ENABLED
    pVoice(NULL),
    #endif
    #ifdef QGC_NOTIFY_TUNES_ENABLED
    sound(NULL),
    #endif
    emergency(false),
    muted(false)
{
    // Load settings
    QSettings settings;
    muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool();
}

void QGCAudioWorker::init()
{
#ifdef QGC_NOTIFY_TUNES_ENABLED
    sound = new QSound(":/files/audio/alert.wav");
#endif

#if defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
    espeak_Initialize(AUDIO_OUTPUT_SYNCH_PLAYBACK, 500, NULL, 0); // initialize for playback with 500ms buffer and no options (see speak_lib.h)
    espeak_VOICE *espeak_voice = espeak_GetCurrentVoice();
    espeak_voice->languages = "en-uk"; // Default to British English
    espeak_voice->identifier = NULL; // no specific voice file specified
    espeak_voice->name = "klatt"; // espeak voice name
    espeak_voice->gender = 2; // Female
    espeak_voice->age = 0; // age not specified
    espeak_SetVoiceByProperties(espeak_voice);
#endif

#if defined _MSC_VER && defined QGC_SPEECH_ENABLED

    if (FAILED(::CoInitialize(NULL)))
    {
        qDebug() << "ERROR: Creating COM object for audio output failed!";
    }
    else
    {

        HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

        if (FAILED(hr))
        {
            qDebug() << "ERROR: Initializing voice for audio output failed!";
        }
    }

#endif
}

QGCAudioWorker::~QGCAudioWorker()
{
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
	if (pVoice) {
		pVoice->Release();
		pVoice = NULL;
	}
    ::CoUninitialize();
#endif
}

void QGCAudioWorker::say(QString inText, int severity)
{
	static bool threadInit = false;
	if (!threadInit) {
		threadInit = true;
		init();
	}

    if (!muted)
    {
        QString text = _fixMillisecondString(inText);
        // Prepend high priority text with alert beep
        if (severity < GAudioOutput::AUDIO_SEVERITY_CRITICAL) {
            beep();
        }

#ifdef QGC_NOTIFY_TUNES_ENABLED
        // Wait for the last sound to finish
        while (!sound->isFinished()) {
            QGC::SLEEP::msleep(100);
        }
#endif

#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
        HRESULT hr = pVoice->Speak(text.toStdWString().c_str(), SPF_DEFAULT, NULL);
		if (FAILED(hr)) {
			qDebug() << "Speak failed, HR:" << QString("%1").arg(hr, 0, 16);
		}
#elif defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
        // Set size of string for espeak: +1 for the null-character
        unsigned int espeak_size = strlen(text.toStdString().c_str()) + 1;
        espeak_Synth(text.toStdString().c_str(), espeak_size, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL);

#elif defined Q_OS_MAC && defined QGC_SPEECH_ENABLED
        // Slashes necessary to have the right start to the sentence
        // copying data prevents SpeakString from reading additional chars
        text = "\\" + text;
        std::wstring str = text.toStdWString();
        unsigned char str2[1024] = {};
        memcpy(str2, text.toLatin1().data(), str.length());
        SpeakString(str2);

        // Block the thread while busy
        // because we run in our own thread, this doesn't
        // halt the main application
        while (SpeechBusy()) {
            QGC::SLEEP::msleep(100);
        }

#else
        // Make sure there isn't an unused variable warning when speech output is disabled
        Q_UNUSED(inText);
#endif
    }
}

void QGCAudioWorker::mute(bool mute)
{
    if (mute != muted)
    {
        this->muted = mute;
        QSettings settings;
        settings.setValue(QGC_GAUDIOOUTPUT_KEY + "muted", this->muted);
//        emit mutedChanged(muted);
    }
}

void QGCAudioWorker::beep()
{

    if (!muted)
    {
#ifdef QGC_NOTIFY_TUNES_ENABLED
        sound->play(":/files/audio/alert.wav");
#endif
    }
}

bool QGCAudioWorker::isMuted()
{
    return this->muted;
}

bool QGCAudioWorker::_getMillisecondString(const QString& string, QString& match, int& number) {
    static QRegularExpression re("([0-9]+ms)");
    QRegularExpressionMatchIterator i = re.globalMatch(string);
    while (i.hasNext()) {
        QRegularExpressionMatch qmatch = i.next();
        if (qmatch.hasMatch()) {
            match = qmatch.captured(0);
            number = qmatch.captured(0).replace("ms", "").toInt();
            return true;
        }
    }
    return false;
}

QString QGCAudioWorker::_fixMillisecondString(const QString& string) {
    QString match;
    QString newNumber;
    QString result = string;
    int number;
    if(_getMillisecondString(string, match, number) && number > 1000) {
        if(number < 60000) {
            int seconds = number / 1000;
            newNumber = QString("%1 second%2").arg(seconds).arg(seconds > 1 ? "s" : "");
        } else {
            int minutes = number / 60000;
            int seconds = (number - (minutes * 60000)) / 1000;
            if (!seconds) {
                newNumber = QString("%1 minute%2").arg(minutes).arg(minutes > 1 ? "s" : "");
            } else {
                newNumber = QString("%1 minute%2 and %3 second%4").arg(minutes).arg(minutes > 1 ? "s" : "").arg(seconds).arg(seconds > 1 ? "s" : "");
            }
        }
        result.replace(match, newNumber);
    }
    return result;
}
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/* Copyright (c) FFLAS-FFPACK
 * Written by Philippe LEDENT <philippe.ledent@etu.univ-grenoble-alpes.fr>
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 */

#include "fflas-ffpack/fflas-ffpack-config.h"
#include <iostream>
#include <givaro/modular.h>
#include <givaro/givrational.h>

#include "fflas-ffpack/fflas-ffpack.h"
#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/utils/fflas_io.h"
#include "fflas-ffpack/paladin/parallel.h"
#include "fflas-ffpack/paladin/fflas_plevel1.h"
#include "fflas-ffpack/utils/args-parser.h"

using namespace std;
using namespace FFLAS;
using namespace FFPACK;

template<class Field>
typename Field::Element run_with_field(int q, size_t iter, size_t N, const size_t BS, const size_t p, const size_t threads){
    Field F(q);
    typename Field::RandIter G(F, BS);

	typename Field::Element_ptr A, B;
	typename Field::Element d; F.init(d);

#ifdef __GIVARO_USE_OPENMP
	Givaro::OMPTimer chrono, time;
#else
	Givaro::Timer chrono, time;
#endif
	time.clear();

	for (size_t i=0;i<iter;++i){
		A = fflas_new(F, N);
		B = fflas_new(F, N);

        PAR_BLOCK { pfrand(F, G, N, 1, A); pfrand(F, G, N, 1, B); }

//         FFLAS::WriteMatrix(std::cerr, F, 1, N, A, 1);
//         FFLAS::WriteMatrix(std::cerr, F, 1, N, B, 1);

        F.assign(d, F.zero);

        FFLAS::ParSeqHelper::Parallel<
            FFLAS::CuttingStrategy::Block,
            FFLAS::StrategyParameter::Threads> ParHelper(threads);

		chrono.clear();
        if (p){
            chrono.start();
            F.assign(d, fdot(F, N, A, 1U, B, 1U, ParHelper));
            chrono.stop();
        } else {
            chrono.start();
            F.assign(d, fdot(F, N, A, 1U, B, 1U, FFLAS::ParSeqHelper::Sequential()));
            chrono.stop();
        }

        // std::cerr << chrono
        //           << " Gfops: " << ((double(2*N)/1000.)/1000.)/(1000.*chrono.realtime())
        //           << std::endl;

		time+=chrono;
		FFLAS::fflas_delete(A);
		FFLAS::fflas_delete(B);
	}
		// -----------
		// Standard output for benchmark
	std::cout << "Time: " << time
			  << " Gfops: " << ((double(2*N)/1000.)/1000.)/(1000.*time.realtime())* double(iter);

// 	F.write(std::cerr, d) << std::endl;
    return d;
}

int main(int argc, char** argv) {

	size_t iter = 3;
	size_t N    = 5000;
    size_t BS   = 5000;
    int q		= 131071101;
	size_t p	=0;
    size_t maxallowed_threads; PAR_BLOCK { maxallowed_threads=NUM_THREADS; }
    size_t threads=maxallowed_threads;

	Argument as[] = {
		{ 'n', "-n N", "Set the dimension of the matrix C.",TYPE_INT , &N },
        { 'q', "-q Q", "Set the field characteristic (0 for the integers).",         TYPE_INT , &q },
		{ 'i', "-i R", "Set number of repetitions.",		TYPE_INT , &iter },
		{ 'b', "-b B", "Set the bitsize of the random elements.",         TYPE_INT , &BS},
		{ 'p', "-p P", "0 for sequential, 1 for parallel.",	TYPE_INT , &p },
		{ 't', "-t T", "number of virtual threads to drive the partition.", TYPE_INT , &threads },
		END_OF_ARGUMENTS
	};

    FFLAS::parseArguments(argc,argv,as);

    if (q > 0){
        BS = Givaro::Integer(q).bitsize();
        double d = run_with_field<Givaro::ModularBalanced<double> >(q, iter, N, BS, p, threads);
        std::cout << ", d: " << d;
    } else {
        auto d = run_with_field<Givaro::ZRing<Givaro::Integer> > (q, iter, N, BS, p, threads);
        std::cout << ", size: " << logtwo(d>0?d:-d);
    }

    FFLAS::writeCommandString(std::cerr, as) << std::endl;
    return 0;
}
<commit_msg>fix output<commit_after>/* -*- mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
// vim:sts=4:sw=4:ts=4:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

/* Copyright (c) FFLAS-FFPACK
 * Written by Philippe LEDENT <philippe.ledent@etu.univ-grenoble-alpes.fr>
 * ========LICENCE========
 * This file is part of the library FFLAS-FFPACK.
 *
 * FFLAS-FFPACK is free software: you can redistribute it and/or modify
 * it under the terms of the  GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========
 */

#include "fflas-ffpack/fflas-ffpack-config.h"
#include <iostream>
#include <givaro/modular.h>
#include <givaro/givrational.h>

#include "fflas-ffpack/fflas-ffpack.h"
#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/utils/fflas_io.h"
#include "fflas-ffpack/paladin/parallel.h"
#include "fflas-ffpack/paladin/fflas_plevel1.h"
#include "fflas-ffpack/utils/args-parser.h"

using namespace std;
using namespace FFLAS;
using namespace FFPACK;

template<class Field>
typename Field::Element run_with_field(int q, size_t iter, size_t N, const size_t BS, const size_t p, const size_t threads){
    Field F(q);
    typename Field::RandIter G(F, BS);

	typename Field::Element_ptr A, B;
	typename Field::Element d; F.init(d);

#ifdef __GIVARO_USE_OPENMP
	Givaro::OMPTimer chrono, time;
#else
	Givaro::Timer chrono, time;
#endif
	time.clear();

	for (size_t i=0;i<iter;++i){
		A = fflas_new(F, N);
		B = fflas_new(F, N);

        PAR_BLOCK { pfrand(F, G, N, 1, A); pfrand(F, G, N, 1, B); }

//         FFLAS::WriteMatrix(std::cerr, F, 1, N, A, 1);
//         FFLAS::WriteMatrix(std::cerr, F, 1, N, B, 1);

        F.assign(d, F.zero);

        FFLAS::ParSeqHelper::Parallel<
            FFLAS::CuttingStrategy::Block,
            FFLAS::StrategyParameter::Threads> ParHelper(threads);

		chrono.clear();
        if (p){
            chrono.start();
            F.assign(d, fdot(F, N, A, 1U, B, 1U, ParHelper));
            chrono.stop();
        } else {
            chrono.start();
            F.assign(d, fdot(F, N, A, 1U, B, 1U, FFLAS::ParSeqHelper::Sequential()));
            chrono.stop();
        }

        // std::cerr << chrono
        //           << " Gfops: " << ((double(2*N)/1000.)/1000.)/(1000.*chrono.realtime())
        //           << std::endl;

		time+=chrono;
		FFLAS::fflas_delete(A);
		FFLAS::fflas_delete(B);
	}
		// -----------
		// Standard output for benchmark
	std::cout << "Time: " << time.realtime()
			  << " Gfops: " << ((double(2*N)/1000.)/1000.)/(1000.*time.realtime())* double(iter);

// 	F.write(std::cerr, d) << std::endl;
    return d;
}

int main(int argc, char** argv) {

	size_t iter = 3;
	size_t N    = 5000;
    size_t BS   = 5000;
    int q		= 131071101;
	size_t p	=0;
    size_t maxallowed_threads; PAR_BLOCK { maxallowed_threads=NUM_THREADS; }
    size_t threads=maxallowed_threads;

	Argument as[] = {
		{ 'n', "-n N", "Set the dimension of the matrix C.",TYPE_INT , &N },
        { 'q', "-q Q", "Set the field characteristic (0 for the integers).",         TYPE_INT , &q },
		{ 'i', "-i R", "Set number of repetitions.",		TYPE_INT , &iter },
		{ 'b', "-b B", "Set the bitsize of the random elements.",         TYPE_INT , &BS},
		{ 'p', "-p P", "0 for sequential, 1 for parallel.",	TYPE_INT , &p },
		{ 't', "-t T", "number of virtual threads to drive the partition.", TYPE_INT , &threads },
		END_OF_ARGUMENTS
	};

    FFLAS::parseArguments(argc,argv,as);

    if (q > 0){
        BS = Givaro::Integer(q).bitsize();
        double d = run_with_field<Givaro::ModularBalanced<double> >(q, iter, N, BS, p, threads);
        std::cout << ", d: " << d;
    } else {
        auto d = run_with_field<Givaro::ZRing<Givaro::Integer> > (q, iter, N, BS, p, threads);
        std::cout << ", size: " << logtwo(d>0?d:-d);
    }

    FFLAS::writeCommandString(std::cerr, as) << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>
// .\Release\x64\benchmarks.exe --benchmark_repetitions=10 --benchmark_min_time=2 --benchmark_filter=Geopotential  // NOLINT(whitespace/line_length)

#include "physics/geopotential_body.hpp"

#include <random>
#include <vector>

#include "astronomy/fortran_astrodynamics_toolkit.hpp"
#include "astronomy/frames.hpp"
#include "base/not_null.hpp"
#include "benchmark/benchmark.h"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/r3_element.hpp"
#include "numerics/fixed_arrays.hpp"
#include "numerics/legendre.hpp"
#include "physics/solar_system.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/parser.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace physics {

using astronomy::ICRS;
using astronomy::ITRS;
using base::not_null;
using geometry::Displacement;
using geometry::Instant;
using geometry::R3Element;
using geometry::Vector;
using numerics::FixedMatrix;
using numerics::LegendreNormalizationFactor;
using physics::SolarSystem;
using quantities::Acceleration;
using quantities::Angle;
using quantities::Exponentiation;
using quantities::GravitationalParameter;
using quantities::Length;
using quantities::ParseQuantity;
using quantities::Pow;
using quantities::Quotient;
using quantities::SIUnit;
using quantities::Sqrt;
using quantities::si::Degree;
using quantities::si::Kilo;
using quantities::si::Metre;
using quantities::si::Radian;
using quantities::si::Second;

template<typename Frame>
Vector<Quotient<Acceleration, GravitationalParameter>, Frame>
GeneralSphericalHarmonicsAccelerationCpp(
    Geopotential<Frame> const& geopotential,
    Instant const& t,
    Displacement<Frame> const& r) {
  auto const r² = r.Norm²();
  auto const r_norm = Sqrt(r²);
  auto const one_over_r³ = r_norm / (r² * r²);
  return geopotential.GeneralSphericalHarmonicsAcceleration(
      t, r, r_norm, r², one_over_r³);
}

// For fairness, the Fortran implementation is wrapped to have the same API as
// the C++ one.
template<typename Frame, int degree, int order>
Vector<Quotient<Acceleration, GravitationalParameter>, Frame>
GeneralSphericalHarmonicsAccelerationF90(
    not_null<OblateBody<Frame> const*> const body,
    double const mu,
    double const rbar,
    FixedMatrix<double, degree + 1, order + 1> const& cnm,
    FixedMatrix<double, degree + 1, order + 1> const& snm,
    Instant const& t,
    Displacement<Frame> const& r) {
  struct SurfaceFrame;
  auto const from_surface_frame =
      body->template FromSurfaceFrame<SurfaceFrame>(t);
  auto const to_surface_frame = from_surface_frame.Inverse();

  Displacement<SurfaceFrame> const r_surface = to_surface_frame(r);
  auto const acceleration_surface =
      Vector<Quotient<Acceleration, GravitationalParameter>, SurfaceFrame>(
          SIUnit<Quotient<Acceleration, GravitationalParameter>>() *
          astronomy::fortran_astrodynamics_toolkit::
              ComputeGravityAccelerationLear<degree, order>(
                  r_surface.coordinates() / Metre, mu, rbar, cnm, snm));
  return from_surface_frame(acceleration_surface);
}

OblateBody<ICRS> MakeEarthBody(SolarSystem<ICRS>& solar_system,
                               int const max_degree) {
  solar_system.LimitOblatenessToDegree("Earth", max_degree);
  auto earth_message = solar_system.gravity_model_message("Earth");

  Angle const earth_right_ascension_of_pole = 0 * Degree;
  Angle const earth_declination_of_pole = 90 * Degree;
  auto const earth_μ = solar_system.gravitational_parameter("Earth");
  auto const earth_reference_radius =
      ParseQuantity<Length>(earth_message.reference_radius());
  MassiveBody::Parameters const massive_body_parameters(earth_μ);
  RotatingBody<ICRS>::Parameters rotating_body_parameters(
      /*mean_radius=*/solar_system.mean_radius("Earth"),
      /*reference_angle=*/0 * Radian,
      /*reference_instant=*/Instant(),
      /*angular_frequency=*/1 * Radian / Second,
      earth_right_ascension_of_pole,
      earth_declination_of_pole);
  return OblateBody<ICRS>(
      massive_body_parameters,
      rotating_body_parameters,
      OblateBody<ICRS>::Parameters::ReadFromMessage(
          earth_message.geopotential(), earth_reference_radius));
}

void BM_ComputeGeopotentialCpp(benchmark::State& state) {
  int const max_degree = state.range(0);

  SolarSystem<ICRS> solar_system_2000(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt");

  auto const earth = MakeEarthBody(solar_system_2000, max_degree);
  Geopotential<ICRS> const geopotential(&earth, /*tolerance=*/0);

  std::mt19937_64 random(42);
  std::uniform_real_distribution<> distribution(-1e7, 1e7);
  std::vector<Displacement<ICRS>> displacements;
  for (int i = 0; i < 1e3; ++i) {
    displacements.push_back(earth.FromSurfaceFrame<ITRS>(Instant())(
        Displacement<ITRS>({distribution(random) * Metre,
                            distribution(random) * Metre,
                            distribution(random) * Metre})));
  }

  while (state.KeepRunning()) {
    Vector<Exponentiation<Length, -2>, ICRS> acceleration;
    for (auto const& displacement : displacements) {
      acceleration = GeneralSphericalHarmonicsAccelerationCpp(
                         geopotential, Instant(), displacement);
    }
    benchmark::DoNotOptimize(acceleration);
  }
}

void BM_ComputeGeopotentialDistance(benchmark::State& state) {
  // Check the performance around this distance.  May be used to tell apart the
  // various contributions.
  double const distance_in_kilometres = state.range(0);

  SolarSystem<ICRS> solar_system_2000(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt");

  auto const earth = MakeEarthBody(solar_system_2000, /*max_degree=*/10);
  Geopotential<ICRS> const geopotential(&earth, /*tolerance=*/0x1.0p-24);

  std::mt19937_64 random(42);
  std::uniform_real_distribution<> distribution(0.9 * distance_in_kilometres,
                                                1.1 * distance_in_kilometres);
  std::vector<Displacement<ICRS>> displacements;
  for (int i = 0; i < 1e3; ++i) {
    displacements.push_back(earth.FromSurfaceFrame<ITRS>(Instant())(
        Displacement<ITRS>({distribution(random) * Kilo(Metre),
                            distribution(random) * Kilo(Metre),
                            distribution(random) * Kilo(Metre)})));
  }

  while (state.KeepRunning()) {
    Vector<Exponentiation<Length, -2>, ICRS> acceleration;
    for (auto const& displacement : displacements) {
      acceleration = GeneralSphericalHarmonicsAccelerationCpp(
                         geopotential, Instant(), displacement);
    }
    benchmark::DoNotOptimize(acceleration);
  }
}

#define PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(d)                         \
  case (d): {                                                              \
    numerics::FixedMatrix<double, (d) + 1, (d) + 1> cnm;                   \
    numerics::FixedMatrix<double, (d) + 1, (d) + 1> snm;                   \
    for (int n = 0; n <= (d); ++n) {                                       \
      for (int m = 0; m <= n; ++m) {                                       \
        cnm[n][m] = earth.cos()[n][m] * LegendreNormalizationFactor(n, m); \
        snm[n][m] = earth.sin()[n][m] * LegendreNormalizationFactor(n, m); \
      }                                                                    \
    }                                                                      \
    while (state.KeepRunning()) {                                          \
      Vector<Exponentiation<Length, -2>, ICRS> acceleration;               \
      for (auto const& displacement : displacements) {                     \
        acceleration =                                                     \
            GeneralSphericalHarmonicsAccelerationF90<ICRS, (d), (d)>(      \
                &earth, mu, rbar, cnm, snm, Instant(), displacement);      \
      }                                                                    \
      benchmark::DoNotOptimize(acceleration);                              \
    }                                                                      \
    break;                                                                 \
  }

void BM_ComputeGeopotentialF90(benchmark::State& state) {
  int const max_degree = state.range(0);

  SolarSystem<ICRS> solar_system_2000(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt");
  auto const earth = MakeEarthBody(solar_system_2000, max_degree);

  double mu =
      earth.gravitational_parameter() / SIUnit<GravitationalParameter>();
  double rbar = earth.reference_radius() / Metre;

  std::mt19937_64 random(42);
  std::uniform_real_distribution<> distribution(-1e7, 1e7);
  std::vector<Displacement<ICRS>> displacements;
  for (int i = 0; i < 1e3; ++i) {
    displacements.push_back(earth.FromSurfaceFrame<ITRS>(Instant())(
        Displacement<ITRS>({distribution(random) * Metre,
                            distribution(random) * Metre,
                            distribution(random) * Metre})));
  }

  switch (max_degree) {
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(2);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(3);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(4);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(5);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(6);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(7);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(8);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(9);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(10);
  }
}

#undef PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90

BENCHMARK(BM_ComputeGeopotentialCpp)->Arg(2)->Arg(3)->Arg(5)->Arg(10);
BENCHMARK(BM_ComputeGeopotentialF90)->Arg(2)->Arg(3)->Arg(5)->Arg(10);
BENCHMARK(BM_ComputeGeopotentialDistance)
    ->Arg(80'000)      // C₂₂, S₂₂, J₂.
    ->Arg(500'000)     // J₂.
    ->Arg(5'000'000);  // Central

}  // namespace physics
}  // namespace principia
<commit_msg>After egg's review.<commit_after>
// .\Release\x64\benchmarks.exe --benchmark_repetitions=10 --benchmark_min_time=2 --benchmark_filter=Geopotential  // NOLINT(whitespace/line_length)

#include "physics/geopotential_body.hpp"

#include <random>
#include <vector>

#include "astronomy/fortran_astrodynamics_toolkit.hpp"
#include "astronomy/frames.hpp"
#include "base/not_null.hpp"
#include "benchmark/benchmark.h"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/r3_element.hpp"
#include "numerics/fixed_arrays.hpp"
#include "numerics/legendre.hpp"
#include "physics/solar_system.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/parser.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace physics {

using astronomy::ICRS;
using astronomy::ITRS;
using base::not_null;
using geometry::Displacement;
using geometry::Instant;
using geometry::R3Element;
using geometry::Vector;
using numerics::FixedMatrix;
using numerics::LegendreNormalizationFactor;
using physics::SolarSystem;
using quantities::Acceleration;
using quantities::Angle;
using quantities::Exponentiation;
using quantities::GravitationalParameter;
using quantities::Length;
using quantities::ParseQuantity;
using quantities::Pow;
using quantities::Quotient;
using quantities::SIUnit;
using quantities::Sqrt;
using quantities::si::Degree;
using quantities::si::Kilo;
using quantities::si::Metre;
using quantities::si::Radian;
using quantities::si::Second;

template<typename Frame>
Vector<Quotient<Acceleration, GravitationalParameter>, Frame>
GeneralSphericalHarmonicsAccelerationCpp(
    Geopotential<Frame> const& geopotential,
    Instant const& t,
    Displacement<Frame> const& r) {
  auto const r² = r.Norm²();
  auto const r_norm = Sqrt(r²);
  auto const one_over_r³ = r_norm / (r² * r²);
  return geopotential.GeneralSphericalHarmonicsAcceleration(
      t, r, r_norm, r², one_over_r³);
}

// For fairness, the Fortran implementation is wrapped to have the same API as
// the C++ one.
template<typename Frame, int degree, int order>
Vector<Quotient<Acceleration, GravitationalParameter>, Frame>
GeneralSphericalHarmonicsAccelerationF90(
    not_null<OblateBody<Frame> const*> const body,
    double const mu,
    double const rbar,
    FixedMatrix<double, degree + 1, order + 1> const& cnm,
    FixedMatrix<double, degree + 1, order + 1> const& snm,
    Instant const& t,
    Displacement<Frame> const& r) {
  struct SurfaceFrame;
  auto const from_surface_frame =
      body->template FromSurfaceFrame<SurfaceFrame>(t);
  auto const to_surface_frame = from_surface_frame.Inverse();

  Displacement<SurfaceFrame> const r_surface = to_surface_frame(r);
  auto const acceleration_surface =
      Vector<Quotient<Acceleration, GravitationalParameter>, SurfaceFrame>(
          SIUnit<Quotient<Acceleration, GravitationalParameter>>() *
          astronomy::fortran_astrodynamics_toolkit::
              ComputeGravityAccelerationLear<degree, order>(
                  r_surface.coordinates() / Metre, mu, rbar, cnm, snm));
  return from_surface_frame(acceleration_surface);
}

OblateBody<ICRS> MakeEarthBody(SolarSystem<ICRS>& solar_system,
                               int const max_degree) {
  solar_system.LimitOblatenessToDegree("Earth", max_degree);
  auto earth_message = solar_system.gravity_model_message("Earth");

  Angle const earth_right_ascension_of_pole = 0 * Degree;
  Angle const earth_declination_of_pole = 90 * Degree;
  auto const earth_μ = solar_system.gravitational_parameter("Earth");
  auto const earth_reference_radius =
      ParseQuantity<Length>(earth_message.reference_radius());
  MassiveBody::Parameters const massive_body_parameters(earth_μ);
  RotatingBody<ICRS>::Parameters rotating_body_parameters(
      /*mean_radius=*/solar_system.mean_radius("Earth"),
      /*reference_angle=*/0 * Radian,
      /*reference_instant=*/Instant(),
      /*angular_frequency=*/1 * Radian / Second,
      earth_right_ascension_of_pole,
      earth_declination_of_pole);
  return OblateBody<ICRS>(
      massive_body_parameters,
      rotating_body_parameters,
      OblateBody<ICRS>::Parameters::ReadFromMessage(
          earth_message.geopotential(), earth_reference_radius));
}

void BM_ComputeGeopotentialCpp(benchmark::State& state) {
  int const max_degree = state.range(0);

  SolarSystem<ICRS> solar_system_2000(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt");

  auto const earth = MakeEarthBody(solar_system_2000, max_degree);
  Geopotential<ICRS> const geopotential(&earth, /*tolerance=*/0);

  std::mt19937_64 random(42);
  std::uniform_real_distribution<> distribution(-1e7, 1e7);
  std::vector<Displacement<ICRS>> displacements;
  for (int i = 0; i < 1e3; ++i) {
    displacements.push_back(earth.FromSurfaceFrame<ITRS>(Instant())(
        Displacement<ITRS>({distribution(random) * Metre,
                            distribution(random) * Metre,
                            distribution(random) * Metre})));
  }

  while (state.KeepRunning()) {
    Vector<Exponentiation<Length, -2>, ICRS> acceleration;
    for (auto const& displacement : displacements) {
      acceleration = GeneralSphericalHarmonicsAccelerationCpp(
                         geopotential, Instant(), displacement);
    }
    benchmark::DoNotOptimize(acceleration);
  }
}

void BM_ComputeGeopotentialDistance(benchmark::State& state) {
  // Check the performance around this distance.  May be used to tell apart the
  // various contributions.
  double const distance_in_kilometres = state.range(0);

  SolarSystem<ICRS> solar_system_2000(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt");

  auto const earth = MakeEarthBody(solar_system_2000, /*max_degree=*/10);
  Geopotential<ICRS> const geopotential(&earth, /*tolerance=*/0x1.0p-24);

  // Generate points in a spherical shell.
  std::mt19937_64 random(42);
  std::uniform_real_distribution<> distribution(0 * distance_in_kilometres,
                                                1.1 * distance_in_kilometres);
  std::vector<Displacement<ICRS>> displacements;
  for (int i = 0; i < 1e3;) {
    Displacement<ITRS> const displacement({distribution(random) * Kilo(Metre),
                                           distribution(random) * Kilo(Metre),
                                           distribution(random) * Kilo(Metre)});
    if (displacement.Norm() > 0.9 * distance_in_kilometres * Kilo(Metre) &&
        displacement.Norm() < 1.1 * distance_in_kilometres * Kilo(Metre)) {
      displacements.push_back(
          earth.FromSurfaceFrame<ITRS>(Instant())(displacement));
      ++i;
    }
  }

  while (state.KeepRunning()) {
    Vector<Exponentiation<Length, -2>, ICRS> acceleration;
    for (auto const& displacement : displacements) {
      acceleration = GeneralSphericalHarmonicsAccelerationCpp(
                         geopotential, Instant(), displacement);
    }
    benchmark::DoNotOptimize(acceleration);
  }
}

#define PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(d)                         \
  case (d): {                                                              \
    numerics::FixedMatrix<double, (d) + 1, (d) + 1> cnm;                   \
    numerics::FixedMatrix<double, (d) + 1, (d) + 1> snm;                   \
    for (int n = 0; n <= (d); ++n) {                                       \
      for (int m = 0; m <= n; ++m) {                                       \
        cnm[n][m] = earth.cos()[n][m] * LegendreNormalizationFactor(n, m); \
        snm[n][m] = earth.sin()[n][m] * LegendreNormalizationFactor(n, m); \
      }                                                                    \
    }                                                                      \
    while (state.KeepRunning()) {                                          \
      Vector<Exponentiation<Length, -2>, ICRS> acceleration;               \
      for (auto const& displacement : displacements) {                     \
        acceleration =                                                     \
            GeneralSphericalHarmonicsAccelerationF90<ICRS, (d), (d)>(      \
                &earth, mu, rbar, cnm, snm, Instant(), displacement);      \
      }                                                                    \
      benchmark::DoNotOptimize(acceleration);                              \
    }                                                                      \
    break;                                                                 \
  }

void BM_ComputeGeopotentialF90(benchmark::State& state) {
  int const max_degree = state.range(0);

  SolarSystem<ICRS> solar_system_2000(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt");
  auto const earth = MakeEarthBody(solar_system_2000, max_degree);

  double mu =
      earth.gravitational_parameter() / SIUnit<GravitationalParameter>();
  double rbar = earth.reference_radius() / Metre;

  std::mt19937_64 random(42);
  std::uniform_real_distribution<> distribution(-1e7, 1e7);
  std::vector<Displacement<ICRS>> displacements;
  for (int i = 0; i < 1e3; ++i) {
    displacements.push_back(earth.FromSurfaceFrame<ITRS>(Instant())(
        Displacement<ITRS>({distribution(random) * Metre,
                            distribution(random) * Metre,
                            distribution(random) * Metre})));
  }

  switch (max_degree) {
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(2);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(3);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(4);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(5);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(6);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(7);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(8);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(9);
    PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90(10);
  }
}

#undef PRINCIPIA_CASE_COMPUTE_GEOPOTENTIAL_F90

BENCHMARK(BM_ComputeGeopotentialCpp)->Arg(2)->Arg(3)->Arg(5)->Arg(10);
BENCHMARK(BM_ComputeGeopotentialF90)->Arg(2)->Arg(3)->Arg(5)->Arg(10);
BENCHMARK(BM_ComputeGeopotentialDistance)
    ->Arg(80'000)      // C₂₂, S₂₂, J₂.
    ->Arg(500'000)     // J₂.
    ->Arg(5'000'000);  // Central

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>#include "manip.h"

using namespace std;

// Manipulator stuff is _always_ in namespace mysqlpp.
namespace mysqlpp {

extern bool dont_quote_auto;

// quote manipulator

bool dont_quote_auto = false;

SQLQueryParms& operator <<(quote_type2 p, SQLString& in)
{
	if (in.is_string) {
		if (in.dont_escape) {
			SQLString in2 = "'" + in + "'";
			 in2.processed = true;
			 return *p.qparms << in2;
		}
		else {
			char *s = new char[in.size() * 2 + 1];
			mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
			SQLString in2 = SQLString("'") + s + "'";
			in2.processed = true;
			*p.qparms << in2;
			delete[]s;
			return *p.qparms;
		}
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(quote_type1 o, const string& in)
{
	char *s = new char[in.size() * 2 + 1];
	mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
	*o.ostr << "'" << s << "'";
	delete[] s;
	return *o.ostr;
}

template<>
ostream& operator<<(quote_type1 o, const char* const& in)
{
	unsigned int size;
	for (size = 0; in[size]; size++) ;
	char *s = new char[size * 2 + 1];
	mysql_escape_string(s, const_cast < char *>(in), size);
	*o.ostr << "'" << s << "'";
	delete[] s;
	return *o.ostr;
}

template<class Str>
inline ostream& _manip(quote_type1 o, const ColData_Tmpl<Str>& in)
{
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		if (in.quote_q())
			*o.ostr << "'" << s << "'";
		else
			*o.ostr << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(quote_type1 o, const ColData_Tmpl<string>& in)
{
	return _manip(o, in);
}

template<>
ostream& operator<<(quote_type1 o, const ColData_Tmpl<const_string>& in)
{
	return _manip(o, in);
}

ostream& operator<<(ostream& o, const ColData_Tmpl<string>& in)
{
	if (dont_quote_auto || (o.rdbuf() == cout.rdbuf()) ||
			(o.rdbuf() == cerr.rdbuf())) {
		return o << in.get_string();
	}

	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		if (in.quote_q())
			o << "'" << s << "'";
		else
			o << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		o << "'" << in.get_string() << "'";
	}
	else {
		o << in.get_string();
	}
	return o;
}

ostream& operator<<(ostream& o, const ColData_Tmpl<const_string>& in)
{
	if (dont_quote_auto || (o.rdbuf() == cout.rdbuf()) ||
			(o.rdbuf() == cerr.rdbuf())) {
		return o << in.get_string();
	}

	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, const_cast < char *>(in.c_str()),
							in.size());
		if (in.quote_q())
			o << "'" << s << "'";
		else
			o << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		o << "'" << in.get_string() << "'";
	}
	else {
		o << in.get_string();
	}
	return o;
}

SQLQuery& operator<<(SQLQuery& o, const ColData_Tmpl<string>& in)
{
	if (dont_quote_auto) {
		o << in.get_string();
		return o;
	}
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		if (in.quote_q())
			static_cast<ostream &>(o) << "'" << s << "'";
		else
			static_cast<ostream &>(o) << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		static_cast<ostream &>(o) << "'" << in.get_string() << "'";
	}
	else {
		static_cast<ostream &>(o) << in.get_string();
	}
	return o;
}

SQLQuery& operator<<(SQLQuery& o, const ColData_Tmpl<const_string>& in)
{
	if (dont_quote_auto) {
		o << in.get_string();
		return o;
	}
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, const_cast < char *>(in.c_str()),
							in.size());
		if (in.quote_q())
			static_cast<ostream &>(o) << "'" << s << "'";
		else
			static_cast<ostream &>(o) << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		static_cast<ostream &>(o) << "'" << in.get_string() << "'";
	}
	else {
		static_cast<ostream &>(o) << in.get_string();
	}
	return o;
}

// quote only manipulator

SQLQueryParms& operator<<(quote_only_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2 = "'" + in + "'";
		in2.processed = true;
		return *p.qparms << in2;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(quote_only_type1 o, const ColData_Tmpl<string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(quote_only_type1 o,
		const ColData_Tmpl<const_string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

// quote double only manipulator

SQLQueryParms& operator<<(quote_double_only_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2 = "\"" + in + "\"";
		in2.processed = true;
		return *p.qparms << in2;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(quote_double_only_type1 o,
		const ColData_Tmpl<string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(quote_double_only_type1 o,
		const ColData_Tmpl<const_string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

// escape manipulator

SQLQueryParms& operator<<(escape_type2 p, SQLString& in)
{
	if (in.is_string) {
		if (in.dont_escape) {
			in.processed = true;
			return *p.qparms << in;
		}
		else {
			char *s = new char[in.size() * 2 + 1];
			mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
			SQLString in2 = s;
			in2.processed = true;
			*p.qparms << in2;
			delete[] s;
			return *p.qparms;
		}
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(escape_type1 o, const string& in)
{
	char *s = new char[in.size() * 2 + 1];
	mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
	*o.ostr << s;
	delete[] s;
	return *o.ostr;
}

template<>
ostream& operator<<(escape_type1 o, const char* const& in)
{
	unsigned int size;
	for (size = 0; in[size]; size++) ;
	char *s = new char[size * 2 + 1];
	mysql_escape_string(s, const_cast < char *>(in), size);
	*o.ostr << s;
	delete[] s;
	return *o.ostr;
}

template<class Str>
inline ostream& _manip(escape_type1 o, const ColData_Tmpl<Str>& in)
{
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		delete[] s;
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(escape_type1 o, const ColData_Tmpl<string>& in)
{
	return _manip(o, in);
}

template<>
ostream& operator<<(escape_type1 o, const ColData_Tmpl<const_string>& in)
{
	return _manip(o, in);
}

} // end namespace mysqlpp

<commit_msg>Removed an unnecessary 'extern'.  (The variable we so declared is defined in this same file!)<commit_after>#include "manip.h"

using namespace std;

// Manipulator stuff is _always_ in namespace mysqlpp.
namespace mysqlpp {

bool dont_quote_auto = false;

// quote manipulator

SQLQueryParms& operator <<(quote_type2 p, SQLString& in)
{
	if (in.is_string) {
		if (in.dont_escape) {
			SQLString in2 = "'" + in + "'";
			 in2.processed = true;
			 return *p.qparms << in2;
		}
		else {
			char *s = new char[in.size() * 2 + 1];
			mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
			SQLString in2 = SQLString("'") + s + "'";
			in2.processed = true;
			*p.qparms << in2;
			delete[]s;
			return *p.qparms;
		}
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(quote_type1 o, const string& in)
{
	char *s = new char[in.size() * 2 + 1];
	mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
	*o.ostr << "'" << s << "'";
	delete[] s;
	return *o.ostr;
}

template<>
ostream& operator<<(quote_type1 o, const char* const& in)
{
	unsigned int size;
	for (size = 0; in[size]; size++) ;
	char *s = new char[size * 2 + 1];
	mysql_escape_string(s, const_cast < char *>(in), size);
	*o.ostr << "'" << s << "'";
	delete[] s;
	return *o.ostr;
}

template<class Str>
inline ostream& _manip(quote_type1 o, const ColData_Tmpl<Str>& in)
{
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		if (in.quote_q())
			*o.ostr << "'" << s << "'";
		else
			*o.ostr << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(quote_type1 o, const ColData_Tmpl<string>& in)
{
	return _manip(o, in);
}

template<>
ostream& operator<<(quote_type1 o, const ColData_Tmpl<const_string>& in)
{
	return _manip(o, in);
}

ostream& operator<<(ostream& o, const ColData_Tmpl<string>& in)
{
	if (dont_quote_auto || (o.rdbuf() == cout.rdbuf()) ||
			(o.rdbuf() == cerr.rdbuf())) {
		return o << in.get_string();
	}

	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		if (in.quote_q())
			o << "'" << s << "'";
		else
			o << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		o << "'" << in.get_string() << "'";
	}
	else {
		o << in.get_string();
	}
	return o;
}

ostream& operator<<(ostream& o, const ColData_Tmpl<const_string>& in)
{
	if (dont_quote_auto || (o.rdbuf() == cout.rdbuf()) ||
			(o.rdbuf() == cerr.rdbuf())) {
		return o << in.get_string();
	}

	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, const_cast < char *>(in.c_str()),
							in.size());
		if (in.quote_q())
			o << "'" << s << "'";
		else
			o << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		o << "'" << in.get_string() << "'";
	}
	else {
		o << in.get_string();
	}
	return o;
}

SQLQuery& operator<<(SQLQuery& o, const ColData_Tmpl<string>& in)
{
	if (dont_quote_auto) {
		o << in.get_string();
		return o;
	}
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		if (in.quote_q())
			static_cast<ostream &>(o) << "'" << s << "'";
		else
			static_cast<ostream &>(o) << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		static_cast<ostream &>(o) << "'" << in.get_string() << "'";
	}
	else {
		static_cast<ostream &>(o) << in.get_string();
	}
	return o;
}

SQLQuery& operator<<(SQLQuery& o, const ColData_Tmpl<const_string>& in)
{
	if (dont_quote_auto) {
		o << in.get_string();
		return o;
	}
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, const_cast < char *>(in.c_str()),
							in.size());
		if (in.quote_q())
			static_cast<ostream &>(o) << "'" << s << "'";
		else
			static_cast<ostream &>(o) << s;
		delete[] s;
	}
	else if (in.quote_q()) {
		static_cast<ostream &>(o) << "'" << in.get_string() << "'";
	}
	else {
		static_cast<ostream &>(o) << in.get_string();
	}
	return o;
}

// quote only manipulator

SQLQueryParms& operator<<(quote_only_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2 = "'" + in + "'";
		in2.processed = true;
		return *p.qparms << in2;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(quote_only_type1 o, const ColData_Tmpl<string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(quote_only_type1 o,
		const ColData_Tmpl<const_string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

// quote double only manipulator

SQLQueryParms& operator<<(quote_double_only_type2 p, SQLString& in)
{
	if (in.is_string) {
		SQLString in2 = "\"" + in + "\"";
		in2.processed = true;
		return *p.qparms << in2;
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(quote_double_only_type1 o,
		const ColData_Tmpl<string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(quote_double_only_type1 o,
		const ColData_Tmpl<const_string>& in)
{
	if (in.quote_q()) {
		*o.ostr << "'" << in << "'";
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

// escape manipulator

SQLQueryParms& operator<<(escape_type2 p, SQLString& in)
{
	if (in.is_string) {
		if (in.dont_escape) {
			in.processed = true;
			return *p.qparms << in;
		}
		else {
			char *s = new char[in.size() * 2 + 1];
			mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
			SQLString in2 = s;
			in2.processed = true;
			*p.qparms << in2;
			delete[] s;
			return *p.qparms;
		}
	}
	else {
		in.processed = true;
		return *p.qparms << in;
	}
}

template<>
ostream& operator<<(escape_type1 o, const string& in)
{
	char *s = new char[in.size() * 2 + 1];
	mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
	*o.ostr << s;
	delete[] s;
	return *o.ostr;
}

template<>
ostream& operator<<(escape_type1 o, const char* const& in)
{
	unsigned int size;
	for (size = 0; in[size]; size++) ;
	char *s = new char[size * 2 + 1];
	mysql_escape_string(s, const_cast < char *>(in), size);
	*o.ostr << s;
	delete[] s;
	return *o.ostr;
}

template<class Str>
inline ostream& _manip(escape_type1 o, const ColData_Tmpl<Str>& in)
{
	if (in.escape_q()) {
		char *s = new char[in.size() * 2 + 1];
		mysql_escape_string(s, in.c_str(), (unsigned long)in.size());
		delete[] s;
	}
	else {
		*o.ostr << in;
	}
	return *o.ostr;
}

template<>
ostream& operator<<(escape_type1 o, const ColData_Tmpl<string>& in)
{
	return _manip(o, in);
}

template<>
ostream& operator<<(escape_type1 o, const ColData_Tmpl<const_string>& in)
{
	return _manip(o, in);
}

} // end namespace mysqlpp

<|endoftext|>


<commit_before><commit_msg>Removed an excessively brittle test.<commit_after><|endoftext|>


<commit_before><commit_msg>Added some comments to better explain the test.<commit_after><|endoftext|>


<commit_before>/**
 * @file		instance.hpp
 * @brief		COSSB Instance
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 7. 27
 * @details	COSSB Instance
 */

#ifndef _COSSB_INSTANCE_HPP_
#define _COSSB_INSTANCE_HPP_

#include "config.hpp"

namespace cossb {
namespace core {

#ifndef _cplusplus
extern "C" {
#endif

/**
 * @brief create COSSB core instances
 */
extern bool cossb_init(base::config* config);

/**
 * @brief destroy COSSB core instances
 */
extern void cossb_destroy();

/**
 * @brief	service components synchronization
 */
extern bool cossb_sync();

#ifndef _cplusplus
}
#endif

} /* namespace core */
} /* namespace cossb */

#endif /* _COSSB_INSTANCE_HPP_ */
<commit_msg>change the argument cossb_init function<commit_after>/**
 * @file		instance.hpp
 * @brief		COSSB Instance
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 7. 27
 * @details	COSSB Instance
 */

#ifndef _COSSB_INSTANCE_HPP_
#define _COSSB_INSTANCE_HPP_

#include "config.hpp"

namespace cossb {
namespace core {

#ifndef _cplusplus
extern "C" {
#endif

/**
 * @brief create COSSB core instances
 */
extern bool cossb_init(const char* manifest);

/**
 * @brief destroy COSSB core instances
 */
extern void cossb_destroy();

/**
 * @brief	service components synchronization
 */
extern bool cossb_sync();

/**
 * @brief	start COSSB engine
 */
extern bool cossb_start();

/**
 * @brief	stop COSSB Engine
 */
extern bool cossb_stop();

#ifndef _cplusplus
}
#endif

} /* namespace core */
} /* namespace cossb */

#endif /* _COSSB_INSTANCE_HPP_ */
<|endoftext|>


<commit_before>#ifndef US_WORLD_HPP
#define US_WORLD_HPP

/*
Copyright (c) 2013, J.D. Koftinoff Software, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of J.D. Koftinoff Software, Ltd. nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL J.D. KOFTINOFF SOFTWARE, LTD.BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstdint>
#include "us_world.h"
#include <string>
#include <iostream>
#include <stdexcept>
#include <vector>

#endif

<commit_msg>use stdint.h instead of cstdint<commit_after>#ifndef US_WORLD_HPP
#define US_WORLD_HPP

/*
Copyright (c) 2013, J.D. Koftinoff Software, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of J.D. Koftinoff Software, Ltd. nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL J.D. KOFTINOFF SOFTWARE, LTD.BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdint.h>
#include "us_world.h"
#include <string>
#include <iostream>
#include <stdexcept>
#include <vector>

#endif

<|endoftext|>


<commit_before>// Copyright 2017 The NXT Authors
//
// 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 "backend/d3d12/ShaderModuleD3D12.h"

#include <spirv-cross/spirv_hlsl.hpp>

namespace backend { namespace d3d12 {

    ShaderModule::ShaderModule(Device* device, ShaderModuleBuilder* builder)
        : ShaderModuleBase(builder), mDevice(device) {
        spirv_cross::CompilerHLSL compiler(builder->AcquireSpirv());

        spirv_cross::CompilerGLSL::Options options_glsl;
        options_glsl.vertex.fixup_clipspace = true;
        compiler.spirv_cross::CompilerGLSL::set_options(options_glsl);

        spirv_cross::CompilerHLSL::Options options_hlsl;
        options_hlsl.shader_model = 51;
        compiler.spirv_cross::CompilerHLSL::set_options(options_hlsl);

        ExtractSpirvInfo(compiler);

        // rename bindings so that each register type b/u/t/s starts at 0 and then offset by
        // kMaxBindingsPerGroup * bindGroupIndex
        auto RenumberBindings = [&](std::vector<spirv_cross::Resource> resources) {
            std::array<uint32_t, kMaxBindGroups> baseRegisters = {};

            for (const auto& resource : resources) {
                auto bindGroupIndex =
                    compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
                auto& baseRegister = baseRegisters[bindGroupIndex];
                auto bindGroupOffset = bindGroupIndex * kMaxBindingsPerGroup;
                compiler.set_decoration(resource.id, spv::DecorationBinding,
                                        bindGroupOffset + baseRegister++);
            }
        };

        const auto& resources = compiler.get_shader_resources();
        RenumberBindings(resources.uniform_buffers);    // c
        RenumberBindings(resources.storage_buffers);    // u
        RenumberBindings(resources.separate_images);    // t
        RenumberBindings(resources.separate_samplers);  // s

        mHlslSource = compiler.compile();
    }

    const std::string& ShaderModule::GetHLSLSource() const {
        return mHlslSource;
    }

}}  // namespace backend::d3d12
<commit_msg>D3D12: Add back flip_vert_y.<commit_after>// Copyright 2017 The NXT Authors
//
// 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 "backend/d3d12/ShaderModuleD3D12.h"

#include <spirv-cross/spirv_hlsl.hpp>

namespace backend { namespace d3d12 {

    ShaderModule::ShaderModule(Device* device, ShaderModuleBuilder* builder)
        : ShaderModuleBase(builder), mDevice(device) {
        spirv_cross::CompilerHLSL compiler(builder->AcquireSpirv());

        spirv_cross::CompilerGLSL::Options options_glsl;
        options_glsl.vertex.fixup_clipspace = true;
        options_glsl.vertex.flip_vert_y = true;
        compiler.spirv_cross::CompilerGLSL::set_options(options_glsl);

        spirv_cross::CompilerHLSL::Options options_hlsl;
        options_hlsl.shader_model = 51;
        compiler.spirv_cross::CompilerHLSL::set_options(options_hlsl);

        ExtractSpirvInfo(compiler);

        // rename bindings so that each register type b/u/t/s starts at 0 and then offset by
        // kMaxBindingsPerGroup * bindGroupIndex
        auto RenumberBindings = [&](std::vector<spirv_cross::Resource> resources) {
            std::array<uint32_t, kMaxBindGroups> baseRegisters = {};

            for (const auto& resource : resources) {
                auto bindGroupIndex =
                    compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
                auto& baseRegister = baseRegisters[bindGroupIndex];
                auto bindGroupOffset = bindGroupIndex * kMaxBindingsPerGroup;
                compiler.set_decoration(resource.id, spv::DecorationBinding,
                                        bindGroupOffset + baseRegister++);
            }
        };

        const auto& resources = compiler.get_shader_resources();
        RenumberBindings(resources.uniform_buffers);    // c
        RenumberBindings(resources.storage_buffers);    // u
        RenumberBindings(resources.separate_images);    // t
        RenumberBindings(resources.separate_samplers);  // s

        mHlslSource = compiler.compile();
    }

    const std::string& ShaderModule::GetHLSLSource() const {
        return mHlslSource;
    }

}}  // namespace backend::d3d12
<|endoftext|>


<commit_before><commit_msg>Reorganized smoke tests, removed videoplayer from windows.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2011-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <policy/policy.h>
#include <test/util/setup_common.h>
#include <txmempool.h>

#include <vector>

static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
    int64_t nTime = 0;
    unsigned int nHeight = 1;
    bool spendsCoinbase = false;
    unsigned int sigOpCost = 4;
    LockPoints lp;
    pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, spendsCoinbase, sigOpCost, lp));
}

struct Available {
    CTransactionRef ref;
    size_t vin_left{0};
    size_t tx_count;
    Available(CTransactionRef& ref, size_t tx_count) : ref(ref), tx_count(tx_count){}
};

static void ComplexMemPool(benchmark::Bench& bench)
{
    int childTxs = 800;
    if (bench.complexityN() > 1) {
        childTxs = static_cast<int>(bench.complexityN());
    }

    FastRandomContext det_rand{true};
    std::vector<Available> available_coins;
    std::vector<CTransactionRef> ordered_coins;
    // Create some base transactions
    size_t tx_counter = 1;
    for (auto x = 0; x < 100; ++x) {
        CMutableTransaction tx = CMutableTransaction();
        tx.vin.resize(1);
        tx.vin[0].scriptSig = CScript() << CScriptNum(tx_counter);
        tx.vin[0].scriptWitness.stack.push_back(CScriptNum(x).getvch());
        tx.vout.resize(det_rand.randrange(10)+2);
        for (auto& out : tx.vout) {
            out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
            out.nValue = 10 * COIN;
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    for (auto x = 0; x < childTxs && !available_coins.empty(); ++x) {
        CMutableTransaction tx = CMutableTransaction();
        size_t n_ancestors = det_rand.randrange(10)+1;
        for (size_t ancestor = 0; ancestor < n_ancestors && !available_coins.empty(); ++ancestor){
            size_t idx = det_rand.randrange(available_coins.size());
            Available coin = available_coins[idx];
            uint256 hash = coin.ref->GetHash();
            // biased towards taking just one ancestor, but maybe more
            size_t n_to_take = det_rand.randrange(2) == 0 ? 1 : 1+det_rand.randrange(coin.ref->vout.size() - coin.vin_left);
            for (size_t i = 0; i < n_to_take; ++i) {
                tx.vin.emplace_back();
                tx.vin.back().prevout = COutPoint(hash, coin.vin_left++);
                tx.vin.back().scriptSig = CScript() << coin.tx_count;
                tx.vin.back().scriptWitness.stack.push_back(CScriptNum(coin.tx_count).getvch());
            }
            if (coin.vin_left == coin.ref->vin.size()) {
                coin = available_coins.back();
                available_coins.pop_back();
            }
            tx.vout.resize(det_rand.randrange(10)+2);
            for (auto& out : tx.vout) {
                out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
                out.nValue = 10 * COIN;
            }
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN);
    CTxMemPool pool;
    LOCK2(cs_main, pool.cs);
    bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
        for (auto& tx : ordered_coins) {
            AddTx(tx, pool);
        }
        pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
        pool.TrimToSize(GetVirtualTransactionSize(*ordered_coins.front()));
    });
}

BENCHMARK(ComplexMemPool);
<commit_msg>[refactor/bench] make mempool_stress bench reusable and parameterizable<commit_after>// Copyright (c) 2011-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <policy/policy.h>
#include <test/util/setup_common.h>
#include <txmempool.h>

#include <vector>

static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
    int64_t nTime = 0;
    unsigned int nHeight = 1;
    bool spendsCoinbase = false;
    unsigned int sigOpCost = 4;
    LockPoints lp;
    pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, spendsCoinbase, sigOpCost, lp));
}

struct Available {
    CTransactionRef ref;
    size_t vin_left{0};
    size_t tx_count;
    Available(CTransactionRef& ref, size_t tx_count) : ref(ref), tx_count(tx_count){}
};

static std::vector<CTransactionRef> CreateOrderedCoins(FastRandomContext& det_rand, int childTxs, int min_ancestors)
{
    std::vector<Available> available_coins;
    std::vector<CTransactionRef> ordered_coins;
    // Create some base transactions
    size_t tx_counter = 1;
    for (auto x = 0; x < 100; ++x) {
        CMutableTransaction tx = CMutableTransaction();
        tx.vin.resize(1);
        tx.vin[0].scriptSig = CScript() << CScriptNum(tx_counter);
        tx.vin[0].scriptWitness.stack.push_back(CScriptNum(x).getvch());
        tx.vout.resize(det_rand.randrange(10)+2);
        for (auto& out : tx.vout) {
            out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
            out.nValue = 10 * COIN;
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    for (auto x = 0; x < childTxs && !available_coins.empty(); ++x) {
        CMutableTransaction tx = CMutableTransaction();
        size_t n_ancestors = det_rand.randrange(10)+1;
        for (size_t ancestor = 0; ancestor < n_ancestors && !available_coins.empty(); ++ancestor){
            size_t idx = det_rand.randrange(available_coins.size());
            Available coin = available_coins[idx];
            uint256 hash = coin.ref->GetHash();
            // biased towards taking min_ancestors parents, but maybe more
            size_t n_to_take = det_rand.randrange(2) == 0 ?
                               min_ancestors :
                               min_ancestors + det_rand.randrange(coin.ref->vout.size() - coin.vin_left);
            for (size_t i = 0; i < n_to_take; ++i) {
                tx.vin.emplace_back();
                tx.vin.back().prevout = COutPoint(hash, coin.vin_left++);
                tx.vin.back().scriptSig = CScript() << coin.tx_count;
                tx.vin.back().scriptWitness.stack.push_back(CScriptNum(coin.tx_count).getvch());
            }
            if (coin.vin_left == coin.ref->vin.size()) {
                coin = available_coins.back();
                available_coins.pop_back();
            }
            tx.vout.resize(det_rand.randrange(10)+2);
            for (auto& out : tx.vout) {
                out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
                out.nValue = 10 * COIN;
            }
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    return ordered_coins;
}

static void ComplexMemPool(benchmark::Bench& bench)
{
    FastRandomContext det_rand{true};
    int childTxs = 800;
    if (bench.complexityN() > 1) {
        childTxs = static_cast<int>(bench.complexityN());
    }
    std::vector<CTransactionRef> ordered_coins = CreateOrderedCoins(det_rand, childTxs, /* min_ancestors */ 1);
    const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN);
    CTxMemPool pool;
    LOCK2(cs_main, pool.cs);
    bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
        for (auto& tx : ordered_coins) {
            AddTx(tx, pool);
        }
        pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
        pool.TrimToSize(GetVirtualTransactionSize(*ordered_coins.front()));
    });
}

BENCHMARK(ComplexMemPool);
<|endoftext|>


<commit_before>#pragma once

#include "blackhole/attribute.hpp"
#include "blackhole/repository/factory/traits.hpp"
#include "blackhole/sink/files/backend.hpp"
#include "blackhole/sink/files/config.hpp"
#include "blackhole/sink/files/flusher.hpp"
#include "blackhole/sink/files/rotation.hpp"
#include "blackhole/sink/files/writer.hpp"
#include "blackhole/utils/unique.hpp"

namespace blackhole {

namespace sink {

template<class Backend, class Rotator, class = void>
class file_hander_t;

template<class Backend>
class file_hander_t<Backend, NoRotation, void> {
    Backend m_backend;
    files::writer_t<Backend> writer;
    files::flusher_t<Backend> flusher;
public:
    file_hander_t(const std::string& path, const files::config_t<NoRotation>& config) :
        m_backend(path),
        writer(m_backend),
        flusher(config.autoflush, m_backend)
    {}

    void handle(const std::string& message) {
        writer.write(message);
        flusher.flush();
    }

    const Backend& backend() {
        return m_backend;
    }
};

template<class Backend, class Rotator>
class file_hander_t<
    Backend,
    Rotator,
    typename std::enable_if<
        !std::is_same<Rotator, NoRotation>::value
    >::type>
{
    Backend m_backend;
    files::writer_t<Backend> writer;
    files::flusher_t<Backend> flusher;
    Rotator rotator;
public:
    file_hander_t(const std::string& path, const files::config_t<Rotator>& config) :
        m_backend(path),
        writer(m_backend),
        flusher(config.autoflush, m_backend),
        rotator(config.rotation, m_backend)
    {}

    void handle(const std::string& message) {
        writer.write(message);
        flusher.flush();
        if (BOOST_UNLIKELY(rotator.necessary(message))) {
            rotator.rotate();
        }
    }

    const Backend& backend() {
        return m_backend;
    }
};

template<class Backend = files::boost_backend_t, class Rotator = NoRotation>
class files_t {
    typedef file_hander_t<Backend, Rotator> file_handler_type;
    typedef std::map<std::string, std::shared_ptr<file_handler_type>> file_handlers_type;

    files::config_t<Rotator> config;
    file_handlers_type m_handlers;
public:
    typedef files::config_t<Rotator> config_type;

    static const char* name() {
        return "files";
    }

    files_t(const config_type& config) :
        config(config)
    {}

    //!@todo: second arg is temporary
    void consume(const std::string& message, const log::attributes_t& attributes = log::attributes_t()) {
        auto filename = make_filename(attributes);
        auto it = m_handlers.find(filename);
        if (it == m_handlers.end()) {
            it = m_handlers.insert(it, std::make_pair(filename, std::make_shared<file_handler_type>(filename, config)));
        }
        it->second->handle(message);
    }

    const file_handlers_type& handlers() {
        return m_handlers;
    }

    std::string make_filename(const log::attributes_t& attributes) const {
        auto it = config.path.begin();
        auto end = config.path.end();
        std::string filename;
        while (it != end) {
            if (*it == '%' && it + 1 != end && *(it + 1) == '(') {
                it += 2;

                std::string key;
                bool found = false;
                while (it != end) {
                    if (*it == ')' && it + 1 != end && *(it + 1) == 's') {
                        found = true;
                        it += 2;
                        break;
                    }
                    key.push_back(*it);
                    it++;
                }

                if (found) {
                    auto ait = attributes.find(key);
                    if (ait != attributes.end()) {
                        std::ostringstream stream;
                        stream << ait->second.value;
                        filename.append(stream.str());
                    } else {
                        filename.append(key);
                    }
                } else {
                    filename.append(key);
                }
            }

            if (it == end) {
                break;
            }
            filename.push_back(*it);
            it++;
        }
//        std::cout << "filename=" << filename << std::endl;
        return filename;
    }
};

} // namespace sink

template<class Backend, class Watcher>
struct unique_id_traits<sink::files_t<Backend, sink::rotator_t<Backend, Watcher>>> {
    typedef sink::rotator_t<Backend, Watcher> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;

    typedef std::map<std::string, boost::any> variant_map_t;

    static std::string generate(const boost::any& config) {
        const variant_map_t& cfg = boost::any_cast<variant_map_t>(config);

        auto rotation_it = cfg.find("rotation");
        if (rotation_it != cfg.end()) {
            const variant_map_t& rotation = boost::any_cast<variant_map_t>(rotation_it->second);

            const bool has_size_watcher = rotation.find("size") != rotation.end();
            const bool has_datetime_watcher = rotation.find("period") != rotation.end();

            if (has_size_watcher && has_datetime_watcher) {
                throw blackhole::error_t("set watcher is not implemented yet");
            } else if (has_size_watcher) {
                return utils::format("%s/%s/%s", sink_type::name(), rotator_type::name(), "size");
            } else if (has_datetime_watcher) {
                return utils::format("%s/%s/%s", sink_type::name(), rotator_type::name(), "datetime");
            }

            throw blackhole::error_t("rotation section not properly configures: no watcher settings found");
        }

        return sink_type::name();
    }
};

template<class Backend>
struct config_traits<sink::files_t<Backend, sink::NoRotation>> {
    static std::string name() {
        return sink::files_t<Backend, sink::NoRotation>::name();
    }
};

template<class Backend, class Watcher>
struct config_traits<sink::files_t<Backend, sink::rotator_t<Backend, Watcher>>> {
    typedef sink::rotator_t<Backend, Watcher> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;

    static std::string name() {
        return utils::format("%s/%s/%s", sink_type::name(), rotator_type::name(), Watcher::name());
    }
};

namespace aux {

template<class Backend, class Rotator>
struct filler<sink::files_t<Backend, Rotator>> {
    template<class Extractor, class Config>
    static void extract_to(const Extractor& ex, Config& config) {
        ex["path"].to(config.path);
        ex["autoflush"].to(config.autoflush);
    }
};

template<class Backend, class Watcher>
struct filler<sink::rotator_t<Backend, Watcher>> {
    template<class Extractor, class Config>
    static void extract_to(const Extractor& ex, Config& config) {
        ex["rotation"]["pattern"].to(config.rotation.pattern);
        ex["rotation"]["backups"].to(config.rotation.backups);
    }
};

} // namespace aux

template<class Backend>
struct factory_traits<sink::files_t<Backend>> {
    typedef sink::files_t<Backend> sink_type;
    typedef typename sink_type::config_type config_type;

    static void map_config(const aux::extractor<sink_type>& ex, config_type& config) {
        aux::filler<sink_type>::extract_to(ex, config);
    }
};

template<class Backend>
struct factory_traits<sink::files_t<Backend, sink::rotator_t<Backend, sink::rotation::watcher::size_t>>> {
    typedef sink::rotation::watcher::size_t watcher_type;
    typedef sink::rotator_t<Backend, watcher_type> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;
    typedef typename sink_type::config_type config_type;

    static void map_config(const aux::extractor<sink_type>& ex, config_type& config) {
        aux::filler<sink_type>::extract_to(ex, config);
        aux::filler<rotator_type>::extract_to(ex, config);
        ex["rotation"]["size"].to(config.rotation.watcher.size);
    }
};

template<class Backend>
struct factory_traits<sink::files_t<Backend, sink::rotator_t<Backend, sink::rotation::watcher::datetime_t<>>>> {
    typedef sink::rotation::watcher::datetime_t<> watcher_type;
    typedef sink::rotator_t<Backend, watcher_type> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;
    typedef typename sink_type::config_type config_type;

    static void map_config(const aux::extractor<sink_type>& ex, config_type& config) {
        aux::filler<sink_type>::extract_to(ex, config);
        aux::filler<rotator_type>::extract_to(ex, config);
        ex["rotation"]["period"].to(config.rotation.watcher.period);
    }
};

} // namespace blackhole
<commit_msg>[Aux] Using hash table instead of RBT. [Code style] Renaming done.<commit_after>#pragma once

#include "blackhole/attribute.hpp"
#include "blackhole/repository/factory/traits.hpp"
#include "blackhole/sink/files/backend.hpp"
#include "blackhole/sink/files/config.hpp"
#include "blackhole/sink/files/flusher.hpp"
#include "blackhole/sink/files/rotation.hpp"
#include "blackhole/sink/files/writer.hpp"
#include "blackhole/utils/unique.hpp"

namespace blackhole {

namespace sink {

template<class Backend, class Rotator, class = void>
class file_hander_t;

template<class Backend>
class file_hander_t<Backend, NoRotation, void> {
    Backend m_backend;
    files::writer_t<Backend> writer;
    files::flusher_t<Backend> flusher;
public:
    file_hander_t(const std::string& path, const files::config_t<NoRotation>& config) :
        m_backend(path),
        writer(m_backend),
        flusher(config.autoflush, m_backend)
    {}

    void handle(const std::string& message) {
        writer.write(message);
        flusher.flush();
    }

    const Backend& backend() {
        return m_backend;
    }
};

template<class Backend, class Rotator>
class file_hander_t<
    Backend,
    Rotator,
    typename std::enable_if<
        !std::is_same<Rotator, NoRotation>::value
    >::type>
{
    Backend m_backend;
    files::writer_t<Backend> writer;
    files::flusher_t<Backend> flusher;
    Rotator rotator;
public:
    file_hander_t(const std::string& path, const files::config_t<Rotator>& config) :
        m_backend(path),
        writer(m_backend),
        flusher(config.autoflush, m_backend),
        rotator(config.rotation, m_backend)
    {}

    void handle(const std::string& message) {
        writer.write(message);
        flusher.flush();
        if (BOOST_UNLIKELY(rotator.necessary(message))) {
            rotator.rotate();
        }
    }

    const Backend& backend() {
        return m_backend;
    }
};

template<class Backend = files::boost_backend_t, class Rotator = NoRotation>
class files_t {
    typedef file_hander_t<Backend, Rotator> handler_type;
    typedef std::unordered_map<std::string, std::shared_ptr<handler_type>> handlers_type;

    files::config_t<Rotator> config;
    handlers_type m_handlers;
public:
    typedef files::config_t<Rotator> config_type;

    static const char* name() {
        return "files";
    }

    files_t(const config_type& config) :
        config(config)
    {}

    void consume(const std::string& message, const log::attributes_t& attributes = log::attributes_t()) {
        auto filename = make_filename(attributes);
        auto it = m_handlers.find(filename);
        if (it == m_handlers.end()) {
            it = m_handlers.insert(it, std::make_pair(filename, std::make_shared<handler_type>(filename, config)));
        }
        it->second->handle(message);
    }

    const handlers_type& handlers() {
        return m_handlers;
    }

    std::string make_filename(const log::attributes_t& attributes) const {
        auto it = config.path.begin();
        auto end = config.path.end();
        std::string filename;
        while (it != end) {
            if (*it == '%' && it + 1 != end && *(it + 1) == '(') {
                it += 2;

                std::string key;
                bool found = false;
                while (it != end) {
                    if (*it == ')' && it + 1 != end && *(it + 1) == 's') {
                        found = true;
                        it += 2;
                        break;
                    }
                    key.push_back(*it);
                    it++;
                }

                if (found) {
                    auto ait = attributes.find(key);
                    if (ait != attributes.end()) {
                        std::ostringstream stream;
                        stream << ait->second.value;
                        filename.append(stream.str());
                    } else {
                        filename.append(key);
                    }
                } else {
                    filename.append(key);
                }
            }

            if (it == end) {
                break;
            }
            filename.push_back(*it);
            it++;
        }
//        std::cout << "filename=" << filename << std::endl;
        return filename;
    }
};

} // namespace sink

template<class Backend, class Watcher>
struct unique_id_traits<sink::files_t<Backend, sink::rotator_t<Backend, Watcher>>> {
    typedef sink::rotator_t<Backend, Watcher> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;

    typedef std::map<std::string, boost::any> variant_map_t;

    static std::string generate(const boost::any& config) {
        const variant_map_t& cfg = boost::any_cast<variant_map_t>(config);

        auto rotation_it = cfg.find("rotation");
        if (rotation_it != cfg.end()) {
            const variant_map_t& rotation = boost::any_cast<variant_map_t>(rotation_it->second);

            const bool has_size_watcher = rotation.find("size") != rotation.end();
            const bool has_datetime_watcher = rotation.find("period") != rotation.end();

            if (has_size_watcher && has_datetime_watcher) {
                throw blackhole::error_t("set watcher is not implemented yet");
            } else if (has_size_watcher) {
                return utils::format("%s/%s/%s", sink_type::name(), rotator_type::name(), "size");
            } else if (has_datetime_watcher) {
                return utils::format("%s/%s/%s", sink_type::name(), rotator_type::name(), "datetime");
            }

            throw blackhole::error_t("rotation section not properly configures: no watcher settings found");
        }

        return sink_type::name();
    }
};

template<class Backend>
struct config_traits<sink::files_t<Backend, sink::NoRotation>> {
    static std::string name() {
        return sink::files_t<Backend, sink::NoRotation>::name();
    }
};

template<class Backend, class Watcher>
struct config_traits<sink::files_t<Backend, sink::rotator_t<Backend, Watcher>>> {
    typedef sink::rotator_t<Backend, Watcher> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;

    static std::string name() {
        return utils::format("%s/%s/%s", sink_type::name(), rotator_type::name(), Watcher::name());
    }
};

namespace aux {

template<class Backend, class Rotator>
struct filler<sink::files_t<Backend, Rotator>> {
    template<class Extractor, class Config>
    static void extract_to(const Extractor& ex, Config& config) {
        ex["path"].to(config.path);
        ex["autoflush"].to(config.autoflush);
    }
};

template<class Backend, class Watcher>
struct filler<sink::rotator_t<Backend, Watcher>> {
    template<class Extractor, class Config>
    static void extract_to(const Extractor& ex, Config& config) {
        ex["rotation"]["pattern"].to(config.rotation.pattern);
        ex["rotation"]["backups"].to(config.rotation.backups);
    }
};

} // namespace aux

template<class Backend>
struct factory_traits<sink::files_t<Backend>> {
    typedef sink::files_t<Backend> sink_type;
    typedef typename sink_type::config_type config_type;

    static void map_config(const aux::extractor<sink_type>& ex, config_type& config) {
        aux::filler<sink_type>::extract_to(ex, config);
    }
};

template<class Backend>
struct factory_traits<sink::files_t<Backend, sink::rotator_t<Backend, sink::rotation::watcher::size_t>>> {
    typedef sink::rotation::watcher::size_t watcher_type;
    typedef sink::rotator_t<Backend, watcher_type> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;
    typedef typename sink_type::config_type config_type;

    static void map_config(const aux::extractor<sink_type>& ex, config_type& config) {
        aux::filler<sink_type>::extract_to(ex, config);
        aux::filler<rotator_type>::extract_to(ex, config);
        ex["rotation"]["size"].to(config.rotation.watcher.size);
    }
};

template<class Backend>
struct factory_traits<sink::files_t<Backend, sink::rotator_t<Backend, sink::rotation::watcher::datetime_t<>>>> {
    typedef sink::rotation::watcher::datetime_t<> watcher_type;
    typedef sink::rotator_t<Backend, watcher_type> rotator_type;
    typedef sink::files_t<Backend, rotator_type> sink_type;
    typedef typename sink_type::config_type config_type;

    static void map_config(const aux::extractor<sink_type>& ex, config_type& config) {
        aux::filler<sink_type>::extract_to(ex, config);
        aux::filler<rotator_type>::extract_to(ex, config);
        ex["rotation"]["period"].to(config.rotation.watcher.period);
    }
};

} // namespace blackhole
<|endoftext|>