<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DBN_RBM_HPP
#define DBN_RBM_HPP

#include <cmath>
#include <vector>
#include <random>
#include <functional>
#include <fstream>

//TODO Find a better way to use mkdir
#include <sys/stat.h>

#include "assert.hpp"
#include "stop_watch.hpp"
#include "fast_matrix.hpp"
#include "fast_vector.hpp"

namespace dbn {

template<std::size_t visibles, std::size_t hiddens>
struct layer {
    static constexpr const std::size_t num_visible = visibles;
    static constexpr const std::size_t num_hidden = hiddens;
};

/*!
 * \brief Restricted Boltzmann Machine
 */
template<typename Layer, bool Momentum = true, int BatchSize = 1, bool Debug = false>
class rbm {
public:
    static_assert(BatchSize > 0, "Batch size must be at least 1");

    typedef double weight;
    typedef double value_t;

    static constexpr const std::size_t num_visible = Layer::num_visible;
    static constexpr const std::size_t num_hidden = Layer::num_hidden;

private:
    fast_vector<value_t, num_visible> visibles;
    fast_vector<value_t, num_hidden> hiddens;

    fast_matrix<weight, num_visible, num_hidden> w;
    fast_vector<weight, num_visible> a;
    fast_vector<weight, num_hidden> b;

    //Weights for momentum
    fast_matrix<weight, Momentum ? num_visible: 0, Momentum ? num_hidden : 0> w_inc;
    fast_vector<weight, Momentum ? num_visible : 0> a_inc;
    fast_vector<weight, Momentum ? num_hidden : 0> b_inc;

    //Temporary data
    fast_vector<weight, num_visible> v1;
    fast_vector<weight, num_hidden> h1;
    fast_vector<weight, num_visible> v2;
    fast_vector<weight, num_hidden> h2;
    fast_vector<weight, num_hidden> hs;

    //Deltas
    fast_matrix<weight, num_visible, num_hidden> gw;
    fast_vector<weight, num_visible> ga;
    fast_vector<weight, num_hidden> gb;

    //TODO Add a way to configure that
    double learning_rate = 0.1;
    double momentum = 0.5;

    void init_weights(){
        //Initialize the weights using a Gaussian distribution of mean 0 and
        //variance 0.0.1
        std::mt19937_64 rand_engine(::time(nullptr));
        std::normal_distribution<double> distribution(0.0, 1.0);
        auto generator = std::bind(distribution, rand_engine);

        for(size_t v = 0; v < num_visible; ++v){
            for(size_t h = 0; h < num_hidden; ++h){
                w(v, h) = generator() * 0.1;
            }
        }
    }

    static constexpr double logistic_sigmoid(double x){
        return 1.0 / (1.0 + exp(-x));
    }

    template<typename V1, typename V2>
    static const V2& bernoulli(const V1& input, V2& output){
        dbn_assert(input.size() == output.size(), "vector must the same sizes");

        static std::mt19937_64 rand_engine(::time(nullptr));
        static std::uniform_real_distribution<double> distribution(0.0, 1.0);
        static auto generator = bind(distribution, rand_engine);

        for(size_t i = 0; i < input.size(); ++i){
            output(i) = generator() < input(i) ? 1.0 : 0.0;
        }

        return output;
    }

public:
    template<bool M = Momentum, typename std::enable_if<(!M), bool>::type = false>
    rbm() : a(0.0), b(0.0){
        static_assert(!Momentum, "This constructor should only be used without momentum support");

        init_weights();
    }

    template<bool M = Momentum, typename std::enable_if<(M), bool>::type = false>
    rbm() : a(0.0), b(0.0), w_inc(0.0){

        static_assert(Momentum, "This constructor should only be used with momentum support");

        init_weights();
    }

    template<typename TrainingItem>
    void train(const std::vector<std::vector<TrainingItem>>& training_data, std::size_t max_epochs){
        stop_watch<std::chrono::seconds> watch;

        //Initialize the visible biases to log(pi/(1-pi))
        for(size_t i = 0; i < num_visible; ++i){
            size_t c = 0;
            for(auto& items : training_data){
                if(items[i] == 1){
                    ++c;
                }
            }

            auto pi = static_cast<double>(c) / training_data.size();
            pi += 0.0001;
            a(i) = log(pi / (1.0 - pi));
        }

        auto batches = training_data.size() / BatchSize;

        for(size_t epoch= 0; epoch < max_epochs; ++epoch){
            double error = 0.0;
            for(size_t i = 0; i < batches; ++i){
                error += cd_step(training_data.begin() + i * BatchSize, training_data.begin() + (i+1) * BatchSize);
            }

            std::cout << "epoch " << epoch << ": Reconstruction error average: " << (error / batches) << std::endl;

            if(Momentum && epoch == 20){
                momentum = 0.9;
            }

            if(Debug){
                generate_hidden_images(epoch);
                generate_histograms(epoch);
            }
        }

        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }

    template<typename V1, typename V2>
    void activate_hidden(V1& h, const V2& v) const {
        h = 0.0;

        for(size_t j = 0; j < num_hidden; ++j){
            double s = 0.0;
            for(size_t i = 0; i < num_visible; ++i){
                s += w(i, j) * v(i);
//sdf
            }

            auto activation = b(j) + s;
            h(j) = logistic_sigmoid(activation);
        }
    }

    template<typename V1, typename V2>
    void activate_visible(const V1& h, V2& v) const {
        v = 0.0;

        for(size_t i = 0; i < num_visible; ++i){
            double s = 0.0;
            for(size_t j = 0; j < num_hidden; ++j){
                s += w(i, j) * h(j);
            }

            auto activation = a(i) + s;
            v(i) = logistic_sigmoid(activation);
        }
    }

    template<typename Iterator>
    double cd_step(Iterator it, Iterator end){
        dbn_assert(std::distance(it, end) == BatchSize, "Invalid size");
        dbn_assert(it->size() == num_visible, "The size of the training sample must match visible units");

        v1 = 0.0;
        h1 = 0.0;
        v2 = 0.0;
        h2 = 0.0;
        hs = 0.0;

        ga = 0.0;
        gb = 0.0;
        gw = 0.0;

        while(it != end){
            auto& items = *it++;

            for(size_t i = 0; i < num_visible; ++i){
                v1(i) = items[i];
            }

            activate_hidden(h1, v1);
            activate_visible(bernoulli(h1, hs), v2);
            activate_hidden(h2, v2);

            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    gw(i, j) += h1(j) * v1(i) - h2(j) * v2(i);
                }
            }

            ga += v1 - v2;
            gb += h1 - h2;
        }

        auto n_samples = static_cast<weight>(BatchSize);

        //gw / BatchSize
        for(size_t i = 0; i < num_visible; ++i){
            for(size_t j = 0; j < num_hidden; ++j){
                gw(i, j) /= n_samples;
            }
        }

        if(Momentum){
            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w_inc(i, j) = w_inc(i, j) * momentum + gw(i,j) * learning_rate;
                }
            }

            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w(i,j) += w_inc(i, j);
                }
            }
        } else {
            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w(i,j) += gw(i, j) * learning_rate;
                }
            }
        }

        if(Momentum){
            a_inc = a_inc * momentum + (ga / n_samples) * learning_rate;
            a += a_inc;
        } else {
            a += (ga / n_samples) * learning_rate;
        }

        if(Momentum){
            b_inc = b_inc * momentum + (gb / n_samples) * learning_rate;
            b += b_inc;
        } else {
            b += (gb / n_samples) * learning_rate;
        }

        //Compute the reconstruction error

        double error = 0.0;
        for(size_t i = 0; i < num_visible; ++i){
            error += (ga(i)/ n_samples) * (ga(i) / n_samples);
        }
        error = sqrt(error / num_visible);

        return error;
    }

    template<typename TrainingItem>
    void reconstruct(const std::vector<TrainingItem>& items){
        dbn_assert(items.size() == num_visible, "The size of the training sample must match visible units");

        stop_watch<> watch;

        //Set the state of the visible units
        for(size_t i = 0; i < num_visible; ++i){
            visibles(i) = items[i];
        }

        activate_hidden(h1, visibles);
        activate_visible(bernoulli(h1, hs), v1);
        bernoulli(v1, visibles);

        std::cout << "Reconstruction took " << watch.elapsed() << "ms" << std::endl;
    }

    void generate_hidden_images(size_t epoch){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        for(size_t j = 0; j < num_hidden; ++j){
            auto path = folder + "/h_" + std::to_string(j) + ".dat";
            std::ofstream file(path, std::ios::out);

            if(!file){
                std::cout << "Could not open file " << path << std::endl;
            } else {
                size_t i = num_visible;
                while(i > 0){
                    --i;

                    auto value = w(i,j);
                    file << static_cast<size_t>(value > 0 ? static_cast<size_t>(value * 255.0) << 8 : static_cast<size_t>(-value * 255.0) << 16) << " ";
                }

                file << std::endl;
                file.close();
            }
        }
    }

    void generate_histograms(size_t epoch){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        //generate_histogram(folder + "/weights.dat", w.data(), num_visible * num_hidden);
//        generate_histogram(folder + "/visibles.dat", a.data(), num_visible);
//        generate_histogram(folder + "/hiddens.dat", b.data(), num_hidden);

        if(Momentum){
            //generate_histogram(folder + "/weights_inc.dat", w_inc.data(), num_visible * num_hidden);
//            generate_histogram(folder + "/visibles_inc.dat", a_inc.data(), num_visible);
//            generate_histogram(folder + "/hiddens_inc.dat", b_inc.data(), num_hidden);
        }
    }

    void generate_histogram(const std::string& path, const double* weights, size_t size){
        std::ofstream file(path, std::ios::out);

        if(!file){
            std::cout << "Could not open file " << path << std::endl;
        } else {
            for(size_t i = 0; i < size; ++i){
                file << weights[i] << std::endl;
            }

            file << std::endl;
            file.close();
        }
    }

    void display() const {
        display_visible_units();
        display_hidden_units();
    }

    void display_visible_units() const {
        std::cout << "Visible  Value" << std::endl;

        for(size_t i = 0; i < num_visible; ++i){
            printf("%-8lu %d\n", i, visibles(i));
        }
    }

    void display_visible_units(size_t matrix) const {
        for(size_t i = 0; i < matrix; ++i){
            for(size_t j = 0; j < matrix; ++j){
                std::cout << visibles(i * matrix + j) << " ";
            }
            std::cout << std::endl;
        }
    }

    void display_hidden_units() const {
        std::cout << "Hidden Value" << std::endl;

        for(size_t j = 0; j < num_hidden; ++j){
            printf("%-8lu %d\n", j, hiddens(j));
        }
    }

    void display_weights(){
        for(size_t j = 0; j < num_hidden; ++j){
            for(size_t i = 0; i < num_visible; ++i){
                std::cout << w(i, j) << " ";
            }
            std::cout << std::endl;
        }
    }

    void display_weights(size_t matrix){
        for(size_t j = 0; j < num_hidden; ++j){
            for(size_t i = 0; i < num_visible;){
                for(size_t m = 0; m < matrix; ++m){
                    std::cout << w(i++, j) << " ";
                }
                std::cout << std::endl;
            }
        }
    }
};

} //end of dbn namespace

