<commit_before>// System headers
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <ctime>
#include <iterator>
// --------------

#include "csv_data_manipulator.hpp"

// --- CONSTANTS --- //
const char *CSVData::VERSION = "v0.2a"; // XXX: Update version here
const char CSVData::CSV_DELIMITER = ',';
const char CSVData::C_STRING_DELIMITER = '"';
const char *CSVData::S_STRING_DELIMITER = "\"";
const char *CSVData::TMP_DELIM_REPLACEMENT = "#|#";
const char CSVData::DECIMAL_DELIMITER = '.';

const int CSVData::ASC = 1;
const int CSVData::DESC = 2;
// ----------------- //

using namespace std;

// ==========================================================================================================|

CSVData::CSVData() : m_is_modified(false), m_is_unified(true), m_rows(0), m_cols(0)
{
}

// ----------------------------------------------------------------------------------------------------------|

CSVData::CSVData(CSVData &rhs) :
    m_is_modified(rhs.is_modified()), m_is_unified(rhs.is_unified()),
    m_rows(rhs.m_rows), m_cols(rhs.m_cols)
{
}

// ----------------------------------------------------------------------------------------------------------|

CSVData::CSVData(const string &filename) :
    m_is_modified(false), m_is_unified(true), m_rows(0), m_cols(0)
{
    read_file(filename);
    m_is_modified = false;
}

// ----------------------------------------------------------------------------------------------------------|

