text:
#include "tpf_fs3d_data_reader.h"

#include "tpf_fs3d_data.h"

#include "tpf/module/tpf_module_reader_base.h"

#include "tpf/data/tpf_data_information.h"
#include "tpf/data/tpf_grid.h"

#include "tpf/log/tpf_log.h"

#include "tpf/performance/tpf_timer.h"

#ifdef __tpf_use_mpiio
#include "tpf/utility/tpf_copy.h"
#include "tpf/utility/tpf_downcast.h"

#include "mpi.h"
#endif

#include <algorithm>
#include <array>
#include <chrono>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include <boost/algorithm/string.hpp>

namespace tpf
{
    namespace modules
    {
        namespace fs3d_reader_aux
        {
            template <typename value_t, typename point_t>
            inline fs3d_data_reader<value_t, point_t>::fs3d_data_reader(const std::string& list_filename, const std::string& grid_filename)
                : list_filename(list_filename), grid_filename(grid_filename), state(NO_INFORMATION)
            { }

            template <typename value_t, typename point_t>
            inline data_information fs3d_data_reader<value_t, point_t>::get_information()
            {
                // Read information
                read_information();

                // Return information
                data_information info;
                info.extent = this->extent;
                info.timesteps = this->timesteps;
                info.datasets.push_back(std::make_pair(this->dataset_name, this->num_components));

                return info;
            }

            template <typename value_t, typename point_t>
            inline void fs3d_data_reader<value_t, point_t>::set_subextent(const data::extent_t& extent)
            {
                if (this->state == NO_INFORMATION)
                {
                    throw std::runtime_error(__tpf_error_message("Global information must be set before setting subextents!"));
                }

                // Check for same sub extent and same number of ghost levels
                bool same_subextent = extent.size() == this->subextent.size();

                for (std::size_t d = 0; d < std::min(extent.size(), this->subextent.size()); ++d)
                {
                    same_subextent &= extent[d].first == this->subextent[d].first && extent[d].second == this->subextent[d].second;
                }

                // Only if there are changes, reload the grid
                if (!same_subextent)
                {
                    this->subextent = extent;

                    this->state = EXTENT_INFORMATION;
                }
            }

            template <typename value_t, typename point_t>
            template <std::size_t components>
            inline data::grid<value_t, point_t, 3, components> fs3d_data_reader<value_t, point_t>::read_timestep(const std::size_t timestep)
            {
                const auto& mpi = mpi::get_instance();

                // Read information
                read_information();

                // Check time step
                if (timestep >= this->data_filenames.size())
                {
                    throw std::runtime_error(__tpf_error_message("Time step is out of bounds!"));
                }

                // Check for same (sub) extent
                bool same_subextent = this->extent.size() == this->subextent.size();

                for (std::size_t d = 0; d < std::min(this->extent.size(), this->subextent.size()); ++d)
                {
                    same_subextent &= this->extent[d].first == this->subextent[d].first && this->extent[d].second == this->subextent[d].second;
                }

                // Read data information
                const auto data_header = read_data_header(timestep);

                // Sanity check
                if (data_header.x_resolution != this->header.x_resolution ||
                    data_header.y_resolution != this->header.y_resolution ||
                    data_header.z_resolution != this->header.z_resolution)
                {
                    throw std::runtime_error(__tpf_error_message("Grid resolutions do not match!"));
                }

                // Read data
                std::vector<value_t> data;

                if (mpi.get_num_processes() == 1 && same_subextent)
                {
                    data = read_data<components>(timestep);
                }
                else
                {
                    data = read_data_block<components>(timestep);
                }

                // Create grid
                return data::grid<value_t, point_t, 3, components>(data_header.name + data_header.unit, this->subextent, std::move(data),
                    this->cell_coordinates, this->node_coordinates, this->cell_sizes);
            }

            template <typename value_t, typename point_t>
            inline void fs3d_data_reader<value_t, point_t>::read_information()
            {
                if (this->state != ALL_INFORMATION)
                {
                    const auto& mpi = mpi::get_instance();

                    if (this->state == GLOBAL_INFORMATION)
                    {
                        throw std::runtime_error(__tpf_error_message("Subextent must be set before reading grid information!"));
                    }

                    if (this->state == NO_INFORMATION)
                    {
                        // Read file list
                        read_file_list();

                        // Read grid information
                        read_grid_header();

                        this->extent.resize(3);
                        this->extent[0].first = this->extent[1].first = this->extent[2].first = 0;
                        this->extent[0].second = static_cast<std::size_t>(this->header.x_resolution - 1);
                        this->extent[1].second = static_cast<std::size_t>(this->header.y_resolution - 1);
                        this->extent[2].second = static_cast<std::size_t>(this->header.z_resolution - 1);

                        // Read time steps and set number of components
                        this->timesteps.resize(this->data_filenames.size());

                        for (std::size_t i = 0; i < this->data_filenames.size(); ++i)
                        {
                            const auto data_header = read_data_header(i);
                            this->timesteps[i] = data_header.time_step;
                            this->num_components = static_cast<std::size_t>(data_header.components);
                            this->dataset_name = data_header.name + data_header.unit;
                        }

                        this->state = GLOBAL_INFORMATION;
                    }

                    if (this->state == EXTENT_INFORMATION)
                    {
                        // Read grid
                        read_grid();

                        this->node_coordinates.clear();
                        this->cell_sizes.clear();

                        this->node_coordinates.resize(3);
                        this->cell_sizes.resize(3);

                        for (std::size_t d = 0; d < 3; ++d)
                        {
                            // Calculate node coordinates
                            this->node_coordinates[d].reserve(this->cell_coordinates[d].size() + 1);
                            this->node_coordinates[d].push_back(static_cast<point_t>(0.0L));

                            for (std::size_t i = 1; i < this->cell_coordinates[d].size() + 1; ++i)
                            {
                                this->node_coordinates[d].push_back(static_cast<point_t>(2.0L) * this->cell_coordinates[d][i - 1] - this->node_coordinates[d][i - 1]);
                            }

                            // Calculate cell sizes
                            this->cell_sizes[d].reserve(this->cell_coordinates[d].size());

                            for (std::size_t i = 0; i < this->cell_coordinates[d].size(); ++i)
                            {
                                this->cell_sizes[d].push_back(this->node_coordinates[d][i + 1] - this->node_coordinates[d][i]);
                            }
                        }

                        // Extract subextent
                        for (std::size_t d = 0; d < 3; ++d)
                        {
                            if (this->subextent[d].first == this->extent[d].first)
                            {
                                this->cell_coordinates[d].resize(this->subextent[d].second - this->subextent[d].first + 1);
                                this->node_coordinates[d].resize(this->subextent[d].second - this->subextent[d].first + 2);
                                this->cell_sizes[d].resize(this->subextent[d].second - this->subextent[d].first + 1);
                            }
                            else
                            {
                                std::vector<point_t> sub_cell_coordinates, sub_node_coordinates, sub_cell_sizes;
                                sub_cell_coordinates.reserve(this->subextent[d].second - this->subextent[d].first + 1);
                                sub_node_coordinates.reserve(this->subextent[d].second - this->subextent[d].first + 2);
                                sub_cell_sizes.reserve(this->subextent[d].second - this->subextent[d].first + 1);

                                sub_cell_coordinates.insert(sub_cell_coordinates.end(), this->cell_coordinates[d].begin() + this->subextent[d].first,
                                    this->cell_coordinates[d].begin() + this->subextent[d].second + 1);
                                sub_node_coordinates.insert(sub_node_coordinates.end(), this->node_coordinates[d].begin() + this->subextent[d].first,
                                    this->node_coordinates[d].begin() + this->subextent[d].second + 2);
                                sub_cell_sizes.insert(sub_cell_sizes.end(), this->cell_sizes[d].begin() + this->subextent[d].first,
                                    this->cell_sizes[d].begin() + this->subextent[d].second + 1);

                                this->cell_coordinates[d].swap(sub_cell_coordinates);
                                this->node_coordinates[d].swap(sub_node_coordinates);
                                this->cell_sizes[d].swap(sub_cell_sizes);
                            }
                        }

                        this->state = ALL_INFORMATION;
                    }
                }
            }