#endif<commit_msg>Rollback<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef DBN_RBM_HPP
#define DBN_RBM_HPP

#include <cmath>
#include <vector>
#include <random>
#include <functional>
#include <fstream>

//TODO Find a better way to use mkdir
#include <sys/stat.h>

#include "assert.hpp"
#include "stop_watch.hpp"
#include "fast_matrix.hpp"
#include "fast_vector.hpp"

namespace dbn {

template<std::size_t visibles, std::size_t hiddens>
struct layer {
    static constexpr const std::size_t num_visible = visibles;
    static constexpr const std::size_t num_hidden = hiddens;
};

/*!
 * \brief Restricted Boltzmann Machine
 */
template<typename Layer, bool Momentum = true, int BatchSize = 1, bool Debug = false>
class rbm {
public:
    static_assert(BatchSize > 0, "Batch size must be at least 1");

    typedef double weight;
    typedef double value_t;

    static constexpr const std::size_t num_visible = Layer::num_visible;
    static constexpr const std::size_t num_hidden = Layer::num_hidden;

private:
    fast_vector<value_t, num_visible> visibles;
    fast_vector<value_t, num_hidden> hiddens;

    fast_matrix<weight, num_visible, num_hidden> w;
    fast_vector<weight, num_visible> a;
    fast_vector<weight, num_hidden> b;

    //Weights for momentum
    fast_matrix<weight, Momentum ? num_visible: 0, Momentum ? num_hidden : 0> w_inc;
    fast_vector<weight, Momentum ? num_visible : 0> a_inc;
    fast_vector<weight, Momentum ? num_hidden : 0> b_inc;

    //Temporary data
    fast_vector<weight, num_visible> v1;
    fast_vector<weight, num_hidden> h1;
    fast_vector<weight, num_visible> v2;
    fast_vector<weight, num_hidden> h2;
    fast_vector<weight, num_hidden> hs;

    //Deltas
    fast_matrix<weight, num_visible, num_hidden> gw;
    fast_vector<weight, num_visible> ga;
    fast_vector<weight, num_hidden> gb;

    //TODO Add a way to configure that
    double learning_rate = 0.1;
    double momentum = 0.5;

    void init_weights(){
        //Initialize the weights using a Gaussian distribution of mean 0 and
        //variance 0.0.1
        std::mt19937_64 rand_engine(::time(nullptr));
        std::normal_distribution<double> distribution(0.0, 1.0);
        auto generator = std::bind(distribution, rand_engine);

        for(size_t v = 0; v < num_visible; ++v){
            for(size_t h = 0; h < num_hidden; ++h){
                w(v, h) = generator() * 0.1;
            }
        }
    }

    static constexpr double logistic_sigmoid(double x){
        return 1.0 / (1.0 + exp(-x));
    }

    template<typename V1, typename V2>
    static const V2& bernoulli(const V1& input, V2& output){
        dbn_assert(input.size() == output.size(), "vector must the same sizes");

        static std::mt19937_64 rand_engine(::time(nullptr));
        static std::uniform_real_distribution<double> distribution(0.0, 1.0);
        static auto generator = bind(distribution, rand_engine);

        for(size_t i = 0; i < input.size(); ++i){
            output(i) = generator() < input(i) ? 1.0 : 0.0;
        }

        return output;
    }

public:
    template<bool M = Momentum, typename std::enable_if<(!M), bool>::type = false>
    rbm() : a(0.0), b(0.0){
        static_assert(!Momentum, "This constructor should only be used without momentum support");

        init_weights();
    }

    template<bool M = Momentum, typename std::enable_if<(M), bool>::type = false>
    rbm() : a(0.0), b(0.0), w_inc(0.0){

        static_assert(Momentum, "This constructor should only be used with momentum support");

        init_weights();
    }

    template<typename TrainingItem>
    void train(const std::vector<std::vector<TrainingItem>>& training_data, std::size_t max_epochs){
        stop_watch<std::chrono::seconds> watch;

        //Initialize the visible biases to log(pi/(1-pi))
        for(size_t i = 0; i < num_visible; ++i){
            size_t c = 0;
            for(auto& items : training_data){
                if(items[i] == 1){
                    ++c;
                }
            }

            auto pi = static_cast<double>(c) / training_data.size();
            pi += 0.0001;
            a(i) = log(pi / (1.0 - pi));
        }

        auto batches = training_data.size() / BatchSize;

        for(size_t epoch= 0; epoch < max_epochs; ++epoch){
            double error = 0.0;
            for(size_t i = 0; i < batches; ++i){
                error += cd_step(training_data.begin() + i * BatchSize, training_data.begin() + (i+1) * BatchSize);
            }

            std::cout << "epoch " << epoch << ": Reconstruction error average: " << (error / batches) << std::endl;

            if(Momentum && epoch == 20){
                momentum = 0.9;
            }

            if(Debug){
                generate_hidden_images(epoch);
                generate_histograms(epoch);
            }
        }

        std::cout << "Training took " << watch.elapsed() << "s" << std::endl;
    }

    template<typename V1, typename V2>
    void activate_hidden(V1& h, const V2& v) const {
        h = 0.0;

        for(size_t j = 0; j < num_hidden; ++j){
            double s = 0.0;
            for(size_t i = 0; i < num_visible; ++i){
                s += w(i, j) * v(i);
            }

            auto activation = b(j) + s;
            h(j) = logistic_sigmoid(activation);
        }
    }

    template<typename V1, typename V2>
    void activate_visible(const V1& h, V2& v) const {
        v = 0.0;

        for(size_t i = 0; i < num_visible; ++i){
            double s = 0.0;
            for(size_t j = 0; j < num_hidden; ++j){
                s += w(i, j) * h(j);
            }

            auto activation = a(i) + s;
            v(i) = logistic_sigmoid(activation);
        }
    }

    template<typename Iterator>
    double cd_step(Iterator it, Iterator end){
        dbn_assert(std::distance(it, end) == BatchSize, "Invalid size");
        dbn_assert(it->size() == num_visible, "The size of the training sample must match visible units");

        v1 = 0.0;
        h1 = 0.0;
        v2 = 0.0;
        h2 = 0.0;
        hs = 0.0;

        ga = 0.0;
        gb = 0.0;
        gw = 0.0;

        while(it != end){
            auto& items = *it++;

            for(size_t i = 0; i < num_visible; ++i){
                v1(i) = items[i];
            }

            activate_hidden(h1, v1);
            activate_visible(bernoulli(h1, hs), v2);
            activate_hidden(h2, v2);

            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    gw(i, j) += h1(j) * v1(i) - h2(j) * v2(i);
                }
            }

            ga += v1 - v2;
            gb += h1 - h2;
        }

        auto n_samples = static_cast<weight>(BatchSize);

        //gw / BatchSize
        for(size_t i = 0; i < num_visible; ++i){
            for(size_t j = 0; j < num_hidden; ++j){
                gw(i, j) /= n_samples;
            }
        }

        if(Momentum){
            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w_inc(i, j) = w_inc(i, j) * momentum + gw(i,j) * learning_rate;
                }
            }

            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w(i,j) += w_inc(i, j);
                }
            }
        } else {
            for(size_t i = 0; i < num_visible; ++i){
                for(size_t j = 0; j < num_hidden; ++j){
                    w(i,j) += gw(i, j) * learning_rate;
                }
            }
        }

        if(Momentum){
            a_inc = a_inc * momentum + (ga / n_samples) * learning_rate;
            a += a_inc;
        } else {
            a += (ga / n_samples) * learning_rate;
        }

        if(Momentum){
            b_inc = b_inc * momentum + (gb / n_samples) * learning_rate;
            b += b_inc;
        } else {
            b += (gb / n_samples) * learning_rate;
        }

        //Compute the reconstruction error

        double error = 0.0;
        for(size_t i = 0; i < num_visible; ++i){
            error += (ga(i)/ n_samples) * (ga(i) / n_samples);
        }
        error = sqrt(error / num_visible);

        return error;
    }

    template<typename TrainingItem>
    void reconstruct(const std::vector<TrainingItem>& items){
        dbn_assert(items.size() == num_visible, "The size of the training sample must match visible units");

        stop_watch<> watch;

        //Set the state of the visible units
        for(size_t i = 0; i < num_visible; ++i){
            visibles(i) = items[i];
        }

        activate_hidden(h1, visibles);
        activate_visible(bernoulli(h1, hs), v1);
        bernoulli(v1, visibles);

        std::cout << "Reconstruction took " << watch.elapsed() << "ms" << std::endl;
    }

    void generate_hidden_images(size_t epoch){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        for(size_t j = 0; j < num_hidden; ++j){
            auto path = folder + "/h_" + std::to_string(j) + ".dat";
            std::ofstream file(path, std::ios::out);

            if(!file){
                std::cout << "Could not open file " << path << std::endl;
            } else {
                size_t i = num_visible;
                while(i > 0){
                    --i;

                    auto value = w(i,j);
                    file << static_cast<size_t>(value > 0 ? static_cast<size_t>(value * 255.0) << 8 : static_cast<size_t>(-value * 255.0) << 16) << " ";
                }

                file << std::endl;
                file.close();
            }
        }
    }

    void generate_histograms(size_t epoch){
        mkdir("reports", 0777);

        auto folder = "reports/epoch_" + std::to_string(epoch);
        mkdir(folder.c_str(), 0777);

        //generate_histogram(folder + "/weights.dat", w.data(), num_visible * num_hidden);
//        generate_histogram(folder + "/visibles.dat", a.data(), num_visible);
//        generate_histogram(folder + "/hiddens.dat", b.data(), num_hidden);

        if(Momentum){
            //generate_histogram(folder + "/weights_inc.dat", w_inc.data(), num_visible * num_hidden);
//            generate_histogram(folder + "/visibles_inc.dat", a_inc.data(), num_visible);
//            generate_histogram(folder + "/hiddens_inc.dat", b_inc.data(), num_hidden);
        }
    }

    void generate_histogram(const std::string& path, const double* weights, size_t size){
        std::ofstream file(path, std::ios::out);

        if(!file){
            std::cout << "Could not open file " << path << std::endl;
        } else {
            for(size_t i = 0; i < size; ++i){
                file << weights[i] << std::endl;
            }

            file << std::endl;
            file.close();
        }
    }

    void display() const {
        display_visible_units();
        display_hidden_units();
    }

    void display_visible_units() const {
        std::cout << "Visible  Value" << std::endl;

        for(size_t i = 0; i < num_visible; ++i){
            printf("%-8lu %d\n", i, visibles(i));
        }
    }

    void display_visible_units(size_t matrix) const {
        for(size_t i = 0; i < matrix; ++i){
            for(size_t j = 0; j < matrix; ++j){
                std::cout << visibles(i * matrix + j) << " ";
            }
            std::cout << std::endl;
        }
    }

    void display_hidden_units() const {
        std::cout << "Hidden Value" << std::endl;

        for(size_t j = 0; j < num_hidden; ++j){
            printf("%-8lu %d\n", j, hiddens(j));
        }
    }

    void display_weights(){
        for(size_t j = 0; j < num_hidden; ++j){
            for(size_t i = 0; i < num_visible; ++i){
                std::cout << w(i, j) << " ";
            }
            std::cout << std::endl;
        }
    }

    void display_weights(size_t matrix){
        for(size_t j = 0; j < num_hidden; ++j){
            for(size_t i = 0; i < num_visible;){
                for(size_t m = 0; m < matrix; ++m){
                    std::cout << w(i++, j) << " ";
                }
                std::cout << std::endl;
            }
        }
    }
};

} //end of dbn namespace