const string CSVData::get_value(int row, int col)
{
     if (row >= m_rows || col >= m_cols || row < 0 || col < 0) return "";
     return const_cast<string&>(m_data.at(row).at(col));
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::set_value(int row, int col, string value)
{
     if (row >= m_rows || col >= m_cols || row < 0 || col < 0) return;

     m_data.at(row).at(col) = value;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::add_row(vector<string> row_data)
{
     size_t new_row_size = row_data.size();
     if (new_row_size != m_cols && m_is_unified) m_is_unified = false;
     m_data.push_back(row_data);
     m_rows++;
     if (m_cols < new_row_size) m_cols = new_row_size;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::add_row(vector<string> row_data, int pos)
{
     if (pos < 0 || pos >= m_data.size()) return;

     vector< vector<string> >::iterator it = m_data.begin() + pos;

     size_t new_row_size = row_data.size();
     if (new_row_size != m_cols && m_is_unified) m_is_unified = false;

     m_data.insert(it, row_data);
     m_rows++;
     if (m_cols < new_row_size) m_cols = new_row_size;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row(int row)
{
	if (row >= m_rows || row < 0) return;
	m_data.erase(m_data.begin() + row);
	m_rows--;
	m_is_modified = true;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row_if(function<bool(int, const std::vector< std::string > &, void *cbData)> cbFun,
        void *cbData)
{
    vector<int> rows_to_delete;

    for (int row = 0; row < m_data.size(); ++row) {
        if ( cbFun(row, m_data.at(row), cbData) ) {
            rows_to_delete.push_back(row);
        }
    }

    if (rows_to_delete.size() > 0) {
        sort(rows_to_delete.begin(), rows_to_delete.end(), std::greater<int>());
        for (int row = 0; row < rows_to_delete.size(); ++row) delete_row(rows_to_delete.at(row));
    }
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row_if(function<bool(int, int, const std::string&, void *cbData)> cbFun, void *cbData)
{
    vector<int> rows_to_delete;

    for (int row = 0; row < m_data.size(); ++row) {
        for (int col = 0; col < m_data.at(row).size(); ++col) {
            if ( cbFun(row, col, m_data.at(row).at(col), cbData) ) {
                rows_to_delete.push_back(row);
                break;
            }
        }
    }

    if (rows_to_delete.size() > 0) {
        sort(rows_to_delete.begin(), rows_to_delete.end(), std::greater<int>());
        for (int row = 0; row < rows_to_delete.size(); ++row) delete_row(rows_to_delete.at(row));
    }
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row_if(function<bool(int, int, const std::string&)> cbFun)
{
    function<bool(int, int, const std::string&, void *cbData)> simple_delete_row_if =
        [=](int row, int col, const std::string& val, void *cbData) {
            return cbFun(row, col, val);
        };

    delete_row_if(simple_delete_row_if, nullptr);
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_col(int col)
{
	if (col >= m_cols || col < 0) return;
	for (int i = 0; i < m_data.size(); ++i) {
		if (col < m_data.at(i).size()) {
			m_data.at(i).erase(m_data.at(i).begin() + col);
			m_is_modified = true;
		}
	}
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_item(int row, int col)
{
	if (row >= m_rows || row < 0) return;
	if (col >= m_data.at(row).size() || col < 0) return;

	m_data.at(row).erase(m_data.at(row).begin() + col);
	m_is_modified = true;
	m_is_unified = false;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::_append_data(std::vector< std::vector<std::string> > &data)
{
    if (data.empty()) return;

    if (m_data.empty()) {
        m_data = move(data);
    } else {
        m_data.reserve(m_data.size() + data.size());
        move(data.begin(), data.end(), back_inserter(m_data));
        data.clear();
    }
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::_read_file(const std::string &filename, std::vector< std::vector<std::string> > &target, int &cols)
{
    ifstream input_file(filename.c_str());

    if (!input_file.is_open()) {
        cerr << "Unable to open file '" << filename << "'. Check if file exists and if you have the right permissions." << endl;
        return;
    }

    string line;

    while (getline(input_file, line)) {
        int contains_strings = 0;
        if ( (contains_strings = count(line.begin(), line.end(), C_STRING_DELIMITER)) > 0 ) {
            size_t left = line.find(C_STRING_DELIMITER, 0);
            size_t right = line.find(C_STRING_DELIMITER, left + 1);

            while (left != string::npos && right != string::npos) {
                size_t found = left;
                while (true) {
                    found = line.find(C_STRING_DELIMITER, found);
                    if (found == string::npos) break;

                    line.replace(found, 1, TMP_DELIM_REPLACEMENT);
                    found += 3;
                }

                left = line.find(C_STRING_DELIMITER, right);
                right = line.find(C_STRING_DELIMITER, left + 1);
            }
        }

        stringstream ss(line);
        string tok, i_row;
        vector<string> row;

        while (getline(ss, tok, CSV_DELIMITER)) {
            if (tok.find(TMP_DELIM_REPLACEMENT) != string::npos) {
                i_row = tok;

                size_t found = 0;
                while (true) {
                    found = i_row.find(TMP_DELIM_REPLACEMENT, found);
                    if (found == string::npos) break;

                    i_row.replace(found, 3, string(S_STRING_DELIMITER));
                    found++;
                }
            } else {
                i_row = tok;
            }
            row.push_back(i_row);
        }

        if (cols != 0 && cols != row.size()) m_is_unified = false;

        cols = row.size();

        target.push_back(row);
    }

    input_file.close();
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::read_file(const string &filename)
{
    m_data.clear();

    _read_file(filename, m_data, m_cols);

    m_is_modified = true;
    m_rows = m_data.size();
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::append_file(const string &filename)
{
    std::vector< std::vector<std::string> > new_data;

    _read_file(filename, new_data, m_cols);
    _append_data(new_data);

    m_is_modified = true;
    m_rows = m_data.size();
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::write_data(const string &filename)
{
    ofstream output_file(filename.c_str(), ofstream::out);

    if (!output_file.is_open()) {
        cerr << "Unable to open file '" << filename << "'. Check if you have the right permissions." << endl;
        return;
    }

    for (int row = 0; row < m_data.size(); ++row) {
        string new_line;

        vector<string> row_data = m_data.at(row);
        for (int i = 0; i < row_data.size(); i++) {
            new_line.append(row_data.at(i));
            new_line.append(string(1, CSV_DELIMITER));
        }

        size_t last_comma = new_line.find_last_of(",");
        new_line.replace(last_comma, 1, "\n");

        output_file << new_line;
    }

    output_file.close();

    m_is_modified = false;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::convert_date_format(const std::string &old_format, const std::string &new_format, int column)
{
    for (int row = 0; row < m_data.size(); ++row) convert_date_format(old_format, new_format, row, column);
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::convert_date_format(const std::string &old_format, const std::string &new_format, int row, int column)
{
    if (column < 0 || column >= m_cols) {
        cerr << "Invalid column number: " << column << endl;
        return;
    }

    if (row < 0 || row >= m_rows) {
        cerr << "Invalid row number: " << row << endl;
        return;
    }

    vector<string> row_data = m_data.at(row);

    string old_date = row_data.at(column);
    std::tm od;
    strptime(old_date.c_str(), old_format.c_str(), &od);

    char buffer[256];
    strftime(buffer, sizeof(buffer), new_format.c_str(), &od);

    string new_date(buffer);

    m_data.at(row).at(column) = new_date;

    m_is_modified = true;
}

// ==========================================================================================================|

static bool is_digits(const string &str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit);
}

// ==========================================================================================================|

void CSVData::sort_by_col(int col, int order)
{
    auto acs_compare_fun = [&](const vector< string > &row1, const vector< string > &row2) {
        bool ret_val;

        if (is_digits(row1[col]) && is_digits(row2[col])) {
            auto a = (row1[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row1[col]) : stol(row1[col]);
            auto b = (row2[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row2[col]) : stol(row2[col]);
            ret_val = a < b;
        } else {
             ret_val = row1[col] < row2[col];
        }

        return ret_val;
    };

    auto desc_compare_fun = [&](const vector< string > &row1, const vector< string > &row2) {
        bool ret_val;

        if (is_digits(row1[col]) && is_digits(row2[col])) {
            auto a = (row1[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row1[col]) : stol(row1[col]);
            auto b = (row2[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row2[col]) : stol(row2[col]);
            ret_val = a > b;
        } else {
             ret_val = row1[col] > row2[col];
        }

        return ret_val;
    };

    switch (order) {
        case DESC:
            sort(m_data.begin(), m_data.end(), desc_compare_fun);
            break;
        case ASC:
        default:
            sort(m_data.begin(), m_data.end(), acs_compare_fun);
            break;
    }

    m_is_modified = true;
}

// ==========================================================================================================|

void CSVData::make_data_unique()
{
    if (!m_is_unified) {
        cout << "Data are not unified. Cannot check all the data." << endl;
        return;
    }

    for (int col = 0; col < m_cols; col++) {
        sort_by_col(col, ASC);
        m_data.erase(unique(m_data.begin(), m_data.end()), m_data.end());
    }
}

// ==========================================================================================================|
<commit_msg>Support both LF and CR Note: CRLF not testet yet...<commit_after>// System headers
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <ctime>
#include <iterator>
// --------------

#include "csv_data_manipulator.hpp"

// --- CONSTANTS --- //
const char *CSVData::VERSION = "v0.2a"; // XXX: Update version here
const char CSVData::CSV_DELIMITER = ',';
const char CSVData::C_STRING_DELIMITER = '"';
const char *CSVData::S_STRING_DELIMITER = "\"";
const char *CSVData::TMP_DELIM_REPLACEMENT = "#|#";
const char CSVData::DECIMAL_DELIMITER = '.';

const int CSVData::ASC = 1;
const int CSVData::DESC = 2;
// ----------------- //

using namespace std;

// ==========================================================================================================|

bool os_safe_getline(istream &is, string &s)
{
    s.clear();

    char c;

    while (is.get(c)) {
        if (is.eof()) {
            return false;
        } else if (c == '\n' || c == '\r') {
            return true;
        } else {
            s += c;
        }
    }
}

// ==========================================================================================================|

CSVData::CSVData() : m_is_modified(false), m_is_unified(true), m_rows(0), m_cols(0)
{
}

// ----------------------------------------------------------------------------------------------------------|

CSVData::CSVData(CSVData &rhs) :
    m_is_modified(rhs.is_modified()), m_is_unified(rhs.is_unified()),
    m_rows(rhs.m_rows), m_cols(rhs.m_cols)
{
}

// ----------------------------------------------------------------------------------------------------------|

CSVData::CSVData(const string &filename) :
    m_is_modified(false), m_is_unified(true), m_rows(0), m_cols(0)
{
    read_file(filename);
    m_is_modified = false;
}

// ----------------------------------------------------------------------------------------------------------|

const string CSVData::get_value(int row, int col)
{
     if (row >= m_rows || col >= m_cols || row < 0 || col < 0) return "";
     return const_cast<string&>(m_data.at(row).at(col));
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::set_value(int row, int col, string value)
{
     if (row >= m_rows || col >= m_cols || row < 0 || col < 0) return;

     m_data.at(row).at(col) = value;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::add_row(vector<string> row_data)
{
     size_t new_row_size = row_data.size();
     if (new_row_size != m_cols && m_is_unified) m_is_unified = false;
     m_data.push_back(row_data);
     m_rows++;
     if (m_cols < new_row_size) m_cols = new_row_size;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::add_row(vector<string> row_data, int pos)
{
     if (pos < 0 || pos >= m_data.size()) return;

     vector< vector<string> >::iterator it = m_data.begin() + pos;

     size_t new_row_size = row_data.size();
     if (new_row_size != m_cols && m_is_unified) m_is_unified = false;

     m_data.insert(it, row_data);
     m_rows++;
     if (m_cols < new_row_size) m_cols = new_row_size;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row(int row)
{
	if (row >= m_rows || row < 0) return;
	m_data.erase(m_data.begin() + row);
	m_rows--;
	m_is_modified = true;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row_if(function<bool(int, const std::vector< std::string > &, void *cbData)> cbFun,
        void *cbData)
{
    vector<int> rows_to_delete;

    for (int row = 0; row < m_data.size(); ++row) {
        if ( cbFun(row, m_data.at(row), cbData) ) {
            rows_to_delete.push_back(row);
        }
    }

    if (rows_to_delete.size() > 0) {
        sort(rows_to_delete.begin(), rows_to_delete.end(), std::greater<int>());
        for (int row = 0; row < rows_to_delete.size(); ++row) delete_row(rows_to_delete.at(row));
    }
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row_if(function<bool(int, int, const std::string&, void *cbData)> cbFun, void *cbData)
{
    vector<int> rows_to_delete;

    for (int row = 0; row < m_data.size(); ++row) {
        for (int col = 0; col < m_data.at(row).size(); ++col) {
            if ( cbFun(row, col, m_data.at(row).at(col), cbData) ) {
                rows_to_delete.push_back(row);
                break;
            }
        }
    }

    if (rows_to_delete.size() > 0) {
        sort(rows_to_delete.begin(), rows_to_delete.end(), std::greater<int>());
        for (int row = 0; row < rows_to_delete.size(); ++row) delete_row(rows_to_delete.at(row));
    }
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_row_if(function<bool(int, int, const std::string&)> cbFun)
{
    function<bool(int, int, const std::string&, void *cbData)> simple_delete_row_if =
        [=](int row, int col, const std::string& val, void *cbData) {
            return cbFun(row, col, val);
        };

    delete_row_if(simple_delete_row_if, nullptr);
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_col(int col)
{
	if (col >= m_cols || col < 0) return;
	for (int i = 0; i < m_data.size(); ++i) {
		if (col < m_data.at(i).size()) {
			m_data.at(i).erase(m_data.at(i).begin() + col);
			m_is_modified = true;
		}
	}
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::delete_item(int row, int col)
{
	if (row >= m_rows || row < 0) return;
	if (col >= m_data.at(row).size() || col < 0) return;

	m_data.at(row).erase(m_data.at(row).begin() + col);
	m_is_modified = true;
	m_is_unified = false;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::_append_data(std::vector< std::vector<std::string> > &data)
{
    if (data.empty()) return;

    if (m_data.empty()) {
        m_data = move(data);
    } else {
        m_data.reserve(m_data.size() + data.size());
        move(data.begin(), data.end(), back_inserter(m_data));
        data.clear();
    }
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::_read_file(const std::string &filename, std::vector< std::vector<std::string> > &target, int &cols)
{
    ifstream input_file(filename.c_str());

    if (!input_file.is_open()) {
        cerr << "Unable to open file '" << filename << "'. Check if file exists and if you have the right permissions." << endl;
        return;
    }

    string line;

    while (os_safe_getline(input_file, line)) {
        int contains_strings = 0;
        if ( (contains_strings = count(line.begin(), line.end(), C_STRING_DELIMITER)) > 0 ) {
            size_t left = line.find(C_STRING_DELIMITER, 0);
            size_t right = line.find(C_STRING_DELIMITER, left + 1);

            while (left != string::npos && right != string::npos) {
                size_t found = left;
                while (true) {
                    found = line.find(C_STRING_DELIMITER, found);
                    if (found == string::npos) break;

                    line.replace(found, 1, TMP_DELIM_REPLACEMENT);
                    found += 3;
                }

                left = line.find(C_STRING_DELIMITER, right);
                right = line.find(C_STRING_DELIMITER, left + 1);
            }
        }

        stringstream ss(line);
        string tok, i_row;
        vector<string> row;

        while (getline(ss, tok, CSV_DELIMITER)) {
            if (tok.find(TMP_DELIM_REPLACEMENT) != string::npos) {
                i_row = tok;

                size_t found = 0;
                while (true) {
                    found = i_row.find(TMP_DELIM_REPLACEMENT, found);
                    if (found == string::npos) break;

                    i_row.replace(found, 3, string(S_STRING_DELIMITER));
                    found++;
                }
            } else {
                i_row = tok;
            }
            row.push_back(i_row);
        }

        if (cols != 0 && cols != row.size()) m_is_unified = false;

        cols = row.size();

        target.push_back(row);
    }

    input_file.close();
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::read_file(const string &filename)
{
    m_data.clear();

    _read_file(filename, m_data, m_cols);

    m_is_modified = true;
    m_rows = m_data.size();
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::append_file(const string &filename)
{
    std::vector< std::vector<std::string> > new_data;

    _read_file(filename, new_data, m_cols);
    _append_data(new_data);

    m_is_modified = true;
    m_rows = m_data.size();
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::write_data(const string &filename)
{
    ofstream output_file(filename.c_str(), ofstream::out);

    if (!output_file.is_open()) {
        cerr << "Unable to open file '" << filename << "'. Check if you have the right permissions." << endl;
        return;
    }

    for (int row = 0; row < m_data.size(); ++row) {
        string new_line;

        vector<string> row_data = m_data.at(row);
        for (int i = 0; i < row_data.size(); i++) {
            new_line.append(row_data.at(i));
            new_line.append(string(1, CSV_DELIMITER));
        }

        size_t last_comma = new_line.find_last_of(",");
        new_line.replace(last_comma, 1, "\n");

        output_file << new_line;
    }

    output_file.close();

    m_is_modified = false;
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::convert_date_format(const std::string &old_format, const std::string &new_format, int column)
{
    for (int row = 0; row < m_data.size(); ++row) convert_date_format(old_format, new_format, row, column);
}

// ----------------------------------------------------------------------------------------------------------|

void CSVData::convert_date_format(const std::string &old_format, const std::string &new_format, int row, int column)
{
    if (column < 0 || column >= m_cols) {
        cerr << "Invalid column number: " << column << endl;
        return;
    }

    if (row < 0 || row >= m_rows) {
        cerr << "Invalid row number: " << row << endl;
        return;
    }

    vector<string> row_data = m_data.at(row);

    string old_date = row_data.at(column);
    std::tm od;
    strptime(old_date.c_str(), old_format.c_str(), &od);

    char buffer[256];
    strftime(buffer, sizeof(buffer), new_format.c_str(), &od);

    string new_date(buffer);

    m_data.at(row).at(column) = new_date;

    m_is_modified = true;
}

// ==========================================================================================================|

static bool is_digits(const string &str)
{
    return std::all_of(str.begin(), str.end(), ::isdigit);
}

// ==========================================================================================================|

void CSVData::sort_by_col(int col, int order)
{
    auto acs_compare_fun = [&](const vector< string > &row1, const vector< string > &row2) {
        bool ret_val;

        if (is_digits(row1[col]) && is_digits(row2[col])) {
            auto a = (row1[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row1[col]) : stol(row1[col]);
            auto b = (row2[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row2[col]) : stol(row2[col]);
            ret_val = a < b;
        } else {
             ret_val = row1[col] < row2[col];
        }

        return ret_val;
    };

    auto desc_compare_fun = [&](const vector< string > &row1, const vector< string > &row2) {
        bool ret_val;

        if (is_digits(row1[col]) && is_digits(row2[col])) {
            auto a = (row1[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row1[col]) : stol(row1[col]);
            auto b = (row2[col].find(DECIMAL_DELIMITER) != string::npos) ? stod(row2[col]) : stol(row2[col]);
            ret_val = a > b;
        } else {
             ret_val = row1[col] > row2[col];
        }

        return ret_val;
    };

    switch (order) {
        case DESC:
            sort(m_data.begin(), m_data.end(), desc_compare_fun);
            break;
        case ASC:
        default:
            sort(m_data.begin(), m_data.end(), acs_compare_fun);
            break;
    }

    m_is_modified = true;
}

// ==========================================================================================================|

void CSVData::make_data_unique()
{
    if (!m_is_unified) {
        cout << "Data are not unified. Cannot check all the data." << endl;
        return;
    }

    for (int col = 0; col < m_cols; col++) {
        sort_by_col(col, ASC);
        m_data.erase(unique(m_data.begin(), m_data.end()), m_data.end());
    }
}

// ==========================================================================================================|
<|endoftext|>


<commit_before>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "ptref_graph.h"
#include "ptreferential.h"
#include <boost/graph/dijkstra_shortest_paths.hpp>

namespace navitia { namespace ptref {

/** Contient le graph des transitions
 *
 * Un arc (u,v) entre les entités u et v, veut dire que l'on peut
 * obtenir U à partir de V
 *
 * Cela peut sembler contre-intuitif, mais cela permet de ne faire qu'un
 * seul appel à Dijkstra pour avoir tout ce qui nous interesse
 */

Jointures::Jointures() {
#define VERTEX_MAP(type_name, collection_name) vertex_map[Type_e::type_name] = boost::add_vertex(Type_e::type_name, g);
    ITERATE_NAVITIA_PT_TYPES(VERTEX_MAP)
    vertex_map[Type_e::JourneyPattern] = boost::add_vertex(Type_e::JourneyPattern, g);
    vertex_map[Type_e::JourneyPatternPoint] = boost::add_vertex(Type_e::JourneyPatternPoint, g);
    vertex_map[Type_e::POI] = boost::add_vertex(Type_e::POI, g);
    vertex_map[Type_e::POIType] = boost::add_vertex(Type_e::POIType, g);
    vertex_map[Type_e::Connection] = boost::add_vertex(Type_e::Connection, g);
    vertex_map[Type_e::Impact] = boost::add_vertex(Type_e::Impact, g);
    vertex_map[Type_e::MetaVehicleJourney] = boost::add_vertex(Type_e::MetaVehicleJourney, g);

    // From a StopArea, we can have its StopPoints.
    boost::add_edge(vertex_map.at(Type_e::StopPoint), vertex_map.at(Type_e::StopArea), g);

    // From a Network, we can have its Lines.
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::Network), g);

    // From a Company, we can have its Lines.
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::Company), g);

    // From a CommercialMode, we can have its Lines.
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::CommercialMode), g);

    // À partir d'un physical mode on peut avoir les vehicule journeys
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::PhysicalMode), g);

    // À partir d'une ligne on peut avoir ses modes commerciaux, compagnies, réseaux et routes
    boost::add_edge(vertex_map.at(Type_e::CommercialMode), vertex_map.at(Type_e::Line), g);
    boost::add_edge(vertex_map.at(Type_e::Company), vertex_map.at(Type_e::Line), g);
    boost::add_edge(vertex_map.at(Type_e::Network), vertex_map.at(Type_e::Line), g);
    boost::add_edge(vertex_map.at(Type_e::Route), vertex_map.at(Type_e::Line), g);

    // À partir d'une route on a sa ligne et ses journey pattern
    boost::add_edge(vertex_map.at(Type_e::JourneyPattern), vertex_map.at(Type_e::Route), g);
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::Route), g);
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::Route), g);

    // À partir d'un journey pattern on peut avoir sa route, ses points et son vehicule journey
    boost::add_edge(vertex_map.at(Type_e::Route), vertex_map.at(Type_e::JourneyPattern), g);
    boost::add_edge(vertex_map.at(Type_e::JourneyPatternPoint), vertex_map.at(Type_e::JourneyPattern), g);
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::JourneyPattern), g);

    // from a VehicleJourney, we can have the Route, the
    // JourneyPattern, the Company, the PhysicalMode, the
    // ValidityPattern, the MetaVehicleJourney, the Dataset
    boost::add_edge(vertex_map.at(Type_e::Route), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::JourneyPattern), vertex_map.at(Type_e::VehicleJourney), g);
    // Higher weight on the Company to get Route->Line better than Company->Line.
    boost::add_edge(vertex_map.at(Type_e::Company), vertex_map.at(Type_e::VehicleJourney), Edge(2.5), g);
    boost::add_edge(vertex_map.at(Type_e::PhysicalMode), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::ValidityPattern), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::MetaVehicleJourney), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::Dataset), vertex_map.at(Type_e::VehicleJourney), g);

    // From a JourneyPatternPoint, we can have the JourneyPattern and
    // the StopPoints.
    boost::add_edge(vertex_map.at(Type_e::JourneyPattern), vertex_map.at(Type_e::JourneyPatternPoint), g);
    boost::add_edge(vertex_map.at(Type_e::StopPoint), vertex_map.at(Type_e::JourneyPatternPoint), g);

    // From a StopPoint, we can have its StopArea, Its
    // JourneyPatternPoints and its Connection.
    boost::add_edge(vertex_map.at(Type_e::StopArea), vertex_map.at(Type_e::StopPoint), g);
    boost::add_edge(vertex_map.at(Type_e::JourneyPatternPoint), vertex_map.at(Type_e::StopPoint), g);
    boost::add_edge(vertex_map.at(Type_e::Connection), vertex_map.at(Type_e::StopPoint), g);

    // D'une connection on a ses deux stop points
    boost::add_edge(vertex_map[Type_e::StopPoint], vertex_map[Type_e::Connection], g);

    //De poi vers poi type et vice et versa
    boost::add_edge(vertex_map[Type_e::POI], vertex_map[Type_e::POIType], g);
    boost::add_edge(vertex_map[Type_e::POIType], vertex_map[Type_e::POI], g);

    //from line to calendar
    boost::add_edge(vertex_map[Type_e::Calendar], vertex_map[Type_e::Line], g);
    boost::add_edge(vertex_map[Type_e::Line], vertex_map[Type_e::Calendar], g);

    // from line_group to lines
    boost::add_edge(vertex_map[Type_e::LineGroup], vertex_map[Type_e::Line], g);
    boost::add_edge(vertex_map[Type_e::Line], vertex_map[Type_e::LineGroup], g);

    // From a MetaVehicleJourney, we can have its VehicleJourneys.
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::MetaVehicleJourney), g);

    // From a dataset we can have a contributor and vehiclejourneys
    boost::add_edge(vertex_map.at(Type_e::Contributor), vertex_map.at(Type_e::Dataset), g);
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::Dataset), g);

    // From a contributor we can have datasets
    boost::add_edge(vertex_map.at(Type_e::Dataset), vertex_map.at(Type_e::Contributor), g);

    // edges for the impacts. for the moment we only need unilateral links,
    // we don't need from an impact all the impacted objects
    const auto objects_having_impacts = {Type_e::StopPoint, Type_e::Line, Type_e::Route, Type_e::StopArea,
            Type_e::Network, Type_e::VehicleJourney, Type_e::MetaVehicleJourney};
    for (auto object: objects_having_impacts) {
        boost::add_edge(vertex_map.at(Type_e::Impact), vertex_map.at(object), g);
    }
}

// Retourne un map qui indique pour chaque type par quel type on peut l'atteindre
// Si le prédécesseur est égal au type, c'est qu'il n'y a pas de chemin
std::map<Type_e,Type_e> find_path(Type_e source) {
    Jointures j;
    if(j.vertex_map.find(source) == j.vertex_map.end()){
        throw ptref_error("Type doesnot exist as a vertex");
    }

    std::vector<Jointures::vertex_t> predecessors(boost::num_vertices(j.g));
    boost::dijkstra_shortest_paths(j.g, j.vertex_map[source],
                                   boost::predecessor_map(&predecessors[0]).
                                   weight_map(boost::get(&Edge::weight, j.g)));

    std::map<Type_e, Type_e> result;

    for(Jointures::vertex_t u = 0; u < boost::num_vertices(j.g); ++u)
        result[j.g[u]] = j.g[predecessors[u]];
    return result;
}

} } //namespace navitia::ptref
<commit_msg>krake: route, stop_point and frame added in graph<commit_after>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "ptref_graph.h"
#include "ptreferential.h"
#include <boost/graph/dijkstra_shortest_paths.hpp>

namespace navitia { namespace ptref {

/** Contient le graph des transitions
 *
 * Un arc (u,v) entre les entités u et v, veut dire que l'on peut
 * obtenir U à partir de V
 *
 * Cela peut sembler contre-intuitif, mais cela permet de ne faire qu'un
 * seul appel à Dijkstra pour avoir tout ce qui nous interesse
 */

Jointures::Jointures() {
#define VERTEX_MAP(type_name, collection_name) vertex_map[Type_e::type_name] = boost::add_vertex(Type_e::type_name, g);
    ITERATE_NAVITIA_PT_TYPES(VERTEX_MAP)
    vertex_map[Type_e::JourneyPattern] = boost::add_vertex(Type_e::JourneyPattern, g);
    vertex_map[Type_e::JourneyPatternPoint] = boost::add_vertex(Type_e::JourneyPatternPoint, g);
    vertex_map[Type_e::POI] = boost::add_vertex(Type_e::POI, g);
    vertex_map[Type_e::POIType] = boost::add_vertex(Type_e::POIType, g);
    vertex_map[Type_e::Connection] = boost::add_vertex(Type_e::Connection, g);
    vertex_map[Type_e::Impact] = boost::add_vertex(Type_e::Impact, g);
    vertex_map[Type_e::MetaVehicleJourney] = boost::add_vertex(Type_e::MetaVehicleJourney, g);

    // From a StopArea, we can have its StopPoints.
    boost::add_edge(vertex_map.at(Type_e::StopPoint), vertex_map.at(Type_e::StopArea), g);

    // From a Network, we can have its Lines.
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::Network), g);

    // From a Company, we can have its Lines.
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::Company), g);

    // From a CommercialMode, we can have its Lines.
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::CommercialMode), g);

    // À partir d'un physical mode on peut avoir les vehicule journeys
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::PhysicalMode), g);

    // À partir d'une ligne on peut avoir ses modes commerciaux, compagnies, réseaux et routes
    boost::add_edge(vertex_map.at(Type_e::CommercialMode), vertex_map.at(Type_e::Line), g);
    boost::add_edge(vertex_map.at(Type_e::Company), vertex_map.at(Type_e::Line), g);
    boost::add_edge(vertex_map.at(Type_e::Network), vertex_map.at(Type_e::Line), g);
    boost::add_edge(vertex_map.at(Type_e::Route), vertex_map.at(Type_e::Line), g);

    // À partir d'une route on a sa ligne et ses journey pattern
    boost::add_edge(vertex_map.at(Type_e::JourneyPattern), vertex_map.at(Type_e::Route), g);
    boost::add_edge(vertex_map.at(Type_e::Line), vertex_map.at(Type_e::Route), g);
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::Route), g);

    // À partir d'un journey pattern on peut avoir sa route, ses points et son vehicule journey
    boost::add_edge(vertex_map.at(Type_e::Route), vertex_map.at(Type_e::JourneyPattern), g);
    boost::add_edge(vertex_map.at(Type_e::JourneyPatternPoint), vertex_map.at(Type_e::JourneyPattern), g);
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::JourneyPattern), g);

    // from a VehicleJourney, we can have the Route, the
    // JourneyPattern, the Company, the PhysicalMode, the
    // ValidityPattern, the MetaVehicleJourney, the Dataset
    boost::add_edge(vertex_map.at(Type_e::Route), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::JourneyPattern), vertex_map.at(Type_e::VehicleJourney), g);
    // Higher weight on the Company to get Route->Line better than Company->Line.
    boost::add_edge(vertex_map.at(Type_e::Company), vertex_map.at(Type_e::VehicleJourney), Edge(2.5), g);
    boost::add_edge(vertex_map.at(Type_e::PhysicalMode), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::ValidityPattern), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::MetaVehicleJourney), vertex_map.at(Type_e::VehicleJourney), g);
    boost::add_edge(vertex_map.at(Type_e::Dataset), vertex_map.at(Type_e::VehicleJourney), g);

    // From a JourneyPatternPoint, we can have the JourneyPattern and
    // the StopPoints.
    boost::add_edge(vertex_map.at(Type_e::JourneyPattern), vertex_map.at(Type_e::JourneyPatternPoint), g);
    boost::add_edge(vertex_map.at(Type_e::StopPoint), vertex_map.at(Type_e::JourneyPatternPoint), g);

    // From a StopPoint, we can have its StopArea, Its
    // JourneyPatternPoints and its Connection.
    boost::add_edge(vertex_map.at(Type_e::StopArea), vertex_map.at(Type_e::StopPoint), g);
    boost::add_edge(vertex_map.at(Type_e::JourneyPatternPoint), vertex_map.at(Type_e::StopPoint), g);
    boost::add_edge(vertex_map.at(Type_e::Connection), vertex_map.at(Type_e::StopPoint), g);

    // D'une connection on a ses deux stop points
    boost::add_edge(vertex_map[Type_e::StopPoint], vertex_map[Type_e::Connection], g);

    //De poi vers poi type et vice et versa
    boost::add_edge(vertex_map[Type_e::POI], vertex_map[Type_e::POIType], g);
    boost::add_edge(vertex_map[Type_e::POIType], vertex_map[Type_e::POI], g);

    //from line to calendar
    boost::add_edge(vertex_map[Type_e::Calendar], vertex_map[Type_e::Line], g);
    boost::add_edge(vertex_map[Type_e::Line], vertex_map[Type_e::Calendar], g);

    // from line_group to lines
    boost::add_edge(vertex_map[Type_e::LineGroup], vertex_map[Type_e::Line], g);
    boost::add_edge(vertex_map[Type_e::Line], vertex_map[Type_e::LineGroup], g);

    // From a MetaVehicleJourney, we can have its VehicleJourneys.
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::MetaVehicleJourney), g);

    // From a dataset we can have a contributor and vehiclejourneys
    boost::add_edge(vertex_map.at(Type_e::Contributor), vertex_map.at(Type_e::Dataset), g);
    boost::add_edge(vertex_map.at(Type_e::VehicleJourney), vertex_map.at(Type_e::Dataset), g);

    // From a contributor we can have datasets
    boost::add_edge(vertex_map.at(Type_e::Dataset), vertex_map.at(Type_e::Contributor), g);

    // From a Route we can have frames
    boost::add_edge(vertex_map.at(Type_e::Frame), vertex_map.at(Type_e::Route), Edge(2), g);
    // From a StopPoint we can have frames
    boost::add_edge(vertex_map.at(Type_e::Frame), vertex_map.at(Type_e::StopPoint), Edge(3), g);

    // edges for the impacts. for the moment we only need unilateral links,
    // we don't need from an impact all the impacted objects
    const auto objects_having_impacts = {Type_e::StopPoint, Type_e::Line, Type_e::Route, Type_e::StopArea,
            Type_e::Network, Type_e::VehicleJourney, Type_e::MetaVehicleJourney};
    for (auto object: objects_having_impacts) {
        boost::add_edge(vertex_map.at(Type_e::Impact), vertex_map.at(object), g);
    }
}