            template <typename value_t, typename point_t>
            inline void fs3d_data_reader<value_t, point_t>::read_file_list()
            {
                // Extract path from list file name
                const auto pos = list_filename.find_last_of("/\\");
                const auto path = list_filename.substr(0, pos + 1);

                // Read file name list
                std::ifstream ifs(list_filename, std::ifstream::in);
                std::string line;

                if (ifs.good())
                {
                    while (!ifs.eof())
                    {
                        std::getline(ifs, line);

                        if (!(line = boost::trim_copy(line)).empty())
                        {
                            this->data_filenames.push_back(path + line);
                        }
                    }

                    ifs.close();
                }
                else
                {
                    throw std::runtime_error(__tpf_error_message("Error reading file list!"));
                }
            }

            template <typename value_t, typename point_t>
            inline void fs3d_data_reader<value_t, point_t>::read_grid_header()
            {
                // Create and read output header
                const std::size_t max_string = 80;

                std::ifstream ifs(this->grid_filename, std::ofstream::in | std::ofstream::binary);

                if (ifs.good())
                {
                    std::array<char, max_string> unit;

                    ifs.read(unit.data(), max_string);
                    ifs.read(reinterpret_cast<char*>(&this->header.x_resolution), sizeof(int));
                    ifs.read(reinterpret_cast<char*>(&this->header.y_resolution), sizeof(int));
                    ifs.read(reinterpret_cast<char*>(&this->header.z_resolution), sizeof(int));

                    this->header.unit.assign(unit.begin(), unit.end());
                    boost::trim(this->header.unit);

                    ifs.close();
                }
                else
                {
                    throw std::runtime_error(__tpf_error_message("Error reading grid file header!"));
                }
            }

            template <typename value_t, typename point_t>
            inline void fs3d_data_reader<value_t, point_t>::read_grid()
            {
                // Read data
                std::ifstream ifs(this->grid_filename, std::ifstream::in | std::ifstream::binary);

                // Create output
                this->cell_coordinates.clear();
                this->cell_coordinates.resize(3);

                this->cell_coordinates[0].resize(this->header.x_resolution);
                this->cell_coordinates[1].resize(this->header.y_resolution);
                this->cell_coordinates[2].resize(this->header.z_resolution);

                if (ifs.good())
                {
                    // Skip header
                    ifs.seekg(grid_header::length);

                    // Read for each dimension
                    if (std::is_same<typename grid_header::value_type, point_t>::value)
                    {
                        // Read block
                        ifs.read((char*)this->cell_coordinates[0].data(), this->cell_coordinates[0].size() * sizeof(typename grid_header::value_type));
                        ifs.read((char*)this->cell_coordinates[1].data(), this->cell_coordinates[1].size() * sizeof(typename grid_header::value_type));
                        ifs.read((char*)this->cell_coordinates[2].data(), this->cell_coordinates[2].size() * sizeof(typename grid_header::value_type));
                    }
                    else
                    {
                        for (std::size_t d = 0; d < 3; ++d)
                        {
                            // Read block to buffer
                            std::vector<typename grid_header::value_type> buffer(this->cell_coordinates[d].size());

                            ifs.read(reinterpret_cast<char*>(buffer.data()), buffer.size() * sizeof(typename grid_header::value_type));

                            // Copy data from buffer
                            for (std::size_t i = 0; i < buffer.size(); ++i)
                            {
                                this->cell_coordinates[d][i] = static_cast<point_t>(buffer[i]);
                            }
                        }
                    }
                }
                else
                {
                    throw std::runtime_error(__tpf_error_message("Error reading grid file!"));
                }
            }

            template <typename value_t, typename point_t>
            inline data_header fs3d_data_reader<value_t, point_t>::read_data_header(const std::size_t timestep) const
            {
                // Create and read output header
                data_header header;
                const std::size_t max_string = 80;

                std::ifstream ifs(this->data_filenames[timestep], std::ofstream::in | std::ofstream::binary);

                if (ifs.good())
                {
                    std::array<char, max_string> name;
                    std::array<char, max_string> unit;

                    ifs.read(name.data(), max_string);
                    ifs.read(unit.data(), max_string);
                    ifs.read(reinterpret_cast<char*>(&header.time_id), sizeof(int));
                    ifs.read(reinterpret_cast<char*>(&header.time_step), sizeof(double));
                    ifs.read(reinterpret_cast<char*>(&header.x_resolution), sizeof(int));
                    ifs.read(reinterpret_cast<char*>(&header.y_resolution), sizeof(int));
                    ifs.read(reinterpret_cast<char*>(&header.z_resolution), sizeof(int));
                    ifs.read(reinterpret_cast<char*>(&header.identifier), sizeof(int));

                    header.name.assign(name.begin(), name.end());
                    boost::trim(header.name);

                    header.unit.assign(unit.begin(), unit.end());
                    boost::trim(header.unit);

                    ifs.seekg(0, std::ios::end);
                    const auto file_size = static_cast<std::size_t>(ifs.tellg());

                    const auto size_per_component = static_cast<std::size_t>(header.x_resolution) * static_cast<std::size_t>(header.y_resolution)
                        * static_cast<std::size_t>(header.z_resolution) * static_cast<std::size_t>(sizeof(double));

                    if (size_per_component == 0)
                    {
                        throw std::runtime_error(__tpf_error_message("Invalid resolution in header of file '", this->data_filenames[timestep], "'!"));
                    }

                    header.components = static_cast<int>((file_size - data_header::length) / size_per_component);

                    if (header.components * size_per_component != file_size - data_header::length)
                    {
                        throw std::runtime_error(__tpf_error_message("Invalid size of file '", this->data_filenames[timestep], "'!"));
                    }

                    ifs.close();
                }
                else
                {
                    throw std::runtime_error(__tpf_error_message("Error reading header of file '", this->data_filenames[timestep], "'!"));
                }

                return header;
            }

            template <typename value_t, typename point_t>
            template <std::size_t components>
            inline std::vector<value_t> fs3d_data_reader<value_t, point_t>::read_data(const std::size_t timestep) const
            {
                __tpf_timer_start(timer, "read_data", std::chrono::seconds);

                // Open file stream
                std::ifstream ifs(this->data_filenames[timestep], std::ifstream::in | std::ifstream::binary);

                // Calculate buffer and data size
                const std::size_t buffer_size = static_cast<std::size_t>(this->header.x_resolution) *
                    static_cast<std::size_t>(this->header.y_resolution) * static_cast<std::size_t>(this->header.z_resolution);

                std::vector<value_t> data(buffer_size * components);

                if (ifs.good())
                {
                    // Skip header
                    ifs.seekg(data_header::length);

                    // Read for each component
                    if (std::is_same<typename data_header::value_type, value_t>::value && components == 1)
                    {
                        // Read block
                        ifs.read(reinterpret_cast<char*>(data.data()), data.size() * sizeof(typename data_header::value_type));
                    }
                    else
                    {
                        std::vector<typename data_header::value_type> buffer(buffer_size);

                        for (std::size_t c = 0; c < components; ++c)
                        {
                            // Read block
                            ifs.read(reinterpret_cast<char*>(buffer.data()), buffer.size() * sizeof(typename data_header::value_type));

                            // Copy data from buffer
                            for (std::size_t i = 0; i < buffer_size; ++i)
                            {
                                const std::size_t data_index = (i * components) + c;

                                data[data_index] = static_cast<value_t>(buffer[i]);
                            }
                        }
                    }

                    ifs.close();
                }
                else
                {
                    throw std::runtime_error(__tpf_error_message("Error reading data file '", this->data_filenames[timestep], "'!"));
                }

                return data;
            }