#endif<|endoftext|>


<commit_before>#include <walrus_stair_detector/walrus_stair_detector_ros.h>
#include <walrus_stair_detector/Stair.h>
#include <pcl_conversions/pcl_conversions.h>

namespace walrus_stair_detector {

WalrusStairDetectorRos::WalrusStairDetectorRos(ros::NodeHandle& nh, ros::NodeHandle& pnh)
  : nh_(nh), pnh_(pnh) {
  points_sub_ = nh_.subscribe<PointCloud>("points", 1, &WalrusStairDetectorRos::pointsCallback, this);
  stair_pub_ = nh_.advertise<Stair>("stairs", 1);
}

static geometry_msgs::Point toPointMsg(Eigen::Vector3f v) {
  geometry_msgs::Point m;
  m.x = v[0];
  m.y = v[1];
  m.z = v[2];
  return m;
}
static geometry_msgs::Vector3 toVector3Msg(Eigen::Vector3f v) {
  geometry_msgs::Vector3 m;
  m.x = v[0];
  m.y = v[1];
  m.z = v[2];
  return m;
}

void WalrusStairDetectorRos::pointsCallback(const PointCloud::ConstPtr& msg) {
  Eigen::Vector3f vertical;
  vertical << 0, -1, 0;

  std::vector<StairModel> stairs;
  MultiTimer timer;
  detector.detect(msg, vertical, &stairs, &timer);
  TimerPeriod time = timer.getTotal();
  if(stairs.size() > 0) {
    ROS_INFO_STREAM("Found " << stairs.size() << " stairs in " << time.wall << "s (User: " << time.user << "s, System: " << time.system << "s)");

    const StairModel& stair_model = stairs[0];
    Stair stair_msg;
    stair_msg.header.frame_id = msg->header.frame_id;
    stair_msg.header.stamp = pcl_conversions::fromPCL(msg->header.stamp);
    stair_msg.origin = toPointMsg(stair_model.origin);
    stair_msg.vertical = toVector3Msg(stair_model.vertical);
    stair_msg.direction = toVector3Msg(stair_model.direction);
    stair_msg.horizontal = toVector3Msg(stair_model.horizontal);
    stair_msg.rise = stair_model.rise;
    stair_msg.run = stair_model.run;
    stair_msg.width = stair_model.width;
    stair_msg.num_stairs = stair_model.num_stairs;
    stair_pub_.publish(stair_msg);
  }
  else {
    ROS_INFO_STREAM("Found no stairs in " << time.wall << "s (User: " << time.user << "s, System: " << time.system << "s)");
  }
}

}
<commit_msg>Fixed compilation on hydro<commit_after>#include <walrus_stair_detector/walrus_stair_detector_ros.h>
#include <walrus_stair_detector/Stair.h>
#include <pcl_conversions/pcl_conversions.h>

namespace walrus_stair_detector {

WalrusStairDetectorRos::WalrusStairDetectorRos(ros::NodeHandle& nh, ros::NodeHandle& pnh)
  : nh_(nh), pnh_(pnh) {
  points_sub_ = nh_.subscribe<PointCloud>("points", 1, &WalrusStairDetectorRos::pointsCallback, this);
  stair_pub_ = nh_.advertise<Stair>("stairs", 1);
}

static geometry_msgs::Point toPointMsg(Eigen::Vector3f v) {
  geometry_msgs::Point m;
  m.x = v[0];
  m.y = v[1];
  m.z = v[2];
  return m;
}
static geometry_msgs::Vector3 toVector3Msg(Eigen::Vector3f v) {
  geometry_msgs::Vector3 m;
  m.x = v[0];
  m.y = v[1];
  m.z = v[2];
  return m;
}

void WalrusStairDetectorRos::pointsCallback(const PointCloud::ConstPtr& msg) {
  Eigen::Vector3f vertical;
  vertical << 0, -1, 0;

  std::vector<StairModel> stairs;
  MultiTimer timer;
  detector.detect(msg, vertical, &stairs, &timer);
  TimerPeriod time = timer.getTotal();
  if(stairs.size() > 0) {
    ROS_INFO_STREAM("Found " << stairs.size() << " stairs in " << time.wall << "s (User: " << time.user << "s, System: " << time.system << "s)");

    const StairModel& stair_model = stairs[0];
    Stair stair_msg;
    pcl_conversions::fromPCL(msg->header, stair_msg.header);
    stair_msg.origin = toPointMsg(stair_model.origin);
    stair_msg.vertical = toVector3Msg(stair_model.vertical);
    stair_msg.direction = toVector3Msg(stair_model.direction);
    stair_msg.horizontal = toVector3Msg(stair_model.horizontal);
    stair_msg.rise = stair_model.rise;
    stair_msg.run = stair_model.run;
    stair_msg.width = stair_model.width;
    stair_msg.num_stairs = stair_model.num_stairs;
    stair_pub_.publish(stair_msg);
  }
  else {
    ROS_INFO_STREAM("Found no stairs in " << time.wall << "s (User: " << time.user << "s, System: " << time.system << "s)");
  }
}

}
<|endoftext|>


<commit_before>//=============================================================================================================
/**
 * @file     main.cpp
 * @author   Juan Garcia-Prieto <juangpc@gmail.com>;
 *           Lorenz Esch <lesch@mgh.harvard.edu>;
 *           Wayne Mead <wayne.mead@uth.tmc.edu>;
 *           John C. Mosher <John.C.Mosher@uth.tmc.edu>;
 *           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
 * @date     May, 2020
 * @since    0.1.0
 *
 * @section  LICENSE
 *
 * Copyright (C) 2019, Juan Garcia-Prieto, Lorenz Esch, Matti Hamalainen, Wayne Mead, John C. Mosher. 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 MNE-CPP authors 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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief     Application for anonymizing patient and personal health information from a fiff file.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "apphandler.h"
#include <utils/generics/applicationlogger.h>

//=============================================================================================================
// Eigen
//=============================================================================================================

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QCoreApplication>

//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace UTILSLIB;

//=============================================================================================================
// MAIN
//=============================================================================================================
/**
 * The function main marks the entry point of the program.
 * By default, main has the storage class extern.
 *
 * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
 * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
 *
 * @return the value that was set to exit() (which is 0 if exit() is called via quit()).
 */
int main(int argc, char* argv[])
{
    qInstallMessageHandler(ApplicationLogger::customLogWriter);

    MNEANONYMIZE::AppHandler h;
    QScopedPointer<QCoreApplication>
            qtApp(h.createApplication(argc, argv));

    qtApp->setOrganizationName("MNE-CPP Project");
    qtApp->setApplicationName("MNE Anonymize");
    qtApp->setApplicationVersion("dev");

    QScopedPointer<MNEANONYMIZE::MainWindow> win(new MNEANONYMIZE::MainWindow);
    QScopedPointer<QObject>
            controller(h.createController(qtApp->arguments()));

    win->show();
    return qtApp->exec();
}
<commit_msg>main allocates pointers to qtApp, handler and controller<commit_after>//=============================================================================================================
/**
 * @file     main.cpp
 * @author   Juan Garcia-Prieto <juangpc@gmail.com>;
 *           Lorenz Esch <lesch@mgh.harvard.edu>;
 *           Wayne Mead <wayne.mead@uth.tmc.edu>;
 *           John C. Mosher <John.C.Mosher@uth.tmc.edu>;
 *           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
 * @date     May, 2020
 * @since    0.1.0
 *
 * @section  LICENSE
 *
 * Copyright (C) 2019, Juan Garcia-Prieto, Lorenz Esch, Matti Hamalainen, Wayne Mead, John C. Mosher. 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 MNE-CPP authors 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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * @brief     Application for anonymizing patient and personal health information from a fiff file.
 *
 */

//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "apphandler.h"
#include <utils/generics/applicationlogger.h>

//=============================================================================================================
// Eigen
//=============================================================================================================

//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QCoreApplication>

//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace UTILSLIB;