// Retourne un map qui indique pour chaque type par quel type on peut l'atteindre
// Si le prédécesseur est égal au type, c'est qu'il n'y a pas de chemin
std::map<Type_e,Type_e> find_path(Type_e source) {
    Jointures j;
    if(j.vertex_map.find(source) == j.vertex_map.end()){
        throw ptref_error("Type doesnot exist as a vertex");
    }

    std::vector<Jointures::vertex_t> predecessors(boost::num_vertices(j.g));
    boost::dijkstra_shortest_paths(j.g, j.vertex_map[source],
                                   boost::predecessor_map(&predecessors[0]).
                                   weight_map(boost::get(&Edge::weight, j.g)));

    std::map<Type_e, Type_e> result;

    for(Jointures::vertex_t u = 0; u < boost::num_vertices(j.g); ++u)
        result[j.g[u]] = j.g[predecessors[u]];
    return result;
}

} } //namespace navitia::ptref
<|endoftext|>


<commit_before>// arbitrary_precision_pi.cpp: generating a 'perfect' approximation of pi for a given number system
//
// Copyright (C) 2017-2020 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

// Configure the posit library with arithmetic exceptions
// enable posit arithmetic exceptions
#define POSIT_THROW_ARITHMETIC_EXCEPTION 1
#include <universal/posit/posit>

/*

Mathematical 	C++ Symbol	Decimal Representation
Expression
pi				M_PI		3.14159265358979323846
pi/2			M_PI_2		1.57079632679489661923
pi/4			M_PI_4		0.785398163397448309616
1/pi			M_1_PI		0.318309886183790671538
2/pi			M_2_PI		0.636619772367581343076
2/sqrt(pi)		M_2_SQRTPI	1.12837916709551257390
sqrt(2)			M_SQRT2		1.41421356237309504880
1/sqrt(2)		M_SQRT1_2	0.707106781186547524401
e				M_E			2.71828182845904523536
log_2(e)		M_LOG2E		1.44269504088896340736
log_10(e)		M_LOG10E	0.434294481903251827651
log_e(2)		M_LN2		0.693147180559945309417
log_e(10)		M_LN10		2.30258509299404568402

*/

constexpr double pi = 3.14159265358979323846;  // best practice for C++

// first 1000 digits of pi
static std::string pi1000 = "3.\
14159265358979323846264338327950288419716939937510\
58209749445923078164062862089986280348253421170679\
82148086513282306647093844609550582231725359408128\
48111745028410270193852110555964462294895493038196\
44288109756659334461284756482337867831652712019091\
45648566923460348610454326648213393607260249141273\
72458700660631558817488152092096282925409171536436\
78925903600113305305488204665213841469519415116094\
33057270365759591953092186117381932611793105118548\
07446237996274956735188575272489122793818301194912\
98336733624406566430860213949463952247371907021798\
60943702770539217176293176752384674818467669405132\
00056812714526356082778577134275778960917363717872\
14684409012249534301465495853710507922796892589235\
42019956112129021960864034418159813629774771309960\
51870721134999999837297804995105973173281609631859\
50244594553469083026425223082533446850352619311881\
71010003137838752886587533208381420617177669147303\
59825349042875546873115956286388235378759375195778\
18577805321712268066130019278766111959092164201989";

int main(int argc, char** argv)
try {
	using namespace std;
	using namespace sw::unum;

	int nrOfFailedTestCases = 0;

	cout << "Perfect approximations of PI for different number systems" << endl;

	cout << pi1000 << endl;

	// 1000 digits -> 1.e1000 -> 2^3322 -> 1.051103774764883380737596422798e+1000 -> you will need 3322 bits to represent 1000 digits of pi

	return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
catch (char const* msg) {
	std::cerr << msg << std::endl;
	return EXIT_FAILURE;
}
catch (const posit_arithmetic_exception& err) {
	std::cerr << "Uncaught posit arithmetic exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (const quire_exception& err) {
	std::cerr << "Uncaught quire exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (const posit_internal_exception& err) {
	std::cerr << "Uncaught posit internal exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (const std::runtime_error& err) {
	std::cerr << "Uncaught runtime exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (...) {
	std::cerr << "Caught unknown exception" << std::endl;
	return EXIT_FAILURE;
}
<commit_msg>Viete Series for pi<commit_after>// arbitrary_precision_pi.cpp: generating a 'perfect' approximation of pi for a given number system
//
// Copyright (C) 2017-2020 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

// Configure the posit library with arithmetic exceptions
// enable posit arithmetic exceptions
#define POSIT_THROW_ARITHMETIC_EXCEPTION 1
#include <universal/posit/posit>

/*

Mathematical 	C++ Symbol	Decimal Representation
Expression
pi				M_PI		3.14159265358979323846
pi/2			M_PI_2		1.57079632679489661923
pi/4			M_PI_4		0.785398163397448309616
1/pi			M_1_PI		0.318309886183790671538
2/pi			M_2_PI		0.636619772367581343076
2/sqrt(pi)		M_2_SQRTPI	1.12837916709551257390
sqrt(2)			M_SQRT2		1.41421356237309504880
1/sqrt(2)		M_SQRT1_2	0.707106781186547524401
e				M_E			2.71828182845904523536
log_2(e)		M_LOG2E		1.44269504088896340736
log_10(e)		M_LOG10E	0.434294481903251827651
log_e(2)		M_LN2		0.693147180559945309417
log_e(10)		M_LN10		2.30258509299404568402

*/

constexpr double pi = 3.14159265358979323846;  // best practice for C++

// first 1000 digits of pi
static std::string pi1000 = "3.\
14159265358979323846264338327950288419716939937510\
58209749445923078164062862089986280348253421170679\
82148086513282306647093844609550582231725359408128\
48111745028410270193852110555964462294895493038196\
44288109756659334461284756482337867831652712019091\
45648566923460348610454326648213393607260249141273\
72458700660631558817488152092096282925409171536436\
78925903600113305305488204665213841469519415116094\
33057270365759591953092186117381932611793105118548\
07446237996274956735188575272489122793818301194912\
98336733624406566430860213949463952247371907021798\
60943702770539217176293176752384674818467669405132\
00056812714526356082778577134275778960917363717872\
14684409012249534301465495853710507922796892589235\
42019956112129021960864034418159813629774771309960\
51870721134999999837297804995105973173281609631859\
50244594553469083026425223082533446850352619311881\
71010003137838752886587533208381420617177669147303\
59825349042875546873115956286388235378759375195778\
18577805321712268066130019278766111959092164201989";

template<typename Real>
Real MethodOfViete(uint32_t N) {
	using namespace sw::unum;
	Real pi = Real(1);
	for (size_t i = N; i > 1; --i) {
		Real repeatingFactor = Real(2);
		for (size_t j = 1; j < i; ++j) {
			repeatingFactor = Real(2) + sqrt(repeatingFactor);
		}
		repeatingFactor = sqrt(repeatingFactor);
		pi = pi * repeatingFactor / Real(2);
	}
	pi *= sqrt(Real(2)) / Real(2);
	pi = Real(2) / pi;
	return pi;
}

int main(int argc, char** argv)
try {
	using namespace std;
	using namespace sw::unum;

	int nrOfFailedTestCases = 0;

	cout << "Perfect approximations of PI for different number systems" << endl;

	cout << pi1000 << endl;

	using Real = double;
	cout << "Viete Series" << endl; // doesn't really work for floats as rounding error accumulates to quickly
	cout << "pi  = " << setprecision(20) << MethodOfViete<float>(50) << endl;
	cout << "pi  = " << setprecision(20) << MethodOfViete<double>(500) << endl;
	cout << "ref = " << setprecision(20) << pi << endl;

	// 1000 digits -> 1.e1000 -> 2^3322 -> 1.051103774764883380737596422798e+1000 -> you will need 3322 bits to represent 1000 digits of pi

	return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
catch (char const* msg) {
	std::cerr << msg << std::endl;
	return EXIT_FAILURE;
}
catch (const posit_arithmetic_exception& err) {
	std::cerr << "Uncaught posit arithmetic exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (const quire_exception& err) {
	std::cerr << "Uncaught quire exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (const posit_internal_exception& err) {
	std::cerr << "Uncaught posit internal exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (const std::runtime_error& err) {
	std::cerr << "Uncaught runtime exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (...) {
	std::cerr << "Caught unknown exception" << std::endl;
	return EXIT_FAILURE;
}
<|endoftext|>


<commit_before><commit_msg>Fixed NEON dotProduct<commit_after><|endoftext|>


<commit_before>/**
 * @file gamestate.hpp
 * @author Robin Dietrich <me (at) invokr (dot) org>
 * @version 1.0
 *
 * @par License
 *    Alice Replay Parser
 *    Copyright 2014 Robin Dietrich
 *
 *    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 _DOTA_GAMESTATE_HPP_
#define _DOTA_GAMESTATE_HPP_

#include <string>
#include <memory>
#include <vector>
#include <set>

#include <alice/demo.pb.h>
#include <alice/netmessages.pb.h>
#include <alice/multiindex.hpp>
#include <alice/stringtable.hpp>
#include <alice/sendtable.hpp>
#include <alice/entity.hpp>
#include <alice/handler.hpp>
#include <alice/exception.hpp>

namespace dota {
    /// @defgroup EXCEPTIONS Exceptions
    /// @{

    /// Thrown when a property is defined as an Array but it's subtype hasn't been set
    CREATE_EXCEPTION( gamestateInvalidArrayProp, "Array property has no previous member to define state." )

    /// Thrown when the baselinceinstance table is not available
    CREATE_EXCEPTION( gamestateBaselineNotFound, "Unable to find baseline instance." )

    /// Thrown when an invalid entity is specified in an update or delete
    CREATE_EXCEPTION( gamestateInvalidId, "Invalid entity id specified in update or delete." )

    /// Thrown when the id for an invalid definition is requested
    CREATE_EXCEPTION( gamestateInvalidDefinition, "Invalid definition specified." )

    /// @}
    /// @defgroup CORE Core
    /// @{

    /**
     * Contains the current state of the game regarding stringtables, sendtables and entities.
     *
     * In addition the class contains the handlers for all callbacks related to entity parsing and handeling.
     * It forwards it's entities to the default handler for them to be relayed to subscribers. Generating the
     * flattables and keeping track of entity updates and deletes also happens here.
     */
    class gamestate {
        public:
            /** Type for a map of stringtables. */
            typedef multiindex<std::string, int32_t, stringtable> stringtableMap;
            /** Type for a map of sendtables. */
            typedef multiindex<std::string, int32_t, sendtable> sendtableMap;
            /** Type for a map of flattables. */
            typedef std::unordered_map<std::string, flatsendtable> flatMap;
            /** Type for a list of entities. */
            typedef std::vector<entity*> entityMap;

            /** Constructor, sets default values and registers the callbacks nessecary. */
            gamestate(handler_t* h)
                : h(h), clist{}, stringtables{}, sendtables{}, flattables{}, entities{}, entityClassBits(0),
                  sendtableId(-1), stringtableId(-1), skipUnsubscribed(false)
            {
                // handle messages nessecary to update gamestate
                handlerRegisterCallback(h, msgDem, DEM_ClassInfo, gamestate, handleClassInfo)

                // allocate memory for entities
                entities.resize(DOTA_MAX_ENTITIES, nullptr);
            }

            /** Destructor, frees all entities that have not been explicitly deleted. */
            ~gamestate() {
                for (auto &e : entities) {
                    delete e;
                }

                for (auto &s : sendtables) {
                    for (auto &ss : s.value) {
                        delete ss.value;
                    }
                }

                stringtables.clear();
                sendtables.clear();
                flattables.clear();
                entities.clear();
            }

            /** Set whether we should skip all unsubscribed entities */
            void skipByDefault(bool skip) {
                skipUnsubscribed = skip;
            }

            /** Ignores said entity when updating the gamestate */
            void ignoreEntity(uint32_t id) {
                skipent.insert(id);
            }

            /** Check if an entity is skipped */
            bool isSkipped(entity *e) {
                // get classid
                uint32_t eId = e->getClassId();

                // check if the entity is skipped because there is no handler
                bool skipU = (skipUnsubscribed && !h->hasCallback<msgEntity>(eId));
                // check to skip if entity is in the ignore set
                bool skipE = skipent.empty() ? false :  (skipent.find(eId) != skipent.end());

                return skipU || skipE;
            }

            /** Returns how many bits we need to read for the class size. */
            inline uint32_t getEntityClassSize() {
                return entityClassBits;
            }

            /** Returns a list of all registered entities. */
            inline entity_list& getEntityClasses() {
                return clist;
            }

            /** Returns a list of all registered stringtables. */
            inline stringtableMap& getStringtables() {
                return stringtables;
            }

            /** Returns a list of all registered sendtables. */
            inline sendtableMap& getSendtables() {
                return sendtables;
            }

            /**
             * Returns a list of all flattables.
             *
             * This function returns an empty map until they have been generated.
             */
            inline flatMap& getFlattables() {
                return flattables;
            }

            /** Returns a list of all entities. */
            inline entityMap& getEntities() {
                return entities;
            }

            /** Returns the flattable for the specified sendtable based on it's name. */
            inline const flatsendtable& getFlattable(const std::string &tbl) {
                auto it = flattables.find(tbl);
                if (it == flattables.end())
                    BOOST_THROW_EXCEPTION( sendtableUnkownTable()
                        << EArg<1>::info(tbl)
                    );

                return it->second;
            }

            /** Returns entity class id for a specific definition */
            inline uint32_t getEntityIdFor(std::string name) {
                for (auto &e : clist) {
                    if (e.second.networkName == name)
                        return e.second.id;
                }

                BOOST_THROW_EXCEPTION( gamestateInvalidDefinition()
                    << EArg<1>::info(name)
                );

                return 0;
            }

            /** Returns all entity class id's for a specific definition substring */
            inline std::vector<uint32_t> findEntityIdFor(std::string name) {
                std::vector<uint32_t> ret;
                uint32_t length = name.size();

                for (auto &e : clist) {
                    if (e.second.networkName.substr(0, length) == name)
                        ret.push_back(e.second.id);
                }

                return ret;
            }

            /** Handles the entity class information and creates the entity_list. */
            void handleClassInfo(handlerCbType(msgDem) msg);

            /** Handles the server information message. Sets the maximum number of possible entities. */
            void handleServerInfo(handlerCbType(msgNet) msg);

            /** Handles creation of the sendtable's and their properties. */
            void handleSendTable(handlerCbType(msgNet) msg);

            /** Creates the stringtable in question. */
            void handleCreateStringtable(handlerCbType(msgNet) msg);

            /** Handles updates to a given stringtable. */
            void handleUpdateStringtable(handlerCbType(msgNet) msg);

            /**
             * Handles an incoming entities and creates / update / deletes it in the gamestate.
             *
             * This function will also forward all the resulting entities to the handler where they are relayed
             * to any subscribers.
             */
            void handleEntity(handlerCbType(msgNet) msg);
        private:
            /** Handler object for this gamestate */
            handler_t* h;
            /** List which includes the name's of all possible entities. */
            entity_list clist;
            /** Contains all active stringtables. */
            stringtableMap stringtables;
            /** Contains the sendtables. */
            sendtableMap sendtables;
            /** A map of flattened sendtables accessible by the sendtable name. */
            flatMap flattables;
            /** List of active entities. */
            entityMap entities;

            /** The number of bits to read for each entitie's class. */
            uint32_t entityClassBits;
            /** ID of the next sendtable to add */
            int32_t sendtableId;
            /** ID of the next stringtable to add */
            int32_t stringtableId;

            /** Whether to skip unsubscribed entities  */
            bool skipUnsubscribed;
            /** List of entity IDs to ignore */
            std::set<uint32_t> skipent;

            /** Prevent copying of this class. */
            gamestate(const gamestate&) = delete;
            /** Prevent moving of this class. */
            gamestate(gamestate&&) = delete;

            /** Sets maximum number of different entity classes, derives entity class size in bits. */
            inline void setMaxClasses(std::size_t classes) {
                entityClassBits = std::ceil(log2(classes));
            }

            /** Flattens the sendtables, generating network representations of the data received in the right order. */
            void flattenSendtables();

            /** Builds a list of properties excluded (included with parents). */
            void buildExcludeList(const sendtable &tbl, std::set<std::string> &excludes);

            /** Build the table hierarchy. */
            void buildHierarchy(const sendtable &tbl, std::set<std::string> &excludes, std::vector<sendprop*> &props);

            /** Gathers properties for a table. */
            void gatherProperties(const sendtable &tbl, std::vector<sendprop*> &dt_prop,
                std::set<std::string> &excludes, std::vector<sendprop*> &props);
    };

    /// @}
}

#endif /* _DOTA_GAMESTATE_HPP_ */<commit_msg>Formating<commit_after>/**
 * @file gamestate.hpp
 * @author Robin Dietrich <me (at) invokr (dot) org>
 * @version 1.0
 *
 * @par License
 *    Alice Replay Parser
 *    Copyright 2014 Robin Dietrich
 *
 *    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 _DOTA_GAMESTATE_HPP_
#define _DOTA_GAMESTATE_HPP_

#include <string>
#include <memory>
#include <vector>
#include <set>

#include <alice/demo.pb.h>
#include <alice/netmessages.pb.h>
#include <alice/multiindex.hpp>
#include <alice/stringtable.hpp>
#include <alice/sendtable.hpp>
#include <alice/entity.hpp>
#include <alice/handler.hpp>
#include <alice/exception.hpp>

namespace dota {
    /// @defgroup EXCEPTIONS Exceptions
    /// @{

    /// Thrown when a property is defined as an Array but it's subtype hasn't been set
    CREATE_EXCEPTION( gamestateInvalidArrayProp, "Array property has no previous member to define state." )

    /// Thrown when the baselinceinstance table is not available
    CREATE_EXCEPTION( gamestateBaselineNotFound, "Unable to find baseline instance." )

    /// Thrown when an invalid entity is specified in an update or delete
    CREATE_EXCEPTION( gamestateInvalidId, "Invalid entity id specified in update or delete." )

    /// Thrown when the id for an invalid definition is requested
    CREATE_EXCEPTION( gamestateInvalidDefinition, "Invalid definition specified." )

    /// @}
    /// @defgroup CORE Core
    /// @{

    /**
     * Contains the current state of the game regarding stringtables, sendtables and entities.
     *
     * In addition the class contains the handlers for all callbacks related to entity parsing and handeling.
     * It forwards it's entities to the default handler for them to be relayed to subscribers. Generating the
     * flattables and keeping track of entity updates and deletes also happens here.
     */
    class gamestate {
        public:
            /** Type for a map of stringtables. */
            typedef multiindex<std::string, int32_t, stringtable> stringtableMap;
            /** Type for a map of sendtables. */
            typedef multiindex<std::string, int32_t, sendtable> sendtableMap;
            /** Type for a map of flattables. */
            typedef std::unordered_map<std::string, flatsendtable> flatMap;
            /** Type for a list of entities. */
            typedef std::vector<entity*> entityMap;

            /** Constructor, sets default values and registers the callbacks nessecary. */
            gamestate(handler_t* h)
                : h(h), clist{}, stringtables{}, sendtables{}, flattables{}, entities{}, entityClassBits(0),
                  sendtableId(-1), stringtableId(-1), skipUnsubscribed(false)
            {
                // handle messages nessecary to update gamestate
                handlerRegisterCallback(h, msgDem, DEM_ClassInfo, gamestate, handleClassInfo)

                // allocate memory for entities
                entities.resize(DOTA_MAX_ENTITIES, nullptr);
            }

            /** Destructor, frees all entities that have not been explicitly deleted. */
            ~gamestate() {
                for (auto &e : entities) {
                    delete e;
                }

                for (auto &s : sendtables) {
                    for (auto &ss : s.value) {
                        delete ss.value;
                    }
                }

                stringtables.clear();
                sendtables.clear();
                flattables.clear();
                entities.clear();
            }

            /** Set whether we should skip all unsubscribed entities */
            void skipByDefault(bool skip) {
                skipUnsubscribed = skip;
            }

            /** Ignores said entity when updating the gamestate */
            void ignoreEntity(uint32_t id) {
                skipent.insert(id);
            }

            /** Check if an entity is skipped */
            bool isSkipped(entity *e) {
                // get classid
                uint32_t eId = e->getClassId();

                // check if the entity is skipped because there is no handler
                bool skipU = (skipUnsubscribed && !h->hasCallback<msgEntity>(eId));
                // check to skip if entity is in the ignore set
                bool skipE = skipent.empty() ? false : (skipent.find(eId) != skipent.end());

                return (skipU || skipE);
            }

            /** Returns how many bits we need to read for the class size. */
            inline uint32_t getEntityClassSize() {
                return entityClassBits;
            }

            /** Returns a list of all registered entities. */
            inline entity_list& getEntityClasses() {
                return clist;
            }

            /** Returns a list of all registered stringtables. */
            inline stringtableMap& getStringtables() {
                return stringtables;
            }

            /** Returns a list of all registered sendtables. */
            inline sendtableMap& getSendtables() {
                return sendtables;
            }

            /**
             * Returns a list of all flattables.
             *
             * This function returns an empty map until they have been generated.
             */
            inline flatMap& getFlattables() {
                return flattables;
            }

            /** Returns a list of all entities. */
            inline entityMap& getEntities() {
                return entities;
            }

            /** Returns the flattable for the specified sendtable based on it's name. */
            inline const flatsendtable& getFlattable(const std::string &tbl) {
                auto it = flattables.find(tbl);
                if (it == flattables.end())
                    BOOST_THROW_EXCEPTION( sendtableUnkownTable()
                        << EArg<1>::info(tbl)
                    );

                return it->second;
            }

            /** Returns entity class id for a specific definition */
            inline uint32_t getEntityIdFor(std::string name) {
                for (auto &e : clist) {
                    if (e.second.networkName == name)
                        return e.second.id;
                }

                BOOST_THROW_EXCEPTION( gamestateInvalidDefinition()
                    << EArg<1>::info(name)
                );

                return 0;
            }

            /** Returns all entity class id's for a specific definition substring */
            inline std::vector<uint32_t> findEntityIdFor(std::string name) {
                std::vector<uint32_t> ret;
                uint32_t length = name.size();

                for (auto &e : clist) {
                    if (e.second.networkName.substr(0, length) == name)
                        ret.push_back(e.second.id);
                }

                return ret;
            }

            /** Handles the entity class information and creates the entity_list. */
            void handleClassInfo(handlerCbType(msgDem) msg);

            /** Handles the server information message. Sets the maximum number of possible entities. */
            void handleServerInfo(handlerCbType(msgNet) msg);

            /** Handles creation of the sendtable's and their properties. */
            void handleSendTable(handlerCbType(msgNet) msg);

            /** Creates the stringtable in question. */
            void handleCreateStringtable(handlerCbType(msgNet) msg);

            /** Handles updates to a given stringtable. */
            void handleUpdateStringtable(handlerCbType(msgNet) msg);

            /**
             * Handles an incoming entities and creates / update / deletes it in the gamestate.
             *
             * This function will also forward all the resulting entities to the handler where they are relayed
             * to any subscribers.
             */
            void handleEntity(handlerCbType(msgNet) msg);
        private:
            /** Handler object for this gamestate */
            handler_t* h;
            /** List which includes the name's of all possible entities. */
            entity_list clist;
            /** Contains all active stringtables. */
            stringtableMap stringtables;
            /** Contains the sendtables. */
            sendtableMap sendtables;
            /** A map of flattened sendtables accessible by the sendtable name. */
            flatMap flattables;
            /** List of active entities. */
            entityMap entities;

            /** The number of bits to read for each entitie's class. */
            uint32_t entityClassBits;
            /** ID of the next sendtable to add */
            int32_t sendtableId;
            /** ID of the next stringtable to add */
            int32_t stringtableId;

            /** Whether to skip unsubscribed entities  */
            bool skipUnsubscribed;
            /** List of entity IDs to ignore */
            std::set<uint32_t> skipent;

            /** Prevent copying of this class. */
            gamestate(const gamestate&) = delete;
            /** Prevent moving of this class. */
            gamestate(gamestate&&) = delete;

            /** Sets maximum number of different entity classes, derives entity class size in bits. */
            inline void setMaxClasses(std::size_t classes) {
                entityClassBits = std::ceil(log2(classes));
            }

            /** Flattens the sendtables, generating network representations of the data received in the right order. */
            void flattenSendtables();

            /** Builds a list of properties excluded (included with parents). */
            void buildExcludeList(const sendtable &tbl, std::set<std::string> &excludes);

            /** Build the table hierarchy. */
            void buildHierarchy(const sendtable &tbl, std::set<std::string> &excludes, std::vector<sendprop*> &props);

            /** Gathers properties for a table. */
            void gatherProperties(const sendtable &tbl, std::vector<sendprop*> &dt_prop,
                std::set<std::string> &excludes, std::vector<sendprop*> &props);
    };

    /// @}
}

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


<commit_before>#ifndef CAFFEINE_COMMON_HPP_
#define CAFFEINE_COMMON_HPP_

#include <iostream>

#include <boost/shared_ptr.hpp>

#include "driver_types.h"

namespace caffeine {
  using boost::shared_ptr;
}

static std::ostream nullout(0);

// TODO(Yangqing): make a better logging scheme
#define LOG_IF(condition) \
    !(condition) ? nullout : std::cout

#define CHECK(condition) \
    LOG_IF(condition) << "Check failed: " #condition " "

#ifndef NDEBUG

#define DCHECK(condition) CHECK(condition)

#else

#define DCHECK(condition)

#endif  // NDEBUG

#define CUDA_CHECK(condition) \
    CUDA_LOG_IF(condition) << "Check failed: " #condition " "

// TODO(Yangqing): make a better logging scheme
#define CUDA_LOG_IF(condition) \
    ((condition) != cudaSuccess) ? nullout : std::cout

#define CUDA_CHECK(condition) \
    CUDA_LOG_IF(condition) << "Check failed: " #condition " "

#ifndef NDEBUG

#define CUDA_DCHECK(condition) CUDA_CHECK(condition)

#else

#define CUDA_DCHECK(condition)

#endif  // NDEBUG

#endif  // CAFFEINE_COMMON_HPP_<commit_msg>common bugfix<commit_after>#ifndef CAFFEINE_COMMON_HPP_
#define CAFFEINE_COMMON_HPP_

#include <iostream>

#include <boost/shared_ptr.hpp>

#include "driver_types.h"

namespace caffeine {
  using boost::shared_ptr;
}

static std::ostream nullout(0);

// TODO(Yangqing): make a better logging scheme
#define LOG_IF(condition) \
    !(condition) ? nullout : std::cout

#define CHECK(condition) \
    LOG_IF(condition) << "Check failed: " #condition " "

#ifndef NDEBUG

#define DCHECK(condition) CHECK(condition)

#else

#define DCHECK(condition)

#endif  // NDEBUG

#define CUDA_CHECK(condition) \
    CUDA_LOG_IF(condition) << "Check failed: " #condition " "

// TODO(Yangqing): make a better logging scheme
#define CUDA_LOG_IF(condition) \
    ((condition) == cudaSuccess) ? nullout : std::cout

#define CUDA_CHECK(condition) \
    CUDA_LOG_IF(condition) << "Check failed: " #condition " "

#ifndef NDEBUG

#define CUDA_DCHECK(condition) CUDA_CHECK(condition)

#else

#define CUDA_DCHECK(condition)

#endif  // NDEBUG

#endif  // CAFFEINE_COMMON_HPP_
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2015, Howard Butler (howard@hobu.co)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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.
****************************************************************************/

#include "DensityKernel.hpp"
#include "../filters/HexBin.hpp"
#include "OGR.hpp"

#include <pdal/pdal_macros.hpp>
#include <pdal/plugin.hpp>
#include <pdal/GlobalEnvironment.hpp>

namespace pdal
{

static PluginInfo const s_info = PluginInfo(
    "kernels.density",
    "Density Kernel",
    "http://pdal.io/kernels/kernels.density.html" );

CREATE_SHARED_PLUGIN(1, 0, DensityKernel, Kernel, s_info)

std::string DensityKernel::getName() const { return s_info.name; }

DensityKernel::DensityKernel()
{
}

void DensityKernel::addSwitches(ProgramArgs& args)
{
    args.add("input,i", "input point cloud file name", m_inputFile);
    args.add("output,o", "output vector data source", m_outputFile);
    args.add("lyr_name", "OGR layer name to write into datasource",
        m_layerName);
    args.add("driver,f", "OGR driver name to use ", m_driverName,
        "ESRI Shapefile");
}

void DensityKernel::makePipeline(const std::string& filename)
{
    if (!pdal::FileUtils::fileExists(filename))
        throw pdal_error("File not found: " + filename);

    m_manager = PipelineManagerPtr(new PipelineManager);

    if (filename == "STDIN")
    {
        m_manager->readPipeline(std::cin);
    }
    else if (FileUtils::extension(filename) == ".xml" ||
        FileUtils::extension(filename) == ".json")
    {
        m_manager->readPipeline(filename);
    }
    else
    {
        StageFactory factory;
        std::string driver = factory.inferReaderDriver(filename);

        if (driver.empty())
            throw pdal_error("Cannot determine input file type of " + filename);
        Stage& reader = m_manager->addReader(driver);
        Options ro;
        ro.add("filename", filename);
        reader.setOptions(ro);
    }
    Stage *stage = m_manager->getStage();
    m_hexbinStage = &(m_manager->addFilter("filters.hexbin"));
    if (!m_hexbinStage) {
        throw pdal_error("Unable to initialize filters.hexbin!");
    }
    m_hexbinStage->setInput(*stage);
}

void DensityKernel::outputDensity(pdal::SpatialReference const& reference)
{

    pdal::HexBin* hexbin = static_cast<pdal::HexBin*>(m_hexbinStage);
    if (!hexbin)
        throw pdal::pdal_error("unable to fetch filters.hexbin stage!");

    hexer::HexGrid* grid = hexbin->grid();

    pdal::hexdensity::writer::OGR writer(m_outputFile, reference.getWKT(), m_driverName);
    writer.writeDensity(grid);
//     writer.writeBoundary(grid);

}

int DensityKernel::execute()
{

    GlobalEnvironment::get().initializeGDAL(0);
    std::string filename = m_usestdin ? std::string("STDIN") : m_inputFile;
    makePipeline(filename);
    applyExtraStageOptionsRecursive(m_manager->getStage());
    point_count_t output = m_manager->execute();
    PointTableRef table = m_manager->pointTable();
    std::cout << "size: " << output << std::endl;
    outputDensity(table.anySpatialReference());
    return 0;
}

}
<commit_msg>remove debugging lint<commit_after>/******************************************************************************
* Copyright (c) 2015, Howard Butler (howard@hobu.co)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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.
****************************************************************************/

#include "DensityKernel.hpp"
#include "../filters/HexBin.hpp"
#include "OGR.hpp"

#include <pdal/pdal_macros.hpp>
#include <pdal/plugin.hpp>
#include <pdal/GlobalEnvironment.hpp>

namespace pdal
{

static PluginInfo const s_info = PluginInfo(
    "kernels.density",
    "Density Kernel",
    "http://pdal.io/kernels/kernels.density.html" );

CREATE_SHARED_PLUGIN(1, 0, DensityKernel, Kernel, s_info)

std::string DensityKernel::getName() const { return s_info.name; }

DensityKernel::DensityKernel()
{
}

void DensityKernel::addSwitches(ProgramArgs& args)
{
    args.add("input,i", "input point cloud file name", m_inputFile);
    args.add("output,o", "output vector data source", m_outputFile);
    args.add("lyr_name", "OGR layer name to write into datasource",
        m_layerName);
    args.add("driver,f", "OGR driver name to use ", m_driverName,
        "ESRI Shapefile");
}

void DensityKernel::makePipeline(const std::string& filename)
{
    if (!pdal::FileUtils::fileExists(filename))
        throw pdal_error("File not found: " + filename);

    m_manager = PipelineManagerPtr(new PipelineManager);

    if (filename == "STDIN")
    {
        m_manager->readPipeline(std::cin);
    }
    else if (FileUtils::extension(filename) == ".xml" ||
        FileUtils::extension(filename) == ".json")
    {
        m_manager->readPipeline(filename);
    }
    else
    {
        StageFactory factory;
        std::string driver = factory.inferReaderDriver(filename);

        if (driver.empty())
            throw pdal_error("Cannot determine input file type of " + filename);
        Stage& reader = m_manager->addReader(driver);
        Options ro;
        ro.add("filename", filename);
        reader.setOptions(ro);
    }
    Stage *stage = m_manager->getStage();
    m_hexbinStage = &(m_manager->addFilter("filters.hexbin"));
    if (!m_hexbinStage) {
        throw pdal_error("Unable to initialize filters.hexbin!");
    }
    m_hexbinStage->setInput(*stage);
}

void DensityKernel::outputDensity(pdal::SpatialReference const& reference)
{

    pdal::HexBin* hexbin = static_cast<pdal::HexBin*>(m_hexbinStage);
    if (!hexbin)
        throw pdal::pdal_error("unable to fetch filters.hexbin stage!");

    hexer::HexGrid* grid = hexbin->grid();

    pdal::hexdensity::writer::OGR writer(m_outputFile, reference.getWKT(), m_driverName);
    writer.writeDensity(grid);
//     writer.writeBoundary(grid);

}

int DensityKernel::execute()
{

    GlobalEnvironment::get().initializeGDAL(0);
    std::string filename = m_usestdin ? std::string("STDIN") : m_inputFile;
    makePipeline(filename);
    applyExtraStageOptionsRecursive(m_manager->getStage());
    point_count_t output = m_manager->execute();
    PointTableRef table = m_manager->pointTable();
    outputDensity(table.anySpatialReference());
    return 0;
}

}
<|endoftext|>