            template <typename value_t, typename point_t>
            template <std::size_t components>
            inline std::vector<value_t> fs3d_data_reader<value_t, point_t>::read_data_block(const std::size_t timestep) const
            {
#ifdef __tpf_use_mpiio
                __tpf_timer("read_data_block parallel", std::chrono::seconds);

                const auto& mpi = mpi::get_instance();

                // Create sub array type representing the data block
                MPI_Datatype memtype, filetype;
                std::array<int, 4> memsizes, local_memsizes, local_memstarts;
                std::array<int, 3> filesizes, local_filesizes, local_filestarts;

                std::size_t memsize = 1;
                std::size_t filesize = 1;

                for (std::size_t i = 0; i < 3; ++i)
                {
                    memsizes[i] = utility::safe_downcast<int>(this->subextent[2 - i].second - this->subextent[2 - i].first + 1);
                    local_memsizes[i] = memsizes[i];
                    local_memstarts[i] = 0;
                    memsize *= memsizes[i];

                    filesizes[i] = utility::safe_downcast<int>(this->extent[2 - i].second - this->extent[2 - i].first + 1);
                    local_filesizes[i] = memsizes[i];
                    local_filestarts[i] = utility::safe_downcast<int>(this->subextent[2 - i].first - this->extent[2 - i].first);
                    filesize *= filesizes[i];
                }

                memsizes[3] = components;
                local_memsizes[3] = 1;
                local_memstarts[3] = 0;
                memsize *= components;

                MPI_Type_create_subarray(4, memsizes.data(), local_memsizes.data(), local_memstarts.data(), MPI_ORDER_C, MPI_DOUBLE, &memtype);
                MPI_Type_commit(&memtype);

                MPI_Type_create_subarray(3, filesizes.data(), local_filesizes.data(), local_filestarts.data(), MPI_ORDER_C, MPI_DOUBLE, &filetype);
                MPI_Type_commit(&filetype);

                // Open file
                std::vector<char> filename(this->data_filenames[timestep].begin(), this->data_filenames[timestep].end());
                filename.push_back('\0');
                MPI_File file;

                auto result = MPI_File_open(mpi.get_comm(), filename.data(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file);

                if (result != MPI_SUCCESS)
                {
                    throw std::runtime_error(__tpf_error_message("Unable to open data file '", this->data_filenames[timestep], "'!"));
                }

                // Calculate file size and offsets
                const MPI_Offset initial_offset = utility::safe_downcast<MPI_Offset>(data_header::length);
                const MPI_Offset increment = utility::safe_downcast<MPI_Offset>(filesize * sizeof(typename data_header::value_type));

                MPI_Offset file_size;

                MPI_File_get_size(file, &file_size);

                if (increment * components + initial_offset != file_size)
                {
                    throw std::runtime_error(__tpf_error_message("File size does not match for file '", this->data_filenames[timestep], "'!"));
                }

                // Read data block
                std::vector<typename data_header::value_type> data(memsize);

                for (std::size_t c = 0; c < components; ++c)
                {
                    result = MPI_File_set_view(file, initial_offset + c * increment, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL);

                    if (result != MPI_SUCCESS)
                    {
                        throw std::runtime_error(__tpf_error_message("Unable to set data file view for file '", this->data_filenames[timestep], "'!"));
                    }

                    result = MPI_File_read_all(file, &data[c], 1, memtype, MPI_STATUS_IGNORE);

                    if (result != MPI_SUCCESS)
                    {
                        throw std::runtime_error(__tpf_error_message("Unable to read data file for file '", this->data_filenames[timestep], "'!"));
                    }
                }

                MPI_Type_free(&memtype);
                MPI_Type_free(&filetype);

                MPI_File_close(&file);

                return utility::copy_data<value_t>(data);
#else
                __tpf_timer("read_data_block sequential", std::chrono::seconds);

                // Open file stream
                std::ifstream ifs(this->data_filenames[timestep], std::ifstream::in | std::ifstream::binary);

                // Create data array
                const std::array<std::size_t, 3> res = {
                    this->extent[0].second - this->extent[0].first + 1,
                    this->extent[1].second - this->extent[1].first + 1,
                    this->extent[2].second - this->extent[2].first + 1 };

                const std::array<std::size_t, 3> subres = {
                    this->subextent[0].second - this->subextent[0].first + 1,
                    this->subextent[1].second - this->subextent[1].first + 1,
                    this->subextent[2].second - this->subextent[2].first + 1 };

                std::vector<value_t> data(subres[0] * subres[1] * subres[2] * components);

                if (ifs.good())
                {
                    std::vector<typename data_header::value_type> buffer(subres[0]);

                    for (std::size_t c = 0; c < components; ++c)
                    {
                        for (std::size_t z = 0; z < subres[2]; ++z)
                        {
                            for (std::size_t y = 0; y < subres[1]; ++y)
                            {
                                // Skip to next block
                                const std::size_t file_index = this->subextent[0].first + res[0] *
                                    ((y + this->subextent[1].first) + res[1] * ((z + this->subextent[2].first) + res[2] * c));

                                ifs.seekg(data_header::length + file_index * sizeof(typename data_header::value_type));

                                if (std::is_same<typename data_header::value_type, value_t>::value && components == 1)
                                {
                                    // Read block
                                    const std::size_t data_index = c + components * (subres[0] * (y + subres[1] * z));

                                    ifs.read(reinterpret_cast<char*>(&data[data_index]), buffer.size() * sizeof(typename data_header::value_type));
                                }
                                else
                                {
                                    // Read block
                                    ifs.read(reinterpret_cast<char*>(buffer.data()), buffer.size() * sizeof(typename data_header::value_type));

                                    // Copy data from buffer
                                    for (std::size_t i = 0; i < subres[0]; ++i)
                                    {
                                        const std::size_t data_index = c + components * (i + subres[0] * (y + subres[1] * z));

                                        data[data_index] = static_cast<value_t>(buffer[i]);
                                    }
                                }
                            }
                        }
                    }

                    ifs.close();
                }
                else
                {
                    throw std::runtime_error(__tpf_error_message("Error reading data file '", this->data_filenames[timestep], "'!"));
                }

                return data;
#endif
            }
        }
    }
}

ext: inl

max_stars_repo_name: UniStuttgart-VISUS/tpf

max_issues_repo_name: UniStuttgart-VISUS/tpf

max_forks_repo_name: UniStuttgart-VISUS/tpf


text:
#ifndef ITL_PC_BLOCK_DIAGONAL_INCLUDE
#define ITL_PC_BLOCK_DIAGONAL_INCLUDE

#include <boost/numeric/itl/pc/diagonal.hpp>

#include "solver/BlockMTLMatrix.h"

namespace itl
{
  namespace pc
  {

    /// Diagonal Preconditioner
    template <>
    class diagonal<AMDiS::BlockMTLMatrix, mtl::Collection<AMDiS::BlockMTLMatrix>::value_type>
    {
    public:
      typedef mtl::Collection<AMDiS::BlockMTLMatrix>::value_type   Value;
      typedef Value                                                value_type;
      typedef mtl::Collection<AMDiS::BlockMTLMatrix>::size_type    size_type;
      typedef diagonal                                             self;

      /// Constructor takes matrix reference
      explicit diagonal(const AMDiS::BlockMTLMatrix& A) : inv_diag(num_rows(A))
      {
        MTL_THROW_IF(num_rows(A) != num_cols(A), mtl::matrix_not_square());
        using math::reciprocal;

        for (size_t i = 0; i < A.n_rows; i++)
          inv_diag[A.getRowRange(i)] = mtl::matrix::diagonal(A.getSubMatrix(i,i));

        for (size_type i = 0; i < num_rows(A); ++i)
          inv_diag[i]= reciprocal(inv_diag[i]);
      }

      /// Member function solve, better use free function solve
      template <typename Vector>
      Vector solve(const Vector& x) const
      {
        Vector y(resource(x));
        solve(x, y);
        return y;
      }

      template <typename VectorIn, typename VectorOut>
      void solve(const VectorIn& x, VectorOut& y) const
      {
        y.checked_change_resource(x);
        MTL_THROW_IF(size(x) != size(inv_diag), mtl::incompatible_size());
        for (size_type i= 0; i < size(inv_diag); ++i)
          y[i]= inv_diag[i] * x[i];
      }

      /// Member function for solving adjoint problem, better use free function adjoint_solve
      template <typename Vector>
      Vector adjoint_solve(const Vector& x) const
      {
        Vector y(resource(x));
        adjoint_solve(x, y);
        return y;
      }

      template <typename VectorIn, typename VectorOut>
      void adjoint_solve(const VectorIn& x, VectorOut& y) const
      {
        using mtl::conj;
        y.checked_change_resource(x);
        MTL_THROW_IF(size(x) != size(inv_diag), mtl::incompatible_size());
        for (size_type i= 0; i < size(inv_diag); ++i)
          y[i]= conj(inv_diag[i]) * x[i];
      }