//=============================================================================================================
// MAIN
//=============================================================================================================
/**
 * The function main marks the entry point of the program.
 * By default, main has the storage class extern.
 *
 * @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
 * @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
 *
 * @return the value that was set to exit() (which is 0 if exit() is called via quit()).
 */
int main(int argc, char* argv[])
{
    qInstallMessageHandler(ApplicationLogger::customLogWriter);

    QScopedPointer<MNEANONYMIZE::AppHandler> h;
    QScopedPointer<QCoreApplication>
            qtApp(h->createApplication(argc, argv));

    qtApp->setOrganizationName("MNE-CPP Project");
    qtApp->setApplicationName("MNE Anonymize");
    qtApp->setApplicationVersion("dev");

    QScopedPointer<QObject>
            controller(h->createController(qtApp->arguments()));

    return qtApp->exec();
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef URI_HPP
#define URI_HPP

#include <gsl.h>
#include <unordered_map>

namespace uri {

  /**
   * Representation of RFC 3986 URI's.
   * Ref. https://tools.ietf.org/html/rfc3986
   **/
  class URI {
  private:
    /** Non-owning pointer-size type */
    struct Span_t {
      size_t begin;
      size_t end;

      Span_t(const size_t b = 0U, const size_t e = 0U) noexcept
        : begin{b}
        , end{e}
      {}
    }; //< struct Span_t

  public:
    /*
     * Default constructor
     */
    URI() = default;

    /*
     * Default copy and move constructors
     */
    URI(URI&) = default;
    URI(URI&&) = default;

    /*
     * Default destructor
     */
    ~URI() = default;

    /*
     * Default assignment operators
     */
    URI& operator=(const URI&) = default;
    URI& operator=(URI&&) = default;

    //
    // We might do a span-based constructor later.
    // URI(gsl::span<const char>);
    //

    /**
     * @brief Construct using a C-String
     *
     * @param uri : A C-String representing a uri
     */
    URI(const char* uri);

    /**
     * @brief Construct using a string
     *
     * @param uri : A string representing a uri
     */
    URI(const std::string& uri);

    ///////////////////////////////////////////////
    //----------RFC-specified URI parts----------//
    ///////////////////////////////////////////////

    /**
     * @brief Get userinfo.
     *
     * E.g. 'username@'...
     *
     * @return The user's information
     */
    std::string userinfo() const;

    /**
     * @brief Get host.
     *
     * E.g. 'includeos.org', '10.0.0.42' etc.
     *
     * @return The host's information
     */
    std::string host() const;

    /**
     * @brief Get the raw port number in decimal character representation.
     *
     * @return The raw port number as a string
     */
    std::string port_str() const;

    /**
     * @brief Get numeric port number.
     *
     * @warning The RFC doesn't specify dimension. This funcion will truncate
     * any overflowing digits.
     *
     * @return The numeric port number as a 16-bit number
     */
    uint16_t port() const noexcept;

    /**
     * @brief Get the path.
     *
     * E.g. /pictures/logo.png
     *
     * @return The path information
     */
    std::string path() const;

    /**
     * @brief Get the complete unparsed query string.
     *
     * @return The complete unparsed query string
     */
    std::string query() const;

    /**
     * @brief Get the fragment part.
     *
     * E.g. "...#anchor1"
     *
     * @return the fragment part
     */
    std::string fragment() const;

    /**
     * @brief Get the URI-decoded value of a query-string key.
     *
     * @param key : The key to find the associated value
     *
     * @return The key's associated value
     *
     * @example For the query: "?name=Bjarne%20Stroustrup",
     * query("name") returns "Bjarne Stroustrup"
     */
    std::string query(const std::string& key);

    /**
     * @brief Get a string representation of this
     * class
     *
     * @return - A string representation
     */
    std::string to_string() const;

  private:

    std::unordered_map<std::string,std::string> queries_;
    Span_t uri_data_;
    Span_t userinfo_;
    Span_t host_;
    Span_t port_str_;
    uint16_t port_ = 0;
    Span_t path_;
    Span_t query_;
    Span_t fragment_;

    static const Span_t zero_span_;

    // A copy of the data, if the string-based constructor was used
    std::string uri_str_;

    /**
     * @brief Parse the given string representing a uri
     * into its given parts according to RFC 3986
     *
     * @param uri : The string representing a uri
     */
    void parse(const std::string& uri);

  }; // class uri::URI

  std::ostream& operator<< (std::ostream&, const URI&);

} // namespace uri

#endif
<commit_msg>Added a method to implicitly convert uri::URI to a std::string<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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.

#ifndef URI_HPP
#define URI_HPP

#include <gsl.h>
#include <unordered_map>

namespace uri {

  /**
   * Representation of RFC 3986 URI's.
   * Ref. https://tools.ietf.org/html/rfc3986
   **/
  class URI {
  private:
    /** Non-owning pointer-size type */
    struct Span_t {
      size_t begin;
      size_t end;

      Span_t(const size_t b = 0U, const size_t e = 0U) noexcept
        : begin{b}
        , end{e}
      {}
    }; //< struct Span_t

  public:
    /*
     * Default constructor
     */
    URI() = default;

    /*
     * Default copy and move constructors
     */
    URI(URI&) = default;
    URI(URI&&) = default;

    /*
     * Default destructor
     */
    ~URI() = default;

    /*
     * Default assignment operators
     */
    URI& operator=(const URI&) = default;
    URI& operator=(URI&&) = default;

    //
    // We might do a span-based constructor later.
    // URI(gsl::span<const char>);
    //

    /**
     * @brief Construct using a C-String
     *
     * @param uri : A C-String representing a uri
     */
    URI(const char* uri);

    /**
     * @brief Construct using a string
     *
     * @param uri : A string representing a uri
     */
    URI(const std::string& uri);

    ///////////////////////////////////////////////
    //----------RFC-specified URI parts----------//
    ///////////////////////////////////////////////

    /**
     * @brief Get userinfo.
     *
     * E.g. 'username@'...
     *
     * @return The user's information
     */
    std::string userinfo() const;

    /**
     * @brief Get host.
     *
     * E.g. 'includeos.org', '10.0.0.42' etc.
     *
     * @return The host's information
     */
    std::string host() const;

    /**
     * @brief Get the raw port number in decimal character representation.
     *
     * @return The raw port number as a string
     */
    std::string port_str() const;

    /**
     * @brief Get numeric port number.
     *
     * @warning The RFC doesn't specify dimension. This funcion will truncate
     * any overflowing digits.
     *
     * @return The numeric port number as a 16-bit number
     */
    uint16_t port() const noexcept;

    /**
     * @brief Get the path.
     *
     * E.g. /pictures/logo.png
     *
     * @return The path information
     */
    std::string path() const;

    /**
     * @brief Get the complete unparsed query string.
     *
     * @return The complete unparsed query string
     */
    std::string query() const;

    /**
     * @brief Get the fragment part.
     *
     * E.g. "...#anchor1"
     *
     * @return the fragment part
     */
    std::string fragment() const;

    /**
     * @brief Get the URI-decoded value of a query-string key.
     *
     * @param key : The key to find the associated value
     *
     * @return The key's associated value
     *
     * @example For the query: "?name=Bjarne%20Stroustrup",
     * query("name") returns "Bjarne Stroustrup"
     */
    std::string query(const std::string& key);

    /**
     * @brief Get a string representation of this
     * class
     *
     * @return - A string representation
     */
    std::string to_string() const;

    /**
     * @brief Operator to transform this class
     * into string form
     */
    operator std::string () const;

  private:

    std::unordered_map<std::string,std::string> queries_;
    Span_t uri_data_;
    Span_t userinfo_;
    Span_t host_;
    Span_t port_str_;
    uint16_t port_ = 0;
    Span_t path_;
    Span_t query_;
    Span_t fragment_;

    static const Span_t zero_span_;

    // A copy of the data, if the string-based constructor was used
    std::string uri_str_;

    /**
     * @brief Parse the given string representing a uri
     * into its given parts according to RFC 3986
     *
     * @param uri : The string representing a uri
     */
    void parse(const std::string& uri);

  }; // class uri::URI

  std::ostream& operator<< (std::ostream&, const URI&);

} // namespace uri

#endif
<|endoftext|>


<commit_before>#pragma once
/**
	@file
	@brief parallel for
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <cybozu/exception.hpp>
#include <cybozu/thread.hpp>
#include <cybozu/array.hpp>

namespace cybozu {

namespace parallel_util {

template<class T, class N>
struct Thread : public cybozu::ThreadBase {
	T *t_;
	N begin_;
	N end_;
	size_t threadIdx_;
	std::string err_;
	Thread()
		: t_(0)
		, begin_(0)
		, end_(0)
		, threadIdx_(0)
	{
	}
	void init(T& t, N begin, N end, size_t threadIdx)
	{
		t_ = &t;
		begin_ = begin;
		end_ = end;
		threadIdx_ = threadIdx;
		err_.empty();
	}
	void threadEntry()
	{
		for (N i = begin_; i < end_; i++) {
			try {
				if (!(*t_)(i, threadIdx_)) break;
			} catch (std::exception& e) {
				err_ = e.what();
				break;
			}
		}
	}
	const std::string& getErr() const { return err_; }
};

} // parallel_util
/*
	void T::f(N i, size_t threadIdx);
*/
template<class T, class N>
void parallel_for(T& target, N n, size_t threadNum)
{
	if (threadNum == 0) throw cybozu::Exception("cybozu:parallel_for:threadNum is zero");
	if ((N)threadNum > n) threadNum = (size_t)n;
	typedef parallel_util::Thread<T, N> Thread;
	{
		cybozu::ScopedArray<Thread> thread(threadNum);
		const N q = N(n / threadNum);
		const N r = N(n % threadNum);
		N begin = 0;
		for (size_t i = 0; i < threadNum; i++) {
			N end = begin + q;
			if (i < r) end++;
			thread[i].init(target, begin, end, i);
			begin = end;
		}
		for (size_t i = 0; i < threadNum; i++) {
			if (!thread[i].beginThread()) throw cybozu::Exception("cybozu:parallel_for:can't beginThread") << i;
		}
		for (size_t i = 0; i < threadNum; i++) {
			if (!thread[i].joinThread()) throw cybozu::Exception("cybozu:parallel_for:can't joinThread") << i;
		}
		for (size_t i = 0; i < threadNum; i++) {
			const std::string& err = thread[i].getErr();
			if (!err.empty()) throw cybozu::Exception("cybozu:paralell_for") << i << err;
		}
	}
}

} // cybozu
<commit_msg>[revert] type of threadNum is N<commit_after>#pragma once
/**
	@file
	@brief parallel for
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <cybozu/exception.hpp>
#include <cybozu/thread.hpp>
#include <cybozu/array.hpp>

namespace cybozu {

namespace parallel_util {

template<class T, class N>
struct Thread : public cybozu::ThreadBase {
	T *t_;
	N begin_;
	N end_;
	N threadIdx_;
	std::string err_;
	Thread()
		: t_(0)
		, begin_(0)
		, end_(0)
		, threadIdx_(0)
	{
	}
	void init(T& t, N begin, N end, N threadIdx)
	{
		t_ = &t;
		begin_ = begin;
		end_ = end;
		threadIdx_ = threadIdx;
		err_.empty();
	}
	void threadEntry()
	{
		for (N i = begin_; i < end_; i++) {
			try {
				if (!(*t_)(i, threadIdx_)) break;
			} catch (std::exception& e) {
				err_ = e.what();
				break;
			}
		}
	}
	const std::string& getErr() const { return err_; }
};

} // parallel_util
/*
	void T::f(N i, size_t threadIdx);
*/
template<class T, class N>
void parallel_for(T& target, N n, N threadNum)
{
	if (threadNum == 0) throw cybozu::Exception("cybozu:parallel_for:threadNum is zero");
	if ((N)threadNum > n) threadNum = (size_t)n;
	typedef parallel_util::Thread<T, N> Thread;
	{
		cybozu::ScopedArray<Thread> thread(threadNum);
		const N q = N(n / threadNum);
		const N r = N(n % threadNum);
		N begin = 0;
		for (N i = 0; i < threadNum; i++) {
			N end = begin + q;
			if (i < r) end++;
			thread[i].init(target, begin, end, i);
			begin = end;
		}
		for (N i = 0; i < threadNum; i++) {
			if (!thread[i].beginThread()) throw cybozu::Exception("cybozu:parallel_for:can't beginThread") << i;
		}
		for (N i = 0; i < threadNum; i++) {
			if (!thread[i].joinThread()) throw cybozu::Exception("cybozu:parallel_for:can't joinThread") << i;
		}
		for (N i = 0; i < threadNum; i++) {
			const std::string& err = thread[i].getErr();
			if (!err.empty()) throw cybozu::Exception("cybozu:paralell_for") << i << err;
		}
	}
}

} // cybozu
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
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 the author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_TIME_HPP_INCLUDED
#define TORRENT_TIME_HPP_INCLUDED

#include <ctime>

#ifndef _WIN32
#include <unistd.h>
#endif

namespace libtorrent
{
	inline char const* time_now_string()
	{
		time_t t = std::time(0);
		tm* timeinfo = std::localtime(&t);
		static char str[200];
		std::strftime(str, 200, "%b %d %X", timeinfo);
		return str;
	}
}

#if (!defined (__MACH__) && !defined (_WIN32) && !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0) || defined (TORRENT_USE_BOOST_DATE_TIME)

#include <boost/date_time/posix_time/posix_time_types.hpp>

namespace libtorrent
{
	typedef boost::posix_time::ptime ptime;
	typedef boost::posix_time::time_duration time_duration;
	inline ptime time_now()
	{ return boost::posix_time::microsec_clock::universal_time(); }
	inline ptime min_time()
	{ return boost::posix_time::ptime(boost::posix_time::min_date_time); }
	inline ptime max_time()
	{ return boost::posix_time::ptime(boost::posix_time::max_date_time); }
	inline time_duration seconds(int s) { return boost::posix_time::seconds(s); }
	inline time_duration milliseconds(int s) { return boost::posix_time::milliseconds(s); }
	inline time_duration microsec(int s) { return boost::posix_time::microsec(s); }
	inline time_duration minutes(int s) { return boost::posix_time::minutes(s); }
	inline time_duration hours(int s) { return boost::posix_time::hours(s); }

	inline int total_seconds(time_duration td)
	{ return td.total_seconds(); }
	inline int total_milliseconds(time_duration td)
	{ return td.total_milliseconds(); }
	inline boost::int64_t total_microseconds(time_duration td)
	{ return td.total_microseconds(); }

}

#else

#include <asio/time_traits.hpp>
#include <boost/cstdint.hpp>

namespace libtorrent
{
	// libtorrent time_duration type
	struct time_duration
	{
		time_duration() {}
		explicit time_duration(boost::int64_t d) : diff(d) {}
		boost::int64_t diff;
	};

	inline bool is_negative(time_duration dt) { return dt.diff < 0; }
	inline bool operator<(time_duration lhs, time_duration rhs)
	{ return lhs.diff < rhs.diff; }
	inline bool operator>(time_duration lhs, time_duration rhs)
	{ return lhs.diff > rhs.diff; }

	// libtorrent time type
	struct ptime
	{
		ptime() {}
		explicit ptime(boost::int64_t t): time(t) {}
		boost::int64_t time;
	};

	inline bool operator>(ptime lhs, ptime rhs)
	{ return lhs.time > rhs.time; }
	inline bool operator>=(ptime lhs, ptime rhs)
	{ return lhs.time >= rhs.time; }
	inline bool operator<=(ptime lhs, ptime rhs)
	{ return lhs.time <= rhs.time; }
	inline bool operator<(ptime lhs, ptime rhs)
	{ return lhs.time < rhs.time; }
	inline bool operator!=(ptime lhs, ptime rhs)
	{ return lhs.time != rhs.time;}
	inline bool operator==(ptime lhs, ptime rhs)
	{ return lhs.time == rhs.time;}
	inline time_duration operator-(ptime lhs, ptime rhs)
	{ return time_duration(lhs.time - rhs.time); }
	inline ptime operator+(ptime lhs, time_duration rhs)
	{ return ptime(lhs.time + rhs.diff); }
	inline ptime operator+(time_duration lhs, ptime rhs)
	{ return ptime(rhs.time + lhs.diff); }
	inline ptime operator-(ptime lhs, time_duration rhs)
	{ return ptime(lhs.time - rhs.diff); }

	ptime time_now();
	inline ptime min_time() { return ptime(0); }
	inline ptime max_time() { return ptime((std::numeric_limits<boost::int64_t>::max)()); }
	int total_seconds(time_duration td);
	int total_milliseconds(time_duration td);
	boost::int64_t total_microseconds(time_duration td);
}

// asio time_traits
namespace asio
{
	template<>
	struct time_traits<libtorrent::ptime>
	{
		typedef libtorrent::ptime time_type;
		typedef libtorrent::time_duration duration_type;
		static time_type now()
		{ return time_type(libtorrent::time_now()); }
		static time_type add(time_type t, duration_type d)
		{ return time_type(t.time + d.diff);}
		static duration_type subtract(time_type t1, time_type t2)
		{ return duration_type(t1 - t2); }
		static bool less_than(time_type t1, time_type t2)
		{ return t1 < t2; }
		static boost::posix_time::time_duration to_posix_duration(
			duration_type d)
		{ return boost::posix_time::microseconds(libtorrent::total_microseconds(d)); }
	};
}

#if defined(__MACH__)

#include <mach/mach_time.h>
#include <boost/cstdint.hpp>

// high precision timer for darwin intel and ppc

namespace libtorrent
{
	namespace aux
	{
		inline boost::int64_t absolutetime_to_microseconds(boost::int64_t at)
		{
			static mach_timebase_info_data_t timebase_info = {0,0};
			if (timebase_info.denom == 0)
				mach_timebase_info(&timebase_info);
			// make sure we don't overflow
			assert((at >= 0 && at >= at / 1000 * timebase_info.numer / timebase_info.denom)
				|| (at < 0 && at < at / 1000 * timebase_info.numer / timebase_info.denom));
			return at / 1000 * timebase_info.numer / timebase_info.denom;
		}

		inline boost::int64_t microseconds_to_absolutetime(boost::int64_t ms)
		{
			static mach_timebase_info_data_t timebase_info = {0,0};
			if (timebase_info.denom == 0)
			{
				mach_timebase_info(&timebase_info);
				assert(timebase_info.numer > 0);
				assert(timebase_info.denom > 0);
			}
			// make sure we don't overflow
			assert((ms >= 0 && ms <= ms * timebase_info.denom / timebase_info.numer * 1000)
				|| (ms < 0 && ms > ms * timebase_info.denom / timebase_info.numer * 1000));
			return ms * timebase_info.denom / timebase_info.numer * 1000;
		}
	}

	inline int total_seconds(time_duration td)
	{
		return aux::absolutetime_to_microseconds(td.diff)
			/ 1000000;
	}
	inline int total_milliseconds(time_duration td)
	{
		return aux::absolutetime_to_microseconds(td.diff)
			/ 1000;
	}
	inline boost::int64_t total_microseconds(time_duration td)
	{
		return aux::absolutetime_to_microseconds(td.diff);
	}

	inline ptime time_now() { return ptime(mach_absolute_time()); }

	inline time_duration microsec(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s));
	}
	inline time_duration milliseconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000));
	}
	inline time_duration seconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000000));
	}
	inline time_duration minutes(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000000 * 60));
	}
	inline time_duration hours(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000000 * 60 * 60));
	}

}
#elif defined(_WIN32)

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>

namespace libtorrent
{
	namespace aux
	{
		inline boost::int64_t performance_counter_to_microseconds(boost::int64_t pc)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);

			return pc * 1000000 / performace_counter_frequency.QuadPart;
		}

		inline boost::int64_t microseconds_to_performance_counter(boost::int64_t ms)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);
			return ms * performace_counter_frequency.QuadPart / 1000000;
		}
	}

	inline int total_seconds(time_duration td)
	{
		return aux::performance_counter_to_microseconds(td.diff)
			/ 1000000;
	}
	inline int total_milliseconds(time_duration td)
	{
		return aux::performance_counter_to_microseconds(td.diff)
			/ 1000;
	}
	inline boost::int64_t total_microseconds(time_duration td)
	{
		return aux::performance_counter_to_microseconds(td.diff);
	}

	inline ptime time_now()
	{
		LARGE_INTEGER now;
		QueryPerformanceCounter(&now);
		return ptime(now.QuadPart);
	}

	inline time_duration microsec(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(s));
	}
	inline time_duration milliseconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000));
	}
	inline time_duration seconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000000));
	}
	inline time_duration minutes(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000000 * 60));
	}
	inline time_duration hours(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000000 * 60 * 60));
	}

}

#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0

#include <time.h>

namespace libtorrent
{
	inline int total_seconds(time_duration td)
	{
		return td.diff / 1000000;
	}
	inline int total_milliseconds(time_duration td)
	{
		return td.diff / 1000;
	}
	inline boost::int64_t total_microseconds(time_duration td)
	{
		return td.diff;
	}

	inline ptime time_now()
	{
		timespec ts;
		clock_gettime(CLOCK_MONOTONIC, &ts);
		return ptime(boost::int64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000);
	}

	inline time_duration microsec(boost::int64_t s)
	{
		return time_duration(s);
	}
	inline time_duration milliseconds(boost::int64_t s)
	{
		return time_duration(s * 1000);
	}
	inline time_duration seconds(boost::int64_t s)
	{
		return time_duration(s * 1000000);
	}
	inline time_duration minutes(boost::int64_t s)
	{
		return time_duration(s * 1000000 * 60);
	}
	inline time_duration hours(boost::int64_t s)
	{
		return time_duration(s * 1000000 * 60 * 60);
	}

}

#endif

#endif
#endif

<commit_msg>overflow fix in timer on windows<commit_after>/*

Copyright (c) 2007, Arvid Norberg
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 the author 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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_TIME_HPP_INCLUDED
#define TORRENT_TIME_HPP_INCLUDED

#include <ctime>

#ifndef _WIN32
#include <unistd.h>
#endif

namespace libtorrent
{
	inline char const* time_now_string()
	{
		time_t t = std::time(0);
		tm* timeinfo = std::localtime(&t);
		static char str[200];
		std::strftime(str, 200, "%b %d %X", timeinfo);
		return str;
	}
}

#if (!defined (__MACH__) && !defined (_WIN32) && !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0) || defined (TORRENT_USE_BOOST_DATE_TIME)

#include <boost/date_time/posix_time/posix_time_types.hpp>

namespace libtorrent
{
	typedef boost::posix_time::ptime ptime;
	typedef boost::posix_time::time_duration time_duration;
	inline ptime time_now()
	{ return boost::posix_time::microsec_clock::universal_time(); }
	inline ptime min_time()
	{ return boost::posix_time::ptime(boost::posix_time::min_date_time); }
	inline ptime max_time()
	{ return boost::posix_time::ptime(boost::posix_time::max_date_time); }
	inline time_duration seconds(int s) { return boost::posix_time::seconds(s); }
	inline time_duration milliseconds(int s) { return boost::posix_time::milliseconds(s); }
	inline time_duration microsec(int s) { return boost::posix_time::microsec(s); }
	inline time_duration minutes(int s) { return boost::posix_time::minutes(s); }
	inline time_duration hours(int s) { return boost::posix_time::hours(s); }

	inline int total_seconds(time_duration td)
	{ return td.total_seconds(); }
	inline int total_milliseconds(time_duration td)
	{ return td.total_milliseconds(); }
	inline boost::int64_t total_microseconds(time_duration td)
	{ return td.total_microseconds(); }

}

#else

#include <asio/time_traits.hpp>
#include <boost/cstdint.hpp>

namespace libtorrent
{
	// libtorrent time_duration type
	struct time_duration
	{
		time_duration() {}
		explicit time_duration(boost::int64_t d) : diff(d) {}
		boost::int64_t diff;
	};

	inline bool is_negative(time_duration dt) { return dt.diff < 0; }
	inline bool operator<(time_duration lhs, time_duration rhs)
	{ return lhs.diff < rhs.diff; }
	inline bool operator>(time_duration lhs, time_duration rhs)
	{ return lhs.diff > rhs.diff; }

	// libtorrent time type
	struct ptime
	{
		ptime() {}
		explicit ptime(boost::int64_t t): time(t) {}
		boost::int64_t time;
	};

	inline bool operator>(ptime lhs, ptime rhs)
	{ return lhs.time > rhs.time; }
	inline bool operator>=(ptime lhs, ptime rhs)
	{ return lhs.time >= rhs.time; }
	inline bool operator<=(ptime lhs, ptime rhs)
	{ return lhs.time <= rhs.time; }
	inline bool operator<(ptime lhs, ptime rhs)
	{ return lhs.time < rhs.time; }
	inline bool operator!=(ptime lhs, ptime rhs)
	{ return lhs.time != rhs.time;}
	inline bool operator==(ptime lhs, ptime rhs)
	{ return lhs.time == rhs.time;}
	inline time_duration operator-(ptime lhs, ptime rhs)
	{ return time_duration(lhs.time - rhs.time); }
	inline ptime operator+(ptime lhs, time_duration rhs)
	{ return ptime(lhs.time + rhs.diff); }
	inline ptime operator+(time_duration lhs, ptime rhs)
	{ return ptime(rhs.time + lhs.diff); }
	inline ptime operator-(ptime lhs, time_duration rhs)
	{ return ptime(lhs.time - rhs.diff); }

	ptime time_now();
	inline ptime min_time() { return ptime(0); }
	inline ptime max_time() { return ptime((std::numeric_limits<boost::int64_t>::max)()); }
	int total_seconds(time_duration td);
	int total_milliseconds(time_duration td);
	boost::int64_t total_microseconds(time_duration td);
}

// asio time_traits
namespace asio
{
	template<>
	struct time_traits<libtorrent::ptime>
	{
		typedef libtorrent::ptime time_type;
		typedef libtorrent::time_duration duration_type;
		static time_type now()
		{ return time_type(libtorrent::time_now()); }
		static time_type add(time_type t, duration_type d)
		{ return time_type(t.time + d.diff);}
		static duration_type subtract(time_type t1, time_type t2)
		{ return duration_type(t1 - t2); }
		static bool less_than(time_type t1, time_type t2)
		{ return t1 < t2; }
		static boost::posix_time::time_duration to_posix_duration(
			duration_type d)
		{ return boost::posix_time::microseconds(libtorrent::total_microseconds(d)); }
	};
}

#if defined(__MACH__)

#include <mach/mach_time.h>
#include <boost/cstdint.hpp>

// high precision timer for darwin intel and ppc

namespace libtorrent
{
	namespace aux
	{
		inline boost::int64_t absolutetime_to_microseconds(boost::int64_t at)
		{
			static mach_timebase_info_data_t timebase_info = {0,0};
			if (timebase_info.denom == 0)
				mach_timebase_info(&timebase_info);
			// make sure we don't overflow
			assert((at >= 0 && at >= at / 1000 * timebase_info.numer / timebase_info.denom)
				|| (at < 0 && at < at / 1000 * timebase_info.numer / timebase_info.denom));
			return at / 1000 * timebase_info.numer / timebase_info.denom;
		}

		inline boost::int64_t microseconds_to_absolutetime(boost::int64_t ms)
		{
			static mach_timebase_info_data_t timebase_info = {0,0};
			if (timebase_info.denom == 0)
			{
				mach_timebase_info(&timebase_info);
				assert(timebase_info.numer > 0);
				assert(timebase_info.denom > 0);
			}
			// make sure we don't overflow
			assert((ms >= 0 && ms <= ms * timebase_info.denom / timebase_info.numer * 1000)
				|| (ms < 0 && ms > ms * timebase_info.denom / timebase_info.numer * 1000));
			return ms * timebase_info.denom / timebase_info.numer * 1000;
		}
	}

	inline int total_seconds(time_duration td)
	{
		return aux::absolutetime_to_microseconds(td.diff)
			/ 1000000;
	}
	inline int total_milliseconds(time_duration td)
	{
		return aux::absolutetime_to_microseconds(td.diff)
			/ 1000;
	}
	inline boost::int64_t total_microseconds(time_duration td)
	{
		return aux::absolutetime_to_microseconds(td.diff);
	}

	inline ptime time_now() { return ptime(mach_absolute_time()); }

	inline time_duration microsec(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s));
	}
	inline time_duration milliseconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000));
	}
	inline time_duration seconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000000));
	}
	inline time_duration minutes(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000000 * 60));
	}
	inline time_duration hours(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_absolutetime(s * 1000000 * 60 * 60));
	}

}
#elif defined(_WIN32)

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>

namespace libtorrent
{
	namespace aux
	{
		inline boost::int64_t performance_counter_to_microseconds(boost::int64_t pc)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);

#ifndef NDEBUG
			// make sure we don't overflow
			boost::int64_t ret = (pc * 1000 / performace_counter_frequency.QuadPart) * 1000;
			assert((pc >= 0 && pc >= ret) || (pc < 0 && pc < ret));
#endif
			return (pc * 1000 / performace_counter_frequency.QuadPart) * 1000;
		}

		inline boost::int64_t microseconds_to_performance_counter(boost::int64_t ms)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);
#ifndef NDEBUG
			// make sure we don't overflow
			boost::int64_t ret = (ms / 1000) * performace_counter_frequency.QuadPart / 1000;
			assert((ms >= 0 && ms <= ret)
				|| (ms < 0 && ms > ret));
#endif
			return (ms / 1000) * performace_counter_frequency.QuadPart / 1000;
		}
	}

	inline int total_seconds(time_duration td)
	{
		return aux::performance_counter_to_microseconds(td.diff)
			/ 1000000;
	}
	inline int total_milliseconds(time_duration td)
	{
		return aux::performance_counter_to_microseconds(td.diff)
			/ 1000;
	}
	inline boost::int64_t total_microseconds(time_duration td)
	{
		return aux::performance_counter_to_microseconds(td.diff);
	}

	inline ptime time_now()
	{
		LARGE_INTEGER now;
		QueryPerformanceCounter(&now);
		return ptime(now.QuadPart);
	}

	inline time_duration microsec(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(s));
	}
	inline time_duration milliseconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000));
	}
	inline time_duration seconds(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000000));
	}
	inline time_duration minutes(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000000 * 60));
	}
	inline time_duration hours(boost::int64_t s)
	{
		return time_duration(aux::microseconds_to_performance_counter(
			s * 1000000 * 60 * 60));
	}

}

#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0

#include <time.h>

namespace libtorrent
{
	inline int total_seconds(time_duration td)
	{
		return td.diff / 1000000;
	}
	inline int total_milliseconds(time_duration td)
	{
		return td.diff / 1000;
	}
	inline boost::int64_t total_microseconds(time_duration td)
	{
		return td.diff;
	}

	inline ptime time_now()
	{
		timespec ts;
		clock_gettime(CLOCK_MONOTONIC, &ts);
		return ptime(boost::int64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000);
	}

	inline time_duration microsec(boost::int64_t s)
	{
		return time_duration(s);
	}
	inline time_duration milliseconds(boost::int64_t s)
	{
		return time_duration(s * 1000);
	}
	inline time_duration seconds(boost::int64_t s)
	{
		return time_duration(s * 1000000);
	}
	inline time_duration minutes(boost::int64_t s)
	{
		return time_duration(s * 1000000 * 60);
	}
	inline time_duration hours(boost::int64_t s)
	{
		return time_duration(s * 1000000 * 60 * 60);
	}

}

#endif

#endif
#endif

<|endoftext|>


<commit_before>/*
*  Copyright 2016 Ivan Ryabov
*
*  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.
*/
/*******************************************************************************
 * libSolace: A C++ delegate analogue of std::function that handles movable objects
 *	@file		solace/delegate.hpp
 *	@author		$LastChangedBy$
 *	@date		$LastChangedDate$
 *	ID:			$Id$
 ******************************************************************************/
#pragma once
#ifndef SOLACE_DELEGATE_HPP
#define SOLACE_DELEGATE_HPP

#include <memory>
#include <type_traits>
#include <utility>

namespace Solace {

template <typename T>
class delegate;

template<class R, class ...A>
class delegate<R(A...)> {
public:
    delegate() = default;

    delegate(delegate const&) = default;

    delegate(delegate && x) = default;

    delegate(::std::nullptr_t const) noexcept : delegate() { }

    template <class C,
              typename = std::enable_if_t<std::is_class<C>{}>>
    explicit delegate(C const* const o) noexcept :
        object_ptr_(const_cast<C*>(o))
    { }

    template <class C,
              typename = std::enable_if_t<std::is_class<C>{}>>
    explicit delegate(C const& o) noexcept :
    object_ptr_(const_cast<C*>(&o))
    {
    }

    template <class C>
    delegate(C* const object_ptr, R (C::* const method_ptr)(A...)) {
        *this = from(object_ptr, method_ptr);
    }

    template <class C>
    delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const) {
        *this = from(object_ptr, method_ptr);
    }

    template <class C>
    delegate(C& object, R (C::* const method_ptr)(A...)) {
        *this = from(object, method_ptr);
    }

    template <class C>
    delegate(C const& object, R (C::* const method_ptr)(A...) const) {
        *this = from(object, method_ptr);
    }

    template <typename T,
              typename = std::enable_if_t<!std::is_same<delegate, typename std::decay<T>::type>{}>
              >
    delegate(T&& f) :
        store_(operator new(sizeof(std::decay_t<T>)), functor_deleter<std::decay_t<T>>),
        store_size_(sizeof(std::decay_t<T>))
    {
        using functor_type = std::decay_t<T>;

        new (store_.get()) functor_type(::std::forward<T>(f));
        object_ptr_ = store_.get();
        stub_ptr_ = functor_stub<functor_type>;
        deleter_ = deleter_stub<functor_type>;
    }

    delegate& operator= (const delegate&) = default;

    delegate& operator= (delegate&&) = default;

    template <class C>
    delegate& operator=(R (C::* const rhs)(A...)) {
        return *this = from(static_cast<C*>(object_ptr_), rhs);
    }

    template <class C>
    delegate& operator=(R (C::* const rhs)(A...) const) {
        return *this = from(static_cast<C const*>(object_ptr_), rhs);
    }

    template <typename T,
              typename = std::enable_if_t<!std::is_same<delegate, std::decay_t<T>>{}>
              >
    delegate& operator= (T&& f) {
        using functor_type = std::decay_t<T>;

        if ((sizeof(functor_type) > store_size_) || !store_.unique()) {
            store_.reset(operator new(sizeof(functor_type)),
                         functor_deleter<functor_type>);
            store_size_ = sizeof(functor_type);
        } else {
            deleter_(store_.get());
        }

        new (store_.get()) functor_type(::std::forward<T>(f));
        object_ptr_ = store_.get();
        stub_ptr_ = functor_stub<functor_type>;
        deleter_ = deleter_stub<functor_type>;

        return *this;
    }

    template <R (* const function_ptr)(A...)>
    static delegate from() noexcept {
        return {nullptr, function_stub<function_ptr>};
    }

    template <class C, R (C::* const method_ptr)(A...)>
    static delegate from(C* const object_ptr) noexcept {
        return {object_ptr, method_stub<C, method_ptr>};
    }

    template <class C, R (C::* const method_ptr)(A...) const>
    static delegate from(C const* const object_ptr) noexcept {
        return {const_cast<C*>(object_ptr), const_method_stub<C, method_ptr>};
    }

    template <class C, R (C::* const method_ptr)(A...)>
    static delegate from(C& object) noexcept {
        return { &object, method_stub<C, method_ptr> };
    }

    template <class C, R (C::* const method_ptr)(A...) const>
    static delegate from(C const& object) noexcept {
        return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
    }

    template <typename T>
    static delegate from(T&& f) {
        return ::std::forward<T>(f);
    }

    static delegate from(R (* const function_ptr)(A...)) {
        return function_ptr;
    }

    template <class C>
    using member_pair = std::pair<C* const, R (C::* const)(A...)>;

    template <class C>
    using const_member_pair = std::pair<C const* const, R (C::* const)(A...) const>;

    template <class C>
    static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...)) {
        return member_pair<C>(object_ptr, method_ptr);
    }

    template <class C>
    static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const) {
        return const_member_pair<C>(object_ptr, method_ptr);
    }

    template <class C>
    static delegate from(C& object, R (C::* const method_ptr)(A...)) {
        return member_pair<C>(&object, method_ptr);
    }

    template <class C>
    static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const) {
        return const_member_pair<C>(&object, method_ptr);
    }

    void reset() { stub_ptr_ = nullptr; store_.reset(); }

    void reset_stub() noexcept { stub_ptr_ = nullptr; }

    delegate& swap(delegate& other) noexcept {
        std::swap(*this, other);

        return *this;
    }

    bool operator== (delegate const& rhs) const noexcept {
        return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
    }

    bool operator!= (delegate const& rhs) const noexcept {
        return !operator==(rhs);
    }

    bool operator< (delegate const& rhs) const noexcept {
        return (object_ptr_ < rhs.object_ptr_) || ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
    }

    bool operator== (::std::nullptr_t const) const noexcept {
        return !stub_ptr_;
    }

    bool operator!=(::std::nullptr_t const) const noexcept {
        return stub_ptr_;
    }

    explicit operator bool() const noexcept { return stub_ptr_; }

    R operator()(A... args) const {
    return stub_ptr_(object_ptr_, std::forward<A>(args)...);
    }

private:
    using stub_ptr_type = R (*)(void*, A&&...);

    delegate(void* const o, stub_ptr_type const m) noexcept :
        object_ptr_(o),
        stub_ptr_(m),
        store_size_(0)
    { }

    friend struct std::hash<delegate>;

    using deleter_type = void (*)(void*);

    void* object_ptr_;
    stub_ptr_type stub_ptr_{};

    deleter_type deleter_;

    std::shared_ptr<void> store_;
    std::size_t store_size_;

    template <class T>
    static void functor_deleter(void* const p) {
        static_cast<T*>(p)->~T();

        operator delete(p);
    }

    template <class T>
    static void deleter_stub(void* const p) {
        static_cast<T*>(p)->~T();
    }

    template <R (*function_ptr)(A...)>
    static R function_stub(void* const, A&&... args) {
        return function_ptr(::std::forward<A>(args)...);
    }

    template <class C, R (C::*method_ptr)(A...)>
    static R method_stub(void* const object_ptr, A&&... args) {
        return (static_cast<C*>(object_ptr)->*method_ptr)(std::forward<A>(args)...);
    }

    template <class C, R (C::*method_ptr)(A...) const>
    static R const_method_stub(void* const object_ptr, A&&... args) {
        return (static_cast<C const*>(object_ptr)->*method_ptr)(std::forward<A>(args)...);
    }

    template <typename>
    struct is_member_pair : std::false_type { };

    template <class C>
    struct is_member_pair< ::std::pair<C* const,
    R (C::* const)(A...)> > : std::true_type {
    };

    template <typename>
    struct is_const_member_pair : std::false_type { };

    template <class C>
    struct is_const_member_pair< ::std::pair<C const* const,
    R (C::* const)(A...) const> > : std::true_type
    {
    };

    template <typename T>
    static std::enable_if_t<!(is_member_pair<T>{} || is_const_member_pair<T>{}), R>
    functor_stub(void* const object_ptr, A&&... args) {
        return (*static_cast<T*>(object_ptr))(std::forward<A>(args)...);
    }

    template <typename T>
    static std::enable_if_t<is_member_pair<T>{} || is_const_member_pair<T>{}, R>
    functor_stub(void* const object_ptr, A&&... args) {
        return (static_cast<T*>(object_ptr)->first->*static_cast<T*>(object_ptr)->second)(std::forward<A>(args)...);
    }

};

}  // End of namespace Solace

namespace std {

    template <typename R, typename ...A>
    struct hash<::Solace::delegate<R(A...)>> {

        size_t operator()(::Solace::delegate<R (A...)> const& d) const noexcept {
            auto const seed(hash<void*>()(d.object_ptr_));

            return hash<typename ::Solace::delegate<R (A...)>::stub_ptr_type>()
                                     (d.stub_ptr_) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        }
    };
}  // namespace std

#endif  // SOLACE_DELEGATE_HPP
<commit_msg>Removed dead code<commit_after><|endoftext|>


<commit_before>#include <boost/python.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <scitbx/stl/map_wrapper.h>
#include <boost/shared_ptr.hpp>
#include <map>
#include <iostream>

namespace dials { namespace util {

namespace boost_python {

using namespace boost::python;

template <class Key, class T, class Compare = std::less <Key> >
class SharedMap {

public:

  typedef typename std::map <Key, T, Compare> map_type;
  typedef typename map_type::key_type key_type;
  typedef typename map_type::mapped_type mapped_type;
  typedef typename map_type::value_type value_type;
  typedef typename map_type::key_compare key_compare;
  typedef typename map_type::value_compare value_compare;
  typedef typename map_type::allocator_type allocator_type;
  typedef typename map_type::reference reference;
  typedef typename map_type::const_reference const_reference;
  typedef typename map_type::pointer pointer;
  typedef typename map_type::const_pointer const_pointer;
  typedef typename map_type::iterator iterator;
  typedef typename map_type::const_iterator const_iterator;
  typedef typename map_type::reverse_iterator reverse_iterator;
  typedef typename map_type::const_reverse_iterator const_reverse_iterator;
  typedef typename map_type::difference_type difference_type;
  typedef typename map_type::size_type size_type;

  SharedMap() : map_(new map_type()) {}

  iterator begin() {
    return (*map_).begin();
  }

  const_iterator begin() const {
    return (*map_).begin();
  }

  iterator end() {
    return (*map_).end();
  }

  const_iterator end() const {
    return (*map_).end();
  }

  reverse_iterator rbegin() {
    return (*map_).rbegin();
  }

  const_reverse_iterator rbegin() const {
    return (*map_).rbegin();
  }

  reverse_iterator rend() {
    return (*map_).rend();
  }

  const_reverse_iterator rend() const {
    return (*map_).rend();
  }

  bool empty() const {
    return (*map_).empty();
  }

  size_type size() const {
    return (*map_).size();
  }

  size_type max_size() const {
    return (*map_).max_size();
  }

  mapped_type& operator[] (const key_type& k) {
    return (*map_)[k];
  }

  mapped_type& at(const key_type& k) {
    return (*map_).at(k);
  }

  const mapped_type& at(const key_type& k) const {
    return (*map_).at(k);
  }

  std::pair <iterator, bool> insert(const value_type& val) {
    return (*map_).insert(val);
  }

  iterator insert(iterator position, const value_type& val) {
    return (*map_).insert(position, val);
  }

  template <class InputIterator>
  void insert(InputIterator first, InputIterator last) {
    return (*map_).insert(first, last);
  }

  void erase(iterator position) {
    return (*map_).erase(position);
  }

  size_type erase(const key_type& k) {
    return (*map_).erase(k);
  }

  void erase(iterator first, iterator last) {
    return (*map_).erase(first, last);
  }

  void swap(map_type& x) {
    (*map_).swap(x);
  }

  void clear() {
    (*map_).clear();
  }

  key_compare key_comp() const {
    return (*map_).key_comp();
  }

  value_compare value_comp() const {
    return (*map_).value_comp();
  }

  iterator find(const key_type& k) {
    return (*map_).find(k);
  }

  const_iterator find(const key_type& k) const {
    return (*map_).find(k);
  }

  size_type count (const key_type& k) const {
    return (*map_).count(k);
  }

  iterator lower_bound(const key_type& k) {
    return (*map_).lower_bound(k);
  }

  const_iterator lower_bound(const key_type& k) const {
    return (*map_).lower_bound(k);
  }

  iterator upper_bound(const key_type& k) {
    return (*map_).upper_bound(k);
  }

  const_iterator upper_bound(const key_type& k) const {
    return (*map_).upper_bound(k);
  }

  std::pair <const_iterator, const_iterator>
  equal_range(const key_type& k) const {
    return (*map_).equal_range(k);
  }

  std::pair <iterator, iterator> equal_range(const key_type& k) {
    return (*map_).equal_range(k);
  }

  allocator_type get_allocator() const {
    return (*map_).get_allocator();
  }

private:

  boost::shared_ptr <map_type> map_;
};

template <class Key, class Value>
class MyMapBase : public SharedMap <Key, Value> {

public:

  typedef SharedMap <Key, Value> map_type;
  typedef typename SharedMap <Key, Value>::mapped_type mapped_type;
  typedef typename SharedMap <Key, Value>::key_type key_type;

private:

  mapped_type& at(const key_type& k) {
    return map_type::at(k);
  }

};

class MyMap : public MyMapBase <int, int> {

public:

  typedef MyMapBase <int, int> map_type;
  typedef typename map_type::const_iterator const_iterator;

  void print() const {
    for (const_iterator it = begin(); it != end(); ++it) {
      std::cout << it->first << " -> " << it->second << std::endl;
    }
  }
};

MyMap map_test(MyMap &map) {

  MyMap map2 = map;
  for (std::size_t i = 0; i < 10; ++i) {
    map2[i] = i;
  }

  return map2;
}

void map_print(const MyMap &map) {
  map.print();
}

void export_my_map() {
  class_<MyMap>("MyMap")
    .def(map_indexing_suite <MyMap> ());

  def("map_test", &map_test);
  def("map_print", &map_print);
}

}

}}
<commit_msg>Changed typedef typename -> typedef in non-template class<commit_after>#include <boost/python.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#include <scitbx/stl/map_wrapper.h>
#include <boost/shared_ptr.hpp>
#include <map>
#include <iostream>

namespace dials { namespace util {

namespace boost_python {

using namespace boost::python;

template <class Key, class T, class Compare = std::less <Key> >
class SharedMap {

public:

  typedef typename std::map <Key, T, Compare> map_type;
  typedef typename map_type::key_type key_type;
  typedef typename map_type::mapped_type mapped_type;
  typedef typename map_type::value_type value_type;
  typedef typename map_type::key_compare key_compare;
  typedef typename map_type::value_compare value_compare;
  typedef typename map_type::allocator_type allocator_type;
  typedef typename map_type::reference reference;
  typedef typename map_type::const_reference const_reference;
  typedef typename map_type::pointer pointer;
  typedef typename map_type::const_pointer const_pointer;
  typedef typename map_type::iterator iterator;
  typedef typename map_type::const_iterator const_iterator;
  typedef typename map_type::reverse_iterator reverse_iterator;
  typedef typename map_type::const_reverse_iterator const_reverse_iterator;
  typedef typename map_type::difference_type difference_type;
  typedef typename map_type::size_type size_type;

  SharedMap() : map_(new map_type()) {}

  iterator begin() {
    return (*map_).begin();
  }

  const_iterator begin() const {
    return (*map_).begin();
  }

  iterator end() {
    return (*map_).end();
  }

  const_iterator end() const {
    return (*map_).end();
  }

  reverse_iterator rbegin() {
    return (*map_).rbegin();
  }

  const_reverse_iterator rbegin() const {
    return (*map_).rbegin();
  }

  reverse_iterator rend() {
    return (*map_).rend();
  }

  const_reverse_iterator rend() const {
    return (*map_).rend();
  }

  bool empty() const {
    return (*map_).empty();
  }

  size_type size() const {
    return (*map_).size();
  }

  size_type max_size() const {
    return (*map_).max_size();
  }

  mapped_type& operator[] (const key_type& k) {
    return (*map_)[k];
  }

  mapped_type& at(const key_type& k) {
    return (*map_).at(k);
  }

  const mapped_type& at(const key_type& k) const {
    return (*map_).at(k);
  }

  std::pair <iterator, bool> insert(const value_type& val) {
    return (*map_).insert(val);
  }

  iterator insert(iterator position, const value_type& val) {
    return (*map_).insert(position, val);
  }

  template <class InputIterator>
  void insert(InputIterator first, InputIterator last) {
    return (*map_).insert(first, last);
  }

  void erase(iterator position) {
    return (*map_).erase(position);
  }

  size_type erase(const key_type& k) {
    return (*map_).erase(k);
  }

  void erase(iterator first, iterator last) {
    return (*map_).erase(first, last);
  }

  void swap(map_type& x) {
    (*map_).swap(x);
  }

  void clear() {
    (*map_).clear();
  }

  key_compare key_comp() const {
    return (*map_).key_comp();
  }

  value_compare value_comp() const {
    return (*map_).value_comp();
  }

  iterator find(const key_type& k) {
    return (*map_).find(k);
  }

  const_iterator find(const key_type& k) const {
    return (*map_).find(k);
  }

  size_type count (const key_type& k) const {
    return (*map_).count(k);
  }

  iterator lower_bound(const key_type& k) {
    return (*map_).lower_bound(k);
  }

  const_iterator lower_bound(const key_type& k) const {
    return (*map_).lower_bound(k);
  }

  iterator upper_bound(const key_type& k) {
    return (*map_).upper_bound(k);
  }

  const_iterator upper_bound(const key_type& k) const {
    return (*map_).upper_bound(k);
  }

  std::pair <const_iterator, const_iterator>
  equal_range(const key_type& k) const {
    return (*map_).equal_range(k);
  }

  std::pair <iterator, iterator> equal_range(const key_type& k) {
    return (*map_).equal_range(k);
  }

  allocator_type get_allocator() const {
    return (*map_).get_allocator();
  }

private:

  boost::shared_ptr <map_type> map_;
};

template <class Key, class Value>
class MyMapBase : public SharedMap <Key, Value> {

public:

  typedef SharedMap <Key, Value> map_type;
  typedef typename SharedMap <Key, Value>::mapped_type mapped_type;
  typedef typename SharedMap <Key, Value>::key_type key_type;

private:

  mapped_type& at(const key_type& k) {
    return map_type::at(k);
  }

};

class MyMap : public MyMapBase <int, int> {

public:

  typedef MyMapBase <int, int> map_type;
  typedef map_type::const_iterator const_iterator;

  void print() const {
    for (const_iterator it = begin(); it != end(); ++it) {
      std::cout << it->first << " -> " << it->second << std::endl;
    }
  }
};

MyMap map_test(MyMap &map) {

  MyMap map2 = map;
  for (std::size_t i = 0; i < 10; ++i) {
    map2[i] = i;
  }

  return map2;
}

void map_print(const MyMap &map) {
  map.print();
}

void export_my_map() {
  class_<MyMap>("MyMap")
    .def(map_indexing_suite <MyMap> ());

  def("map_test", &map_test);
  def("map_print", &map_print);
}

}

}}
<|endoftext|>