    protected:
      mtl::vector::dense_vector<value_type>    inv_diag;
    };

  }
} // namespace itl::pc

#endif // ITL_PC_DIAGONAL_INCLUDE

ext: hpp


text:
/*
 * Copyright (c) 2019 oxarbitrage and contributors.
 *
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <boost/test/unit_test.hpp>

#include <graphene/app/api.hpp>
#include <graphene/utilities/tempdir.hpp>
#include <fc/crypto/digest.hpp>

#include <graphene/custom_operations/custom_operations_plugin.hpp>

#include "../common/database_fixture.hpp"

#define BOOST_TEST_MODULE Custom operations plugin tests

using namespace graphene::chain;
using namespace graphene::chain::test;
using namespace graphene::app;
using namespace graphene::custom_operations;

BOOST_FIXTURE_TEST_SUITE( custom_operation_tests, database_fixture )

void map_operation(flat_map<string, optional<string>>& pairs, bool remove, string& catalog, account_id_type& account,
      private_key& pk, database& db)
{
   signed_transaction trx;
   set_expiration(db, trx);

   custom_operation op;
   account_storage_map store;

   store.key_values = pairs;
   store.remove = remove;
   store.catalog = catalog;

   auto packed = fc::raw::pack(store);
   packed.insert(packed.begin(), types::account_map);

   op.payer = account;
   op.data = packed;
   op.fee = db.get_global_properties().parameters.current_fees->calculate_fee(op);
   trx.operations.push_back(op);
   trx.sign(pk, db.get_chain_id());
   PUSH_TX(db, trx, ~0);
   trx.clear();
}

BOOST_AUTO_TEST_CASE(custom_operations_account_storage_map_test)
{
try {
   ACTORS((nathan)(alice)(robert)(patty));

   app.enable_plugin("custom_operations");
   custom_operations_api custom_operations_api(app);

   generate_block();
   enable_fees();

   int64_t init_balance(10000 * GRAPHENE_BLOCKCHAIN_PRECISION);

   transfer(committee_account, nathan_id, asset(init_balance));
   transfer(committee_account, alice_id, asset(init_balance));

   // catalog is indexed so cant be too big(greater than CUSTOM_OPERATIONS_MAX_KEY_SIZE(200) is not allowed)
   std::string catalog(201, 'a');
   flat_map<string, optional<string>> pairs;
   pairs["key"] = fc::json::to_string("value");
   map_operation(pairs, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   auto storage_results_nathan = custom_operations_api.get_storage_info("nathan", catalog);
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 0 );

   // keys are indexed so they cant be too big(greater than CUSTOM_OPERATIONS_MAX_KEY_SIZE(200) is not allowed)
   catalog = "whatever";
   std::string key(201, 'a');
   pairs.clear();
   pairs[key] = fc::json::to_string("value");
   map_operation(pairs, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   storage_results_nathan = custom_operations_api.get_storage_info("nathan", catalog);
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 0 );

   // creating a map with bad json as value is not allowed
   catalog = "whatever";
   pairs.clear();
   pairs["key"] = "value";
   map_operation(pairs, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   storage_results_nathan = custom_operations_api.get_storage_info("nathan", catalog);
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 0 );

   // nathan adds key-value data via custom operation to a settings catalog
   catalog = "settings";
   pairs.clear();
   pairs["language"] = fc::json::to_string("en");
   pairs["image_url"] = fc::json::to_string("http://some.image.url/img.jpg");
   map_operation(pairs, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // check nathan stored data with the api
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, "image_url");
   BOOST_CHECK_EQUAL(storage_results_nathan[0].value->as_string(), "http://some.image.url/img.jpg");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[1].key, "language");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].value->as_string(), "en");

   // edit some stuff and add new stuff
   pairs.clear();
   pairs["image_url"] = fc::json::to_string("http://new.image.url/newimg.jpg");
   pairs["theme"] = fc::json::to_string("dark");
   map_operation(pairs, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // check old and new stuff
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 3 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, "image_url");
   BOOST_CHECK_EQUAL(storage_results_nathan[0].value->as_string(), "http://new.image.url/newimg.jpg");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[1].key, "language");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].value->as_string(), "en");
   BOOST_CHECK_EQUAL(storage_results_nathan[2].key, "theme");
   BOOST_CHECK_EQUAL(storage_results_nathan[2].value->as_string(), "dark");

   // delete stuff from the storage
   pairs.clear();
   pairs["theme"] = fc::json::to_string("dark");
   map_operation(pairs, true, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // theme is removed from the storage
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, "image_url");
   BOOST_CHECK_EQUAL(storage_results_nathan[0].value->as_string(), "http://new.image.url/newimg.jpg");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[1].key, "language");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].value->as_string(), "en");

   // delete stuff that it is not there
   pairs.clear();
   pairs["nothere"] = fc::json::to_string("nothere");
   map_operation(pairs, true, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // nothing changes
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, "image_url");
   BOOST_CHECK_EQUAL(storage_results_nathan[0].value->as_string(), "http://new.image.url/newimg.jpg");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[1].key, "language");
   BOOST_CHECK_EQUAL(storage_results_nathan[1].value->as_string(), "en");

   // alice, duplicated keys in storage, only second value will be added
   pairs.clear();
   catalog = "random";
   pairs["key1"] = fc::json::to_string("value1");
   pairs["key1"] = fc::json::to_string("value2");
   map_operation(pairs, false, catalog, alice_id, alice_private_key, db);
   generate_block();

   vector<account_storage_object> storage_results_alice = custom_operations_api.get_storage_info("alice", "random");
   BOOST_CHECK_EQUAL(storage_results_alice.size(), 1 );
   BOOST_CHECK_EQUAL(storage_results_alice[0].account.instance.value, 17 );
   BOOST_CHECK_EQUAL(storage_results_alice[0].key, "key1");
   BOOST_CHECK_EQUAL(storage_results_alice[0].value->as_string(), "value2");

   // add an object
   pairs.clear();
   catalog = "account_object";
   pairs["nathan"] = fc::json::to_string(nathan);
   map_operation(pairs, false, catalog, alice_id, alice_private_key, db);
   generate_block();

   storage_results_alice = custom_operations_api.get_storage_info("alice", "account_object");
   BOOST_CHECK_EQUAL(storage_results_alice.size(), 1);
   BOOST_CHECK_EQUAL(storage_results_alice[0].account.instance.value, 17);
   BOOST_CHECK_EQUAL(storage_results_alice[0].key, "nathan");
   BOOST_CHECK_EQUAL(storage_results_alice[0].value->as<account_object>(20).name, "nathan");

   // add 2 more objects
   pairs.clear();
   catalog = "account_object";
   pairs["robert"] = fc::json::to_string(robert);
   pairs["patty"] = fc::json::to_string(patty);
   map_operation(pairs, false, catalog, alice_id, alice_private_key, db);
   generate_block();

   storage_results_alice = custom_operations_api.get_storage_info("alice", "account_object");
   BOOST_CHECK_EQUAL(storage_results_alice.size(), 3);
   BOOST_CHECK_EQUAL(storage_results_alice[0].account.instance.value, 17);
   BOOST_CHECK_EQUAL(storage_results_alice[0].key, "nathan");
   BOOST_CHECK_EQUAL(storage_results_alice[0].value->as<account_object>(20).name, "nathan");
   BOOST_CHECK_EQUAL(storage_results_alice[1].account.instance.value, 17);
   BOOST_CHECK_EQUAL(storage_results_alice[1].key, "patty");
   BOOST_CHECK_EQUAL(storage_results_alice[1].value->as<account_object>(20).name, "patty");
   BOOST_CHECK_EQUAL(storage_results_alice[2].key, "robert");
   BOOST_CHECK_EQUAL(storage_results_alice[2].value->as<account_object>(20).name, "robert");
}
catch (fc::exception &e) {
   edump((e.to_detail_string()));
   throw;
} }

BOOST_AUTO_TEST_CASE(custom_operations_account_storage_list_test)
{
try {
   ACTORS((nathan)(alice)(robert)(patty));

   app.enable_plugin("custom_operations");
   custom_operations_api custom_operations_api(app);

   generate_block();
   enable_fees();

   int64_t init_balance(10000 * GRAPHENE_BLOCKCHAIN_PRECISION);

   transfer(committee_account, nathan_id, asset(init_balance));
   transfer(committee_account, alice_id, asset(init_balance));

   // catalog is indexed so cant be too big(greater than CUSTOM_OPERATIONS_MAX_KEY_SIZE(200) is not allowed)
   std::string catalog(201, 'a');
   flat_map<string, optional<string>> accounts;
   accounts[robert.name];
   map_operation(accounts, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   auto storage_results_nathan = custom_operations_api.get_storage_info("nathan", catalog);
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 0 );

   // keys are indexed so they cant be too big(greater than CUSTOM_OPERATIONS_MAX_KEY_SIZE(200) is not allowed)
   catalog = "whatever";
   std::string value(201, 'a');
   accounts.clear();
   accounts[value];
   map_operation(accounts, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   storage_results_nathan = custom_operations_api.get_storage_info("nathan", catalog);
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 0 );

   // nathan add a list of accounts to storage
   accounts.clear();
   accounts[alice.name];
   accounts[robert.name];
   catalog = "contact_list";
   map_operation(accounts, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // get the account list for nathan, check alice and robert are there
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "contact_list");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, alice.name);
   BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[1].key, robert.name);

   // add a value into account list already there
   accounts.clear();
   accounts[alice.name];
   map_operation(accounts, false, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // nothing changes
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "contact_list");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, alice.name);
   BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[1].key, robert.name);

   // delete alice from the list
   accounts.clear();
   accounts[alice.name];
   map_operation(accounts, true, catalog, nathan_id, nathan_private_key, db);
   generate_block();

   // alice gone
   storage_results_nathan = custom_operations_api.get_storage_info("nathan", "contact_list");
   BOOST_CHECK_EQUAL(storage_results_nathan.size(), 1 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 );
   BOOST_CHECK_EQUAL(storage_results_nathan[0].key, robert.name);

   // duplicated accounts in the list, only 1 will be inserted
   accounts.clear();
   accounts[robert.name];
   accounts[robert.name];
   map_operation(accounts, false, catalog, alice_id, alice_private_key, db);
   generate_block();

   auto storage_results_alice = custom_operations_api.get_storage_info("alice", "contact_list");
   BOOST_CHECK_EQUAL(storage_results_alice.size(), 1 );
   BOOST_CHECK_EQUAL(storage_results_alice[0].account.instance.value, 17 );
   BOOST_CHECK_EQUAL(storage_results_alice[0].key, robert.name);
}
catch (fc::exception &e) {
   edump((e.to_detail_string()));
   throw;
} }

BOOST_AUTO_TEST_SUITE_END()

ext: cpp

max_stars_repo_name: hammadsherwani/bitshares-core

max_issues_repo_name: hammadsherwani/bitshares-core

max_forks_repo_name: hammadsherwani/bitshares-core


text:
#define BOOST_TEST_MODULE cmc_test
#include <boost/test/unit_test.hpp>
#include "coinmarketcap.hpp"

using namespace cwo;

BOOST_AUTO_TEST_CASE(ctors)
{
//  CMC m("<api-key>");
}

BOOST_AUTO_TEST_CASE(GetPriceForCryptoInCurrency)
{
//  CMC m("<api-key>");
//  std::vector<CRYPTOTYPE> t = {ETH, VET, BTC};
//  m.crypto(t)->currency(EUR)->update();
//  std::cout << m.price(ETH) << std::endl;
//  std::cout << m.price(VET) << std::endl;
//  std::cout << m.price(BTC) << std::endl;
}

max_stars_repo_name: ndzik/coinwalletoverview

max_issues_repo_name: ndzik/coinwalletoverview

max_forks_repo_name: ndzik/coinwalletoverview


text:
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)

Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/align/align_down.hpp>
#include <boost/core/lightweight_test.hpp>

template<std::size_t N>
struct A { };

template<class T, std::size_t N>
void test(A<N>)
{
    T v1 = N;
    BOOST_TEST(boost::alignment::align_down(v1, N) == v1);
    T v2 = N + 1;
    BOOST_TEST(boost::alignment::align_down(v2, N) == v1);
}

template<class T>
void test(A<1>)
{
    T v = 1;
    BOOST_TEST(boost::alignment::align_down(v, 1) == v);
}

template<class T>
void test()
{
    test<T>(A<1>());
    test<T>(A<2>());
    test<T>(A<4>());
    test<T>(A<8>());
    test<T>(A<16>());
    test<T>(A<32>());
    test<T>(A<64>());
    test<T>(A<128>());
}

int main()
{
    test<int>();
    test<unsigned>();
    test<long>();
    test<unsigned long>();
    test<short>();
    test<unsigned short>();
#if !defined(BOOST_NO_LONG_LONG)
    test<long long>();
    test<unsigned long long>();
#endif
    test<std::size_t>();
    test<std::ptrdiff_t>();

    return boost::report_errors();
}


text:
/*

Copyright (c) 2005-2015, University of Oxford.
All rights reserved.

University of Oxford means the Chancellor, Masters and Scholars of the
University of Oxford, having an administrative office at Wellington
Square, Oxford OX1 2JD, UK.

This file is part of Chaste.

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 University of Oxford 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 HOLDER 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 TESTCELLPOPULATIONCOUNTWRITERS_HPP_
#define TESTCELLPOPULATIONCOUNTWRITERS_HPP_

#include <cxxtest/TestSuite.h>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include "ArchiveOpener.hpp"
#include "AbstractCellBasedTestSuite.hpp"
#include "FileComparison.hpp"

// Cell population count writers
#include "CellMutationStatesCountWriter.hpp"
#include "CellProliferativePhasesCountWriter.hpp"
#include "CellProliferativeTypesCountWriter.hpp"

// Files to create populations
#include "HoneycombVertexMeshGenerator.hpp"
#include "HoneycombMeshGenerator.hpp"
#include "PottsMeshGenerator.hpp"
#include "CellsGenerator.hpp"
#include "FixedDurationGenerationBasedCellCycleModel.hpp"

#include "MeshBasedCellPopulation.hpp"
#include "MeshBasedCellPopulationWithGhostNodes.hpp"
#include "CaBasedCellPopulation.hpp"
#include "NodeBasedCellPopulation.hpp"
#include "NodeBasedCellPopulationWithBuskeUpdate.hpp"
#include "NodeBasedCellPopulationWithParticles.hpp"
#include "PottsBasedCellPopulation.hpp"
#include "VertexBasedCellPopulation.hpp"

#include "PetscSetupAndFinalize.hpp"

class TestCellPopulationCountWriters : public AbstractCellBasedTestSuite
{
public:

    void TestCellMutationStatesCountWriter() throw (Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a simple 2D CaBasedCellPopulation
        PottsMeshGenerator<2> generator(5, 0, 0, 5, 0, 0);
        PottsMesh<2>* p_mesh = generator.GetMesh();
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, 5u);
        std::vector<unsigned> location_indices;
        location_indices.push_back(7);
        location_indices.push_back(11);
        location_indices.push_back(12);
        location_indices.push_back(13);
        location_indices.push_back(17);
        CaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices);

        cell_population.AddCellPopulationCountWriter<CellMutationStatesCountWriter>();

        // Create an output directory for the writer
        std::string output_directory = "TestCellMutationStatesCountWriter";
        OutputFileHandler output_file_handler(output_directory, false);
        std::string results_dir = output_file_handler.GetOutputDirectoryFullPath();

        // Create a CellMutationStatesCountWriter and test that the correct output is generated
        CellMutationStatesCountWriter<2,2> mutation_states_writer;
        mutation_states_writer.OpenOutputFile(output_file_handler);
        mutation_states_writer.WriteHeader(&cell_population);
        mutation_states_writer.WriteTimeStamp();
        mutation_states_writer.Visit(&cell_population);
        mutation_states_writer.WriteNewline();
        mutation_states_writer.CloseFile();

        FileComparison(results_dir + "cellmutationstates.dat", "cell_based/test/data/TestCellPopulationCountWriters/cellmutationstates.dat").CompareFiles();

        // Test that we can append to files
        mutation_states_writer.OpenOutputFileForAppend(output_file_handler);
        mutation_states_writer.WriteTimeStamp();
        mutation_states_writer.Visit(&cell_population);
        mutation_states_writer.WriteNewline();
        mutation_states_writer.CloseFile();

        FileComparison(results_dir + "cellmutationstates.dat", "cell_based/test/data/TestCellPopulationCountWriters/cellmutationstates_twice.dat").CompareFiles();
    }

    void TestCellMutationStatesCountWriterArchiving() throw (Exception)
    {
        // The purpose of this test is to check that archiving can be done for this class
        OutputFileHandler handler("archive", false);
        std::string archive_filename = handler.GetOutputDirectoryFullPath() + "CellMutationStatesCountWriter.arch";

        {
            AbstractCellBasedWriter<2,2>* const p_population_writer = new CellMutationStatesCountWriter<2,2>();
            std::ofstream ofs(archive_filename.c_str());
            boost::archive::text_oarchive output_arch(ofs);
            output_arch << p_population_writer;
            delete p_population_writer;
        }
        PetscTools::Barrier(); //Processes read after last process has (over-)written archive
        {
            AbstractCellBasedWriter<2,2>* p_population_writer_2;
            std::ifstream ifs(archive_filename.c_str(), std::ios::binary);
            boost::archive::text_iarchive input_arch(ifs);
            input_arch >> p_population_writer_2;
            delete p_population_writer_2;
       }
    }

    void TestCellProliferativePhasesCountWriters() throw (Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a simple 3D MeshBasedCellPopulation
        std::vector<Node<3>*> nodes;
        nodes.push_back(new Node<3>(0, true,  0.0, 0.0, 0.0));
        nodes.push_back(new Node<3>(1, true,  1.0, 1.0, 0.0));
        nodes.push_back(new Node<3>(2, true,  1.0, 0.0, 1.0));
        nodes.push_back(new Node<3>(3, true,  0.0, 1.0, 1.0));
        nodes.push_back(new Node<3>(4, false, 0.5, 0.5, 0.5));
        MutableMesh<3,3> mesh(nodes);
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 3> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());
        MeshBasedCellPopulation<3> cell_population(mesh, cells);

        cell_population.AddCellPopulationCountWriter<CellProliferativePhasesCountWriter>();

        // Create an output directory for the writer
        std::string output_directory = "TestCellProliferativePhasesCountWriter";
        OutputFileHandler output_file_handler(output_directory, false);
        std::string results_dir = output_file_handler.GetOutputDirectoryFullPath();

        // Create a CellProliferativePhasesCountWriter and test that the correct output is generated
        CellProliferativePhasesCountWriter<3,3> phases_count_writer;
        phases_count_writer.OpenOutputFile(output_file_handler);
        phases_count_writer.WriteTimeStamp();
        phases_count_writer.Visit(&cell_population);
        phases_count_writer.WriteNewline();
        phases_count_writer.CloseFile();

        FileComparison(results_dir + "cellcyclephases.dat", "cell_based/test/data/TestCellPopulationCountWriters/cellcyclephases.dat").CompareFiles();

        // Test that we can append to files
        phases_count_writer.OpenOutputFileForAppend(output_file_handler);
        phases_count_writer.WriteTimeStamp();
        phases_count_writer.Visit(&cell_population);
        phases_count_writer.WriteNewline();
        phases_count_writer.CloseFile();

        FileComparison(results_dir + "cellcyclephases.dat", "cell_based/test/data/TestCellPopulationCountWriters/cellcyclephases_twice.dat").CompareFiles();
    }

    void TestCellProliferativePhasesCountWriterArchiving() throw (Exception)
    {
        // The purpose of this test is to check that archiving can be done for this class
        OutputFileHandler handler("archive", false);
        std::string archive_filename = handler.GetOutputDirectoryFullPath() + "CellProliferativePhasesCountWriter.arch";

        {
            AbstractCellBasedWriter<2,2>* const p_population_writer = new CellProliferativePhasesCountWriter<2,2>();
            std::ofstream ofs(archive_filename.c_str());
            boost::archive::text_oarchive output_arch(ofs);
            output_arch << p_population_writer;
            delete p_population_writer;
        }
        PetscTools::Barrier(); //Processes read after last process has (over-)written archive
        {
            AbstractCellBasedWriter<2,2>* p_population_writer_2;
            std::ifstream ifs(archive_filename.c_str(), std::ios::binary);
            boost::archive::text_iarchive input_arch(ifs);
            input_arch >> p_population_writer_2;
            delete p_population_writer_2;
       }
    }

    void TestCellProliferativeTypesCountWriters() throw (Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a simple 3D MeshBasedCellPopulation
        std::vector<Node<3>*> nodes;
        nodes.push_back(new Node<3>(0, true,  0.0, 0.0, 0.0));
        nodes.push_back(new Node<3>(1, true,  1.0, 1.0, 0.0));
        nodes.push_back(new Node<3>(2, true,  1.0, 0.0, 1.0));
        nodes.push_back(new Node<3>(3, true,  0.0, 1.0, 1.0));
        nodes.push_back(new Node<3>(4, false, 0.5, 0.5, 0.5));
        MutableMesh<3,3> mesh(nodes);
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 3> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());
        MeshBasedCellPopulation<3> cell_population(mesh, cells);

        cell_population.AddCellPopulationCountWriter<CellProliferativeTypesCountWriter>();

        // An ordering must be specified for cell mutation states and cell proliferative types
        cell_population.SetDefaultCellMutationStateAndProliferativeTypeOrdering();

        // Create an output directory for the writer
        std::string output_directory = "TestCellProliferativeTypesCountWriter";
        OutputFileHandler output_file_handler(output_directory, false);
        std::string results_dir = output_file_handler.GetOutputDirectoryFullPath();

        // Create a CellProliferativeTypesCountWriter and test that the correct output is generated
        CellProliferativeTypesCountWriter<3,3> types_count_writer;
        types_count_writer.OpenOutputFile(output_file_handler);
        types_count_writer.WriteTimeStamp();
        types_count_writer.Visit(&cell_population);
        types_count_writer.WriteNewline();
        types_count_writer.CloseFile();

        FileComparison(results_dir + "celltypes.dat", "cell_based/test/data/TestCellPopulationCountWriters/celltypes.dat").CompareFiles();

        // Test that we can append to files
        types_count_writer.OpenOutputFileForAppend(output_file_handler);
        types_count_writer.WriteTimeStamp();
        types_count_writer.Visit(&cell_population);
        types_count_writer.WriteNewline();
        types_count_writer.CloseFile();

        FileComparison(results_dir + "celltypes.dat", "cell_based/test/data/TestCellPopulationCountWriters/celltypes_twice.dat").CompareFiles();
    }

    void TestCellProliferativeTypesCountWriterArchiving() throw (Exception)
    {
        // The purpose of this test is to check that archiving can be done for this class
        OutputFileHandler handler("archive", false);
        std::string archive_filename = handler.GetOutputDirectoryFullPath() + "CellProliferativeTypesCountWriter.arch";

        {
            AbstractCellBasedWriter<2,2>* const p_population_writer = new CellProliferativeTypesCountWriter<2,2>();
            std::ofstream ofs(archive_filename.c_str());
            boost::archive::text_oarchive output_arch(ofs);
            output_arch << p_population_writer;
            delete p_population_writer;
        }
        PetscTools::Barrier(); //Processes read after last process has (over-)written archive
        {
            AbstractCellBasedWriter<2,2>* p_population_writer_2;
            std::ifstream ifs(archive_filename.c_str(), std::ios::binary);
            boost::archive::text_iarchive input_arch(ifs);
            input_arch >> p_population_writer_2;
            delete p_population_writer_2;
       }
    }
};

#endif /*TESTCELLPOPULATIONCOUNTWRITERS_HPP_*/

max_stars_repo_name: ktunya/ChasteMod

max_issues_repo_name: ktunya/ChasteMod

max_forks_repo_name: ktunya/ChasteMod


text:
//
// Copyright 2016 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python.hpp>
#include <boost/python/converter/from_python.hpp>

#include "pxr/usdImaging/usdImagingGL/rendererSettings.h"

using namespace boost::python;

PXR_NAMESPACE_USING_DIRECTIVE

void
wrapRendererSettings()
{
    // Wrap the UsdImagingGLRendererSetting::Type enum. Accessible as
    // UsdImagingGL.RendererSettingType.
    enum_<UsdImagingGLRendererSetting::Type>("RendererSettingType")
            .value("FLAG", UsdImagingGLRendererSetting::TYPE_FLAG)
            .value("INT", UsdImagingGLRendererSetting::TYPE_INT)
            .value("FLOAT", UsdImagingGLRendererSetting::TYPE_FLOAT)
            .value("STRING", UsdImagingGLRendererSetting::TYPE_STRING)
    ;

    // Wrap the UsdImagingGLRendererSetting struct.
    // Accessible as UsdImagingGL.RendererSetting
    typedef UsdImagingGLRendererSetting Setting;
    class_<UsdImagingGLRendererSetting>("RendererSetting",
            "Renderer Setting Metadata")
        .add_property("key", make_getter(&Setting::key,
                return_value_policy<return_by_value>()))
        .def_readonly("name", &Setting::name)
        .def_readonly("type", &Setting::type)
        .add_property("defValue", make_getter(&Setting::defValue,
                return_value_policy<return_by_value>()))
        ;
}

max_stars_repo_name: DougRogers-DigitalFish/USD

max_issues_repo_name: DougRogers-DigitalFish/USD

max_forks_repo_name: DougRogers-DigitalFish/USD


text:
// Copyright (c) 2015-2018 Daniel Cooke
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

#include "denovo_contamination.hpp"

#include <algorithm>
#include <iterator>
#include <array>

#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include <boost/range/combine.hpp>

#include "basics/trio.hpp"
#include "core/types/allele.hpp"
#include "core/types/haplotype.hpp"
#include "core/types/genotype.hpp"
#include "core/tools/read_assigner.hpp"
#include "io/variant/vcf_record.hpp"
#include "utils/genotype_reader.hpp"
#include "utils/concat.hpp"
#include "utils/append.hpp"
#include "is_denovo.hpp"
#include "../facets/samples.hpp"
#include "../facets/genotypes.hpp"
#include "../facets/pedigree.hpp"
#include "../facets/read_assignments.hpp"

namespace octopus { namespace csr {

const std::string DeNovoContamination::name_ = "DC";

std::unique_ptr<Measure> DeNovoContamination::do_clone() const
{
    return std::make_unique<DeNovoContamination>(*this);
}

namespace {

bool is_denovo(const VcfRecord& call, const Measure::FacetMap& facets)
{
    return boost::get<bool>(IsDenovo(false).evaluate(call, facets));
}

auto find_child_idx(const std::vector<SampleName>& samples, const octopus::Pedigree& pedigree)
{
    assert(samples.size() == 3);
    if (is_parent_of(samples[0], samples[1], pedigree)) {
        return 1;
    } else if (is_parent_of(samples[1], samples[0], pedigree)) {
        return 0;
    } else {
        return 2;
    }
}

template <typename Container>
void sort_unique(Container& values)
{
    std::sort(std::begin(values), std::end(values));
    values.erase(std::unique(std::begin(values), std::end(values)), std::end(values));
}

auto get_denovo_alleles(const VcfRecord& denovo, const Trio& trio)
{
    auto parent_alleles = concat(get_called_alleles(denovo, trio.mother(), true).first,
                                 get_called_alleles(denovo, trio.father(), true).first);
    auto child_alleles = get_called_alleles(denovo, trio.child(), true).first;
    sort_unique(parent_alleles); sort_unique(child_alleles);
    std::vector<Allele> result {};
    result.reserve(child_alleles.size());
    std::set_difference(std::cbegin(child_alleles), std::cend(child_alleles),
                        std::cbegin(parent_alleles), std::cend(parent_alleles),
                        std::back_inserter(result));
    return result;
}

auto get_denovo_haplotypes(const Facet::GenotypeMap& genotypes, const std::vector<Allele>& denovos)
{
    std::vector<Haplotype> result {};
    if (!denovos.empty()) {
        const auto allele_region = denovos.front().mapped_region();
        for (const auto& p : genotypes) {
            const auto& overlapped_genotypes = overlap_range(p.second, allele_region);
            if (size(overlapped_genotypes) == 1) {
                const auto& genotype = overlapped_genotypes.front();
                for (const auto& haplotype : genotype) {
                    if (std::any_of(std::cbegin(denovos), std::cend(denovos),
                                    [&] (const auto& denovo) { return haplotype.includes(denovo); })) {
                        result.push_back(haplotype);
                    }
                }
            }
        }
        sort_unique(result);
    }
    return result;
}

bool contains(const MappableFlatSet<Genotype<Haplotype>>& genotypes, const Haplotype& haplotype)
{
    return std::any_of(std::cbegin(genotypes), std::cend(genotypes), [&] (const auto& genotype) { return genotype.contains(haplotype); });
}

bool is_parental_haplotype(const Haplotype& haplotype, const Facet::GenotypeMap& genotypes, const Trio& trio)
{
    return contains(genotypes.at(trio.mother()), haplotype) || contains(genotypes.at(trio.father()), haplotype);
}

auto get_denovo_haplotypes(const VcfRecord& denovo, const Facet::GenotypeMap& genotypes, const Trio& trio)
{
    const auto denovo_alleles = get_denovo_alleles(denovo, trio);
    auto result = get_denovo_haplotypes(genotypes, denovo_alleles);
    const auto is_parental = [&] (const auto& haplotype) { return is_parental_haplotype(haplotype, genotypes, trio); };
    result.erase(std::remove_if(std::begin(result), std::end(result), is_parental), std::end(result));
    return result;
}

template <typename MappableType>
auto copy_overlapped_to_vector(const AmbiguousReadList& reads, const MappableType& mappable)
{
    const auto overlapped = overlap_range(reads, mappable);
    std::vector<AlignedRead> result {};
    result.reserve(size(overlapped));
    std::transform(std::cbegin(overlapped), std::cend(overlapped), std::back_inserter(result),
                   [] (const auto& read) { return read.read; });
    return result;
}

} // namespace

Measure::ResultType DeNovoContamination::do_evaluate(const VcfRecord& call, const FacetMap& facets) const
{
    boost::optional<int> result {};
    if (is_denovo(call, facets)) {
        const auto& samples = get_value<Samples>(facets.at("Samples"));
        const auto& pedigree = get_value<Pedigree>(facets.at("Pedigree"));
        assert(is_trio(samples, pedigree)); // TODO: Implement for general pedigree
        const auto trio = *make_trio(samples[find_child_idx(samples, pedigree)], pedigree);
        const auto& genotypes = get_value<Genotypes>(facets.at("Genotypes"));
        const auto denovo_haplotypes = get_denovo_haplotypes(call, genotypes, trio);
        if (denovo_haplotypes.empty()) {
            return result;
        }
        const auto& assignments = get_value<ReadAssignments>(facets.at("ReadAssignments"));
        Genotype<Haplotype> denovo_genotype {static_cast<unsigned>(denovo_haplotypes.size() + 1)};
        HaplotypeProbabilityMap haplotype_priors {};
        haplotype_priors.reserve(denovo_haplotypes.size() + 1);
        for (const auto& haplotype : denovo_haplotypes) {
            assert(is_same_region(haplotype, denovo_haplotypes.front()));
            denovo_genotype.emplace(haplotype);
            haplotype_priors[haplotype] = -1;
        }
        const std::array<SampleName, 2> parents {trio.mother(), trio.father()};
        result = 0;
        for (const auto& sample : parents) {
            for (const auto& p : assignments.support.at(sample)) {
                auto supporting_reads = copy_overlapped(p.second, call);
                if (!supporting_reads.empty()) {
                    const Haplotype& assigned_haplotype {p.first};
                    if (!denovo_genotype.contains(assigned_haplotype)) {
                        auto dummy = denovo_genotype;
                        dummy.emplace(assigned_haplotype);
                        haplotype_priors[assigned_haplotype] = 0;
                        const auto support = compute_haplotype_support(dummy, supporting_reads, haplotype_priors);
                        haplotype_priors.erase(assigned_haplotype);
                        for (const auto& denovo : denovo_haplotypes) {
                            if (support.count(denovo) == 1) {
                                *result += support.at(denovo).size();
                            }
                        }
                    } else {
                        // This could happen if we don't call all 'de novo' alleles on the called de novo haplotype.
                        *result += supporting_reads.size();
                    }
                }
            }
            if (assignments.ambiguous.count(sample) == 1 && !assignments.ambiguous.at(sample).empty()) {
                const auto ambiguous_reads = copy_overlapped_to_vector(assignments.ambiguous.at(sample), call);
                if (!ambiguous_reads.empty()) {
                    const auto overlapped_genotypes = overlap_range(genotypes.at(sample), call);
                    if (size(overlapped_genotypes) == 1) {
                        const auto& called_genotype = overlapped_genotypes.front();
                        auto dummy = called_genotype;
                        for (const auto& haplotype : denovo_haplotypes) {
                            dummy.emplace(haplotype);
                        }
                        for (const auto& haplptype : called_genotype) {
                            haplotype_priors[haplptype] = 0;
                        }
                        const auto support = compute_haplotype_support(dummy, ambiguous_reads, haplotype_priors);
                        for (const auto& haplotype : called_genotype) {
                            haplotype_priors.erase(haplotype);
                        }
                        for (const auto& denovo : denovo_haplotypes) {
                            if (support.count(denovo) == 1) {
                                *result += support.at(denovo).size();
                            }
                        }
                    }
                }
            }
        }
    }
    return result;
}

Measure::ResultCardinality DeNovoContamination::do_cardinality() const noexcept
{
    return ResultCardinality::one;
}

const std::string& DeNovoContamination::do_name() const
{
    return name_;
}

std::string DeNovoContamination::do_describe() const
{
    return "Number of reads supporting a de novo haplotype in the normal";
}

std::vector<std::string> DeNovoContamination::do_requirements() const
{
    std::vector<std::string> result {"Samples", "Genotypes", "ReadAssignments", "Pedigree"};
    utils::append(IsDenovo(false).requirements(), result);
    sort_unique(result);
    return result;
}

} // namespace csr
} // namespace octopus

max_stars_repo_name: gmagoon/octopus

max_issues_repo_name: gmagoon/octopus

max_forks_repo_name: gmagoon/octopus


text:
#include "tally.h"
#include "main.h"

#include <boost/test/unit_test.hpp>
#include <memory>
#include <vector>

namespace
{
    typedef std::shared_ptr<CBlockIndex> CBlockIndexPtr;
    std::vector<CBlockIndexPtr> CreateChain()
    {
        std::vector<CBlockIndexPtr> blocks;

        // Create a chain of 100 blocks
        for(int i=1; i<=100; ++i)
        {
            CBlockIndexPtr block = std::make_shared<CBlockIndex>();
            block->nHeight = i;

            // Attach to chain
            if(!blocks.empty())
            {
                CBlockIndexPtr previous = blocks.back();
                previous->pnext = block.get();
                block->pprev = previous.get();
            }

            blocks.push_back(block);
        }

        return blocks;
    }
}

BOOST_AUTO_TEST_SUITE(tally_tests)

BOOST_AUTO_TEST_CASE(tally_FindTallyTriggerShouldUseTallyGranularity)
{
    BOOST_CHECK_EQUAL(TALLY_GRANULARITY, 10);

    auto chain = CreateChain();
    CBlockIndexPtr head = chain.back();

    const CBlockIndex* block = FindTallyTrigger(head.get()->pprev);
    BOOST_CHECK_EQUAL(block->nHeight, 90);
}

BOOST_AUTO_TEST_CASE(tally_IsTallyTriggerShouldUseTallyGranularity)
{
    auto chain = CreateChain();
    CBlockIndexPtr head = chain.back();

    BOOST_CHECK(IsTallyTrigger(head.get()));
    BOOST_CHECK(IsTallyTrigger(head->pprev) == false);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: sweede-se/Gridcoin-Research

max_issues_repo_name: sweede-se/Gridcoin-Research

max_forks_repo_name: sweede-se/Gridcoin-Research


text:
/*
	Copyright (C) 2003-2014 by David White <davewx7@gmail.com>

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	   1. The origin of this software must not be misrepresented; you must not
	   claim that you wrote the original software. If you use this software
	   in a product, an acknowledgement in the product documentation would be
	   appreciated but is not required.

	   2. Altered source versions must be plainly marked as such, and must not be
	   misrepresented as being the original software.

	   3. This notice may not be removed or altered from any source
	   distribution.
*/

#pragma once

#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <map>

#include "variant.hpp"

namespace http
{
	typedef std::map<std::string, std::string> environment;

	std::map<std::string, std::string> parse_http_headers(std::string& str);

	struct WebServerProxyInfo;

	class web_server
	{
	public:

		struct SocketInfo {
			explicit SocketInfo(boost::asio::io_service& service);
			boost::asio::ip::tcp::socket socket;
			int client_version;
			bool supports_deflate;
		};

		typedef std::shared_ptr<SocketInfo> socket_ptr;
		typedef std::shared_ptr<boost::array<char, 64*1024> > buffer_ptr;

		explicit web_server(boost::asio::io_service& io_service, int port=23456);
		virtual ~web_server();

		void connect_proxy(uint32_t session_id, const std::string& host, const std::string& port);

		void keepalive_socket(socket_ptr socket);

		static void disconnect_socket(socket_ptr socket);

	protected:
		void start_accept();
		void handle_accept(socket_ptr socket, const boost::system::error_code& error);

		void send_msg(socket_ptr socket, const std::string& mime_type, const std::string& msg, const std::string& header_parms);
		void send_404(socket_ptr socket);

		void handle_send(socket_ptr socket, const boost::system::error_code& e, size_t nbytes, size_t max_bytes, std::shared_ptr<std::string> buf);

		virtual void disconnect(socket_ptr socket);

		virtual void handlePost(socket_ptr socket, variant doc, const environment& env, const std::string& raw_msg) = 0;
		virtual void handleGet(socket_ptr socket, const std::string& url, const std::map<std::string, std::string>& args) = 0;

	private:

		std::vector<std::shared_ptr<WebServerProxyInfo>> proxies_;

		struct receive_buf {
			receive_buf() : wanted(0) {}
			std::string msg;
			size_t wanted;
		};
		typedef std::shared_ptr<receive_buf> receive_buf_ptr;

	public:
		void start_receive(socket_ptr socket, receive_buf_ptr buf=receive_buf_ptr());

	private:

		void handle_receive(socket_ptr socket, buffer_ptr buf, const boost::system::error_code& e, size_t nbytes, receive_buf_ptr recv_buf);
		void handle_incoming_data(socket_ptr socket, const char* i1, const char* i2, receive_buf_ptr recv_buf);

		void handle_message(socket_ptr socket, receive_buf_ptr recv_buf);

		virtual variant parse_message(const std::string& msg) const;

		boost::asio::io_service& io_service_;
		std::shared_ptr<boost::asio::ip::tcp::acceptor> acceptor_;
	};
}

max_stars_repo_name: gamobink/anura

max_issues_repo_name: gamobink/anura

max_forks_repo_name: gamobink/anura


text:
#include "mexpr.hpp"
//#include "error_handler.hpp"
#include <boost/spirit/include/phoenix_function.hpp>

namespace client { namespace math { namespace parser
{
    template <typename Iterator>
    expression<Iterator>::expression(error_handler<Iterator>& error_handler)
      : expression::base_type(expr)
    {
        qi::_1_type _1;
        qi::_2_type _2;
        qi::_3_type _3;
        qi::_4_type _4;

        qi::char_type char_;
        qi::uint_type uint_;
        qi::_val_type _val;
        qi::raw_type raw;
        qi::lexeme_type lexeme;
        qi::alpha_type alpha;
        qi::alnum_type alnum;
        qi::bool_type bool_;
        qi::double_type double_;

        using qi::on_error;
        using qi::on_success;
        using qi::fail;
        using boost::phoenix::function;

        typedef function<client::error_handler<Iterator> > error_handler_function;

        additive_op.add
            ("+", ast::optoken::plus)
            ("-", ast::optoken::minus)
            ;

        multiplicative_op.add
            ("*", ast::optoken::times)
            ("/", ast::optoken::divide)
            ;

        unary_op.add
            ("+", ast::optoken::positive)
            ("-", ast::optoken::negative)
            ;
        keywords.add
            ("true")
            ("false")
            ;

        ///////////////////////////////////////////////////////////////////////
        // Main expression grammar
        expr =
            additive_expr.alias()
            ;

        additive_expr =
                multiplicative_expr
            >> *(additive_op >> multiplicative_expr)
            ;

        multiplicative_expr =
                unary_expr
            >> *(multiplicative_op >> unary_expr)
            ;

        unary_expr =
                primary_expr
            |   (unary_op >> primary_expr)
            ;

        primary_expr =
                double_
            |   identifier
            |   colIndex
            |   '(' >> expr >> ')'
            ;

        identifier = '$' >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]];

        colIndex = '$' >> uint_;
        ///////////////////////////////////////////////////////////////////////
        // Debugging and error handling and reporting support.
        BOOST_SPIRIT_DEBUG_NODES(
            (expr)
            (additive_expr)
            (multiplicative_expr)
            (unary_expr)
            (primary_expr)
            (identifier)
            (colIndex)
        );

        ///////////////////////////////////////////////////////////////////////
        // Error handling: on error in expr, call error_handler.
        on_error<fail>(expr,
            error_handler_function(error_handler)(
                _4, _3, _2));

        ///////////////////////////////////////////////////////////////////////
        // Annotation: on success in primary_expr, call annotation.
        /*
        on_success(primary_expr,
            annotation_function(error_handler.iters)(_val, _1));
            */
    }
}}}

max_stars_repo_name: haptork/pawn

max_issues_repo_name: haptork/pawn

max_forks_repo_name: haptork/pawn


text:
#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>

//____________________________________________________________________________//

BOOST_AUTO_TEST_CASE( test )
{
    int i = 2;
    int j = 1;
    BOOST_REQUIRE_EQUAL( i, j );
}

//____________________________________________________________________________//

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema