<commit_before>#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#include "ascii_grid_loader.hpp"
#include "code/ylikuutio/geometry/spherical_world_struct.hpp"
#include "code/ylikuutio/triangulation/triangulate_quads_struct.hpp"
#include "code/ylikuutio/triangulation/quad_triangulation.hpp"
#include "code/ylikuutio/string/ylikuutio_string.hpp"
#include "code/ylikuutio/common/pi.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <cstdio>   // std::FILE, std::fclose, std::fopen, std::fread, std::getchar, std::printf etc.
#include <iostream> // std::cout, std::cin, std::cerr
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string, std::stoi
#include <vector>   // std::vector

namespace loaders
{
    bool load_ASCII_grid(
            const std::string& ASCII_grid_file_name,
            std::vector<glm::vec3>& out_vertices,
            std::vector<glm::vec2>& out_UVs,
            std::vector<glm::vec3>& out_normals,
            const int32_t x_step,
            const int32_t z_step,
            const std::string& triangulation_type)
    {
        // Beginning of `L4133D.asc`.
        //
        // ncols        3000
        // nrows        3000
        // xllcorner    386000.000000000000
        // yllcorner    6672000.000000000000
        // cellsize     2.000000000000
        // NODATA_value  -9999.000
        // 34.315 34.467 34.441 34.260 33.972 33.564 33.229 33.130 33.102 33.024 32.902 32.669 32.305 32.013 31.937 31.893 31.831 31.832

        std::cout << "Loading ascii grid file " << ASCII_grid_file_name << " ...\n";

        // Open the file
        const char* char_ASCII_grid_file_name = ASCII_grid_file_name.c_str();
        std::FILE* file = std::fopen(char_ASCII_grid_file_name, "rb");
        if (!file)
        {
            std::cerr << ASCII_grid_file_name << " could not be opened.\n";
            return false;
        }

        // Find out file size.
        if (std::fseek(file, 0, SEEK_END) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        int64_t file_size = std::ftell(file);

        if (file_size < 0)
        {
            std::cerr << "ftell failed for the file " << ASCII_grid_file_name << " !\n";
            std::fclose(file);
            return false;
        }

        // Move file pointer to the beginning of file.
        if (fseek(file, 0, SEEK_SET) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        // Reserve enough memory.
        char* point_data = new char[file_size];

        if (point_data == nullptr)
        {
            std::cerr << "Reserving memory for point data failed.\n";
            std::fclose(file);
            return false;
        }

        char* point_data_pointer = point_data;

        // Read the point data from the file into the buffer.
        // TODO: add check for file reading!
        std::fread(point_data, 1, file_size, file);

        // Everything is in memory now, the file can be closed
        std::fclose(file);

        // All possible block identifier strings.
        std::vector<std::string> number_strings_vector = { "-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        int32_t image_width = string::extract_int32_t_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "ncols");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        int32_t image_height = string::extract_int32_t_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "nrows");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "xllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "yllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "cellsize");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "nodata_value");

        // note: the value of `image_height_in_use` can be adjusted here (for testing purposes).
        int32_t image_height_in_use = image_height;

        float* vertex_data;
        vertex_data = new float[image_width * image_height_in_use];

        if (vertex_data == nullptr)
        {
            std::cerr << "Reserving memory for vertex data failed.\n";
            delete[] point_data;
            return false;
        }

        float* vertex_pointer;
        vertex_pointer = vertex_data;

        // start processing image_data.
        std::cout << "Processing image data.\n";

        int32_t last_percent = -1;
        int32_t current_percent = -1;

        for (int32_t z = 0; z < image_height_in_use; z++)
        {
            // show progress in percents.
            current_percent = static_cast<int32_t>(floor(100.0f * ((double) z / (double) (image_height_in_use - 1))));

            if (current_percent > last_percent)
            {
                std::cout << current_percent << "% ";
                last_percent = current_percent;
            }

            for (int32_t x = 0; x < image_width; x++)
            {
                while (!string::check_and_report_if_some_string_matches(point_data, point_data_pointer, file_size, number_strings_vector))
                {
                    point_data_pointer++;
                }
                *vertex_pointer++ = string::extract_float_value_from_string(
                        point_data,
                        --point_data_pointer,
                        file_size,
                        (const char* const) " \n",
                        (const char* const) nullptr);
            }
        }

        delete[] point_data;

        std::cout << "Triangulating ascii grid data.\n";

        geometry::TriangulateQuadsStruct triangulate_quads_struct;
        triangulate_quads_struct.image_width = image_width;
        triangulate_quads_struct.image_height = image_height_in_use;
        triangulate_quads_struct.x_step = x_step;
        triangulate_quads_struct.z_step = z_step;
        triangulate_quads_struct.triangulation_type = triangulation_type;
        triangulate_quads_struct.sphere_radius = NAN;
        triangulate_quads_struct.spherical_world_struct = geometry::SphericalWorldStruct(); // not used, but is needed in the function call.

        bool result = geometry::triangulate_quads(vertex_data, triangulate_quads_struct, out_vertices, out_UVs, out_normals);
        delete vertex_data;
        return result;
    }
}
<commit_msg>`load_ASCII_grid`: added check for file reading.<commit_after>#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#include "ascii_grid_loader.hpp"
#include "code/ylikuutio/geometry/spherical_world_struct.hpp"
#include "code/ylikuutio/triangulation/triangulate_quads_struct.hpp"
#include "code/ylikuutio/triangulation/quad_triangulation.hpp"
#include "code/ylikuutio/string/ylikuutio_string.hpp"
#include "code/ylikuutio/common/pi.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <cstdio>   // std::FILE, std::fclose, std::fopen, std::fread, std::getchar, std::printf etc.
#include <iostream> // std::cout, std::cin, std::cerr
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string, std::stoi
#include <vector>   // std::vector

namespace loaders
{
    bool load_ASCII_grid(
            const std::string& ASCII_grid_file_name,
            std::vector<glm::vec3>& out_vertices,
            std::vector<glm::vec2>& out_UVs,
            std::vector<glm::vec3>& out_normals,
            const int32_t x_step,
            const int32_t z_step,
            const std::string& triangulation_type)
    {
        // Beginning of `L4133D.asc`.
        //
        // ncols        3000
        // nrows        3000
        // xllcorner    386000.000000000000
        // yllcorner    6672000.000000000000
        // cellsize     2.000000000000
        // NODATA_value  -9999.000
        // 34.315 34.467 34.441 34.260 33.972 33.564 33.229 33.130 33.102 33.024 32.902 32.669 32.305 32.013 31.937 31.893 31.831 31.832

        std::cout << "Loading ascii grid file " << ASCII_grid_file_name << " ...\n";

        // Open the file
        const char* char_ASCII_grid_file_name = ASCII_grid_file_name.c_str();
        std::FILE* file = std::fopen(char_ASCII_grid_file_name, "rb");
        if (!file)
        {
            std::cerr << ASCII_grid_file_name << " could not be opened.\n";
            return false;
        }

        // Find out file size.
        if (std::fseek(file, 0, SEEK_END) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        int64_t file_size = std::ftell(file);

        if (file_size < 0)
        {
            std::cerr << "ftell failed for the file " << ASCII_grid_file_name << " !\n";
            std::fclose(file);
            return false;
        }

        // Move file pointer to the beginning of file.
        if (fseek(file, 0, SEEK_SET) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        // Reserve enough memory.
        char* point_data = new char[file_size];

        if (point_data == nullptr)
        {
            std::cerr << "Reserving memory for point data failed.\n";
            std::fclose(file);
            return false;
        }

        char* point_data_pointer = point_data;

        // Read the point data from the file into the buffer.
        if (std::fread(point_data, 1, file_size, file) != file_size)
        {
            std::cerr << "Error while reading " << ASCII_grid_file_name << "\n";
            std::fclose(file);
            return false;
        }

        // Everything is in memory now, the file can be closed
        std::fclose(file);

        // All possible block identifier strings.
        std::vector<std::string> number_strings_vector = { "-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        int32_t image_width = string::extract_int32_t_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "ncols");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        int32_t image_height = string::extract_int32_t_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "nrows");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "xllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "yllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "cellsize");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, file_size, number_strings_vector));
        string::extract_float_value_from_string(
                point_data,
                --point_data_pointer,
                file_size,
                (const char* const) " \n",
                (const char* const) "nodata_value");

        // note: the value of `image_height_in_use` can be adjusted here (for testing purposes).
        int32_t image_height_in_use = image_height;

        float* vertex_data;
        vertex_data = new float[image_width * image_height_in_use];

        if (vertex_data == nullptr)
        {
            std::cerr << "Reserving memory for vertex data failed.\n";
            delete[] point_data;
            return false;
        }

        float* vertex_pointer;
        vertex_pointer = vertex_data;

        // start processing image_data.
        std::cout << "Processing image data.\n";

        int32_t last_percent = -1;
        int32_t current_percent = -1;

        for (int32_t z = 0; z < image_height_in_use; z++)
        {
            // show progress in percents.
            current_percent = static_cast<int32_t>(floor(100.0f * ((double) z / (double) (image_height_in_use - 1))));

            if (current_percent > last_percent)
            {
                std::cout << current_percent << "% ";
                last_percent = current_percent;
            }

            for (int32_t x = 0; x < image_width; x++)
            {
                while (!string::check_and_report_if_some_string_matches(point_data, point_data_pointer, file_size, number_strings_vector))
                {
                    point_data_pointer++;
                }
                *vertex_pointer++ = string::extract_float_value_from_string(
                        point_data,
                        --point_data_pointer,
                        file_size,
                        (const char* const) " \n",
                        (const char* const) nullptr);
            }
        }

        delete[] point_data;

        std::cout << "Triangulating ascii grid data.\n";

        geometry::TriangulateQuadsStruct triangulate_quads_struct;
        triangulate_quads_struct.image_width = image_width;
        triangulate_quads_struct.image_height = image_height_in_use;
        triangulate_quads_struct.x_step = x_step;
        triangulate_quads_struct.z_step = z_step;
        triangulate_quads_struct.triangulation_type = triangulation_type;
        triangulate_quads_struct.sphere_radius = NAN;
        triangulate_quads_struct.spherical_world_struct = geometry::SphericalWorldStruct(); // not used, but is needed in the function call.

        bool result = geometry::triangulate_quads(vertex_data, triangulate_quads_struct, out_vertices, out_UVs, out_normals);
        delete vertex_data;
        return result;
    }
}
<|endoftext|>


<commit_before>#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#include "ascii_grid_loader.hpp"
#include "code/ylikuutio/triangulation/quad_triangulation.hpp"
#include "code/ylikuutio/string/ylikuutio_string.hpp"
#include "code/ylikuutio/common/globals.hpp"
#include "code/ylikuutio/common/global_variables.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <cstdio>   // std::FILE, std::fclose, std::fopen, std::fread, std::getchar, std::printf etc.
#include <iostream> // std::cout, std::cin, std::cerr
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string, std::stoi
#include <vector>   // std::vector

namespace loaders
{
    bool load_ASCII_grid(
            std::string ASCII_grid_file_name,
            std::vector<glm::vec3>& out_vertices,
            std::vector<glm::vec2>& out_UVs,
            std::vector<glm::vec3>& out_normals,
            uint32_t x_step,
            uint32_t z_step,
            std::string triangulation_type)
    {
        // Beginning of `L4133D.asc`.
        //
        // ncols        3000
        // nrows        3000
        // xllcorner    386000.000000000000
        // yllcorner    6672000.000000000000
        // cellsize     2.000000000000
        // NODATA_value  -9999.000
        // 34.315 34.467 34.441 34.260 33.972 33.564 33.229 33.130 33.102 33.024 32.902 32.669 32.305 32.013 31.937 31.893 31.831 31.832

        std::cout << "Loading ascii grid file " << ASCII_grid_file_name << " ...\n";

        // Open the file
        const char* char_ASCII_grid_file_name = ASCII_grid_file_name.c_str();
        std::FILE* file = std::fopen(char_ASCII_grid_file_name, "rb");
        if (!file)
        {
            std::cerr << ASCII_grid_file_name << " could not be opened.\n";
            return false;
        }

        // Find out file size.
        if (std::fseek(file, 0, SEEK_END) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        uint64_t file_size = std::ftell(file);

        // Move file pointer to the beginning of file.
        if (fseek(file, 0, SEEK_SET) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        // Reserve enough memory.
        char* point_data = new char[file_size];

        if (point_data == nullptr)
        {
            std::cerr << "Reserving memory for point data failed.\n";
            std::fclose(file);
            return false;
        }

        char* point_data_pointer = point_data;

        // Read the point data from the file into the buffer.
        // TODO: add check for file reading!
        std::fread(point_data, 1, file_size, file);

        // Everything is in memory now, the file can be closed
        std::fclose(file);

        // All possible block identifier strings.
        std::vector<std::string> number_strings_vector = { "-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        int32_t image_width = string::extract_int32_t_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "ncols");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        int32_t image_height = string::extract_int32_t_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "nrows");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float xllcorner = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "xllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float yllcorner = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "yllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float cellsize = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "cellsize");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float nodata_value = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "nodata_value");

        // note: the value of `image_height_in_use` can be adjusted here (for testing purposes).
        uint32_t image_height_in_use = image_height;

        float* vertex_data;
        vertex_data = new float[image_width * image_height_in_use];

        if (vertex_data == nullptr)
        {
            std::cerr << "Reserving memory for vertex data failed.\n";
            delete point_data;
            return false;
        }

        float* vertex_pointer;
        vertex_pointer = vertex_data;

        // start processing image_data.
        std::cout << "Processing image data.\n";

        for (uint32_t z = 0; z < image_height_in_use; z++)
        {
            // show progress in percents.
            int32_t current_percent = static_cast<int32_t>(floor(100.0f * ((double) z / (double) (image_height_in_use - 1))));
            std::cout << current_percent << "% ";

            for (uint32_t x = 0; x < image_width; x++)
            {
                while (!string::check_and_report_if_some_string_matches(point_data, point_data_pointer, number_strings_vector))
                {
                    point_data_pointer++;
                }
                *vertex_pointer++ = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) nullptr);
            }
        }

        delete point_data;

        std::cout << "Triangulating ascii grid data.\n";

        TriangulateQuadsStruct triangulate_quads_struct;
        triangulate_quads_struct.image_width = image_width;
        triangulate_quads_struct.image_height = image_height_in_use;
        triangulate_quads_struct.x_step = x_step;
        triangulate_quads_struct.z_step = z_step;
        triangulate_quads_struct.triangulation_type = triangulation_type;
        triangulate_quads_struct.sphere_radius = NAN;
        triangulate_quads_struct.spherical_world_struct = SphericalWorldStruct(); // not used, but is needed in the function call.

        bool result = geometry::triangulate_quads(vertex_data, triangulate_quads_struct, out_vertices, out_UVs, out_normals);
        delete vertex_data;
        return result;
    }
}
<commit_msg>Cleaning up trailing whitespace.<commit_after>#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#include "ascii_grid_loader.hpp"
#include "code/ylikuutio/triangulation/quad_triangulation.hpp"
#include "code/ylikuutio/string/ylikuutio_string.hpp"
#include "code/ylikuutio/common/globals.hpp"
#include "code/ylikuutio/common/global_variables.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <cstdio>   // std::FILE, std::fclose, std::fopen, std::fread, std::getchar, std::printf etc.
#include <iostream> // std::cout, std::cin, std::cerr
#include <stdint.h> // uint32_t etc.
#include <string>   // std::string, std::stoi
#include <vector>   // std::vector

namespace loaders
{
    bool load_ASCII_grid(
            std::string ASCII_grid_file_name,
            std::vector<glm::vec3>& out_vertices,
            std::vector<glm::vec2>& out_UVs,
            std::vector<glm::vec3>& out_normals,
            uint32_t x_step,
            uint32_t z_step,
            std::string triangulation_type)
    {
        // Beginning of `L4133D.asc`.
        //
        // ncols        3000
        // nrows        3000
        // xllcorner    386000.000000000000
        // yllcorner    6672000.000000000000
        // cellsize     2.000000000000
        // NODATA_value  -9999.000
        // 34.315 34.467 34.441 34.260 33.972 33.564 33.229 33.130 33.102 33.024 32.902 32.669 32.305 32.013 31.937 31.893 31.831 31.832

        std::cout << "Loading ascii grid file " << ASCII_grid_file_name << " ...\n";

        // Open the file
        const char* char_ASCII_grid_file_name = ASCII_grid_file_name.c_str();
        std::FILE* file = std::fopen(char_ASCII_grid_file_name, "rb");
        if (!file)
        {
            std::cerr << ASCII_grid_file_name << " could not be opened.\n";
            return false;
        }

        // Find out file size.
        if (std::fseek(file, 0, SEEK_END) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        uint64_t file_size = std::ftell(file);

        // Move file pointer to the beginning of file.
        if (fseek(file, 0, SEEK_SET) != 0)
        {
            std::cerr << "moving file pointer of file " << ASCII_grid_file_name << " failed!\n";
            std::fclose(file);
            return false;
        }

        // Reserve enough memory.
        char* point_data = new char[file_size];

        if (point_data == nullptr)
        {
            std::cerr << "Reserving memory for point data failed.\n";
            std::fclose(file);
            return false;
        }

        char* point_data_pointer = point_data;

        // Read the point data from the file into the buffer.
        // TODO: add check for file reading!
        std::fread(point_data, 1, file_size, file);

        // Everything is in memory now, the file can be closed
        std::fclose(file);

        // All possible block identifier strings.
        std::vector<std::string> number_strings_vector = { "-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        int32_t image_width = string::extract_int32_t_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "ncols");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        int32_t image_height = string::extract_int32_t_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "nrows");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float xllcorner = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "xllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float yllcorner = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "yllcorner");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float cellsize = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "cellsize");

        while (!string::check_and_report_if_some_string_matches(point_data, ++point_data_pointer, number_strings_vector));
        float nodata_value = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) "nodata_value");

        // note: the value of `image_height_in_use` can be adjusted here (for testing purposes).
        uint32_t image_height_in_use = image_height;

        float* vertex_data;
        vertex_data = new float[image_width * image_height_in_use];

        if (vertex_data == nullptr)
        {
            std::cerr << "Reserving memory for vertex data failed.\n";
            delete point_data;
            return false;
        }

        float* vertex_pointer;
        vertex_pointer = vertex_data;

        // start processing image_data.
        std::cout << "Processing image data.\n";

        for (uint32_t z = 0; z < image_height_in_use; z++)
        {
            // show progress in percents.
            int32_t current_percent = static_cast<int32_t>(floor(100.0f * ((double) z / (double) (image_height_in_use - 1))));
            std::cout << current_percent << "% ";

            for (uint32_t x = 0; x < image_width; x++)
            {
                while (!string::check_and_report_if_some_string_matches(point_data, point_data_pointer, number_strings_vector))
                {
                    point_data_pointer++;
                }
                *vertex_pointer++ = string::extract_float_value_from_string(--point_data_pointer, (char*) " \n", (const char*) nullptr);
            }
        }

        delete point_data;

        std::cout << "Triangulating ascii grid data.\n";

        TriangulateQuadsStruct triangulate_quads_struct;
        triangulate_quads_struct.image_width = image_width;
        triangulate_quads_struct.image_height = image_height_in_use;
        triangulate_quads_struct.x_step = x_step;
        triangulate_quads_struct.z_step = z_step;
        triangulate_quads_struct.triangulation_type = triangulation_type;
        triangulate_quads_struct.sphere_radius = NAN;
        triangulate_quads_struct.spherical_world_struct = SphericalWorldStruct(); // not used, but is needed in the function call.

        bool result = geometry::triangulate_quads(vertex_data, triangulate_quads_struct, out_vertices, out_UVs, out_normals);
        delete vertex_data;
        return result;
    }
}
<|endoftext|>


<commit_before>#pragma once

#include <boost/optional.hpp>
#include <boost/unordered_map.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>

#include <crab/common/types.hpp>
#include <crab/cfg/cfg.hpp>

/*
 * Datastructures needed during inter-procedural analysis
 */

namespace crab {

  namespace analyzer {

    // XXX: Currently we assume a _contex-insensitive_ approach so we
    // store a single summary per function. For implementing a
    // context-sensitive approach we would need to allow multiple
    // summaries per function.

    /* Store the calling contexts of each function */
    template <typename CFG, typename AbsDomain>
    class call_ctx_table: boost::noncopyable {
     public:

      typedef typename CFG::basic_block_t::callsite_t callsite_t;
      typedef typename CFG::fdecl_t fdecl_t;
      typedef typename CFG::varname_t varname_t;
      typedef typename CFG::variable_t variable_t;
      typedef AbsDomain abs_domain_t;

     private:
      typedef boost::unordered_map <std::size_t, abs_domain_t> call_table_t;

      call_table_t m_call_table;

      // XXX: assume context-insensitive analysis so it will merge all
      // calling contexts using abstract domain's join keeping a
      // single calling context per function.
      void insert_helper (std::size_t func_key, AbsDomain inv) {
        auto it = m_call_table.find (func_key);
        if (it != m_call_table.end ()) {
          it->second = it->second | inv;
        } else {
          m_call_table.insert (std::make_pair (func_key, inv));
	}
      }

     public:

      call_ctx_table() { }

      void insert (callsite_t cs, AbsDomain inv) {
        insert_helper (cfg::cfg_hasher<CFG>::hash (cs), inv);
      }

      void insert (fdecl_t d, AbsDomain inv) {
        insert_helper (cfg::cfg_hasher<CFG>::hash (d), inv);
      }

      AbsDomain get_call_ctx (fdecl_t d) const {
        auto it = m_call_table.find (cfg::cfg_hasher<CFG>::hash (d));
        if (it != m_call_table.end ())
          return it->second;
        else
          return AbsDomain::top ();
      }

    };

    /* Store the summaries for each function*/
    template<typename CFG, typename AbsDomain>
    class summary_table: boost::noncopyable {

     public:

      typedef typename CFG::basic_block_t::callsite_t callsite_t;
      typedef typename CFG::fdecl_t fdecl_t;
      typedef AbsDomain abs_domain_t;
      typedef typename CFG::variable_t variable_t;

      // A summary is an input-output relationship between function
      // parameters. The relationship can be as expressive as
      // AbsDomain.
      class Summary {

        // --- function info
        fdecl_t m_fdecl;
        // --- Summary involving only m_params + m_ret_vals variables
        abs_domain_t m_sum;
        // --- Keep all the input original parameters of the function
        std::vector <variable_t> m_inputs;
        // --- Keep a copy of all input original parameters of the function
        std::vector <variable_t> m_internal_inputs;
        // --- Keep all the output original parameters of the function
        std::vector <variable_t> m_outputs;
        // --- Keep a copy of all output original parameters of the function
        std::vector <variable_t> m_internal_outputs;

	// - m_sum is defined in terms of m_internal_inputs  and m_internal_outputs.
	// - m_fdecl is defined in terms of m_inputs and m_outputs.

	// helper to rename summaries
	void rename (abs_domain_t &abs,
		     const std::vector<variable_t> &from_inputs,
		     const std::vector<variable_t> &from_outputs,
		     const std::vector<variable_t> &to_inputs,
		     const std::vector<variable_t> &to_outputs) const {

	  assert (from_inputs.size() == to_inputs.size());
	  assert (from_outputs.size() == to_outputs.size());

	  // append inputs and outputs
	  std::vector<variable_t> from_vars, to_vars;
	  from_vars.reserve(from_inputs.size() + from_outputs.size());
	  from_vars.insert(from_vars.end(), from_inputs.begin(), from_inputs.end() );
	  from_vars.insert(from_vars.end(), from_outputs.begin(), from_outputs.end() );
	  to_vars.reserve(to_inputs.size() + to_outputs.size());
	  to_vars.insert(to_vars.end(), to_inputs.begin(), to_inputs.end() );
	  to_vars.insert(to_vars.end(), to_outputs.begin(), to_outputs.end() );
	  abs.rename(from_vars, to_vars);
	}

       public:

        Summary (fdecl_t fdecl,
                 abs_domain_t sum,
                 const std::vector<variable_t> &inputs,
                 const std::vector<variable_t> &outputs):
	  m_fdecl(fdecl), m_sum(sum), m_inputs(inputs), m_outputs(outputs) {

	  m_internal_inputs.reserve(m_inputs.size());
	  m_internal_outputs.reserve(m_outputs.size());
	  for (auto v: m_inputs) {
	    variable_t fresh_v(v.name().get_var_factory().get(), v.get_type());
	    m_internal_inputs.push_back(fresh_v);
	  }
	  for (auto v: m_outputs) {
	    variable_t fresh_v(v.name().get_var_factory().get(), v.get_type());
	    m_internal_outputs.push_back(fresh_v);
	  }

          if (m_fdecl.get_num_inputs() != m_inputs.size ())
            CRAB_ERROR ("mismatch between function declaration and summary parameters");
          if (m_fdecl.get_num_outputs() != m_outputs.size ())
            CRAB_ERROR ("mismatch between function declaration and summary return vals");
	  if (m_inputs.size() != m_internal_inputs.size())
	    CRAB_ERROR("internal error in Summary class");
	  if (m_outputs.size() != m_internal_outputs.size())
	    CRAB_ERROR("internal error in Summary class");
        }

	// -- The summary, input, and output variables contain the
	// -- original variable names.
        abs_domain_t get_sum () const { return m_sum;}

	// return the input variables of the summary
        const std::vector<variable_t>& get_inputs () const
	{ return m_inputs;}

	// return the output variables of the summary
        const std::vector<variable_t>& get_outputs () const
	{ return m_outputs;}

	// -- The summary, input, and output variables are renamed so
	//    that they have unique variable names. This avoids naming
	//    clashes when summaries are used in the interprocedural
	//    analysis.
	//
        abs_domain_t get_renamed_sum() const {
	  abs_domain_t res(m_sum);
	  rename(res, m_inputs, m_outputs,
		 m_internal_inputs, m_internal_outputs);
	  return res;
	}

        const std::vector<variable_t>& get_renamed_inputs() const
	{ return m_internal_inputs;}

        const std::vector<variable_t>& get_renamed_outputs() const
	{ return m_internal_outputs;}

        // Check type consistency between function declaration and callsite
        // XXXX: this is needed because we don't type check crab programs.
        void check_type_consistency (callsite_t cs) const {

          if (m_fdecl.get_num_inputs() != cs.get_num_args())
            CRAB_ERROR ("Mismatch between number of callsite and summary parameters");
          if (m_fdecl.get_num_outputs() != cs.get_lhs().size())
            CRAB_ERROR ("Mismatch between number of callsite and summary return values");

          for (unsigned i=0; i < cs.get_num_args (); i++){
            if (m_fdecl.get_input_type(i) != cs.get_arg_type (i))
              CRAB_ERROR ("Mismatch between type of callsite and summary parameter");
          }

          for (unsigned i=0; i < cs.get_lhs().size(); i++){
            if (m_fdecl.get_output_type(i) != cs.get_lhs()[i].get_type())
              CRAB_ERROR ("Mismatch between type of callsite and summary return value");
          }
        }

        void write(crab_os &o) const {
	  o << m_fdecl.get_func_name() << "(IN:{";
	  for (unsigned i=0; i<m_fdecl.get_num_inputs(); i++){
	    o << m_inputs[i] << ":" <<  m_fdecl.get_input_type(i);
	    if (i != m_fdecl.get_num_inputs() - 1)
	      o << ",";
	  }
	  o << "},OUT:{";
	  for (unsigned i=0; i<m_fdecl.get_num_outputs(); i++){
	    o << m_outputs[i] << ":" <<  m_fdecl.get_output_type(i);
	    if (i != m_fdecl.get_num_outputs() - 1)
	      o << ",";
	  }
	  o << "}) ==>\n";
          abs_domain_t tmp (m_sum);
          o << tmp;
        }

      };

     private:

      typedef boost::shared_ptr <Summary> summary_ptr;
      typedef boost::unordered_map <std::size_t, summary_ptr> summary_table_t;

      summary_table_t m_sum_table;

     public:

      summary_table () { }

      // insert summary information
      void insert (fdecl_t d,
                   AbsDomain sum,
                   const std::vector<variable_t>& inputs,
                   const std::vector<variable_t>& outputs) {

        std::vector<variable_t> ins(inputs.begin(), inputs.end ());
        std::vector<variable_t> outs(outputs.begin(), outputs.end ());
        summary_ptr sum_tuple (new Summary (d, sum, ins, outs));
        m_sum_table.insert (std::make_pair (cfg::cfg_hasher<CFG>::hash (d), sum_tuple));
      }

      // return true if there is a summary
      bool hasSummary (callsite_t cs) const {
        auto it = m_sum_table.find (cfg::cfg_hasher<CFG>::hash (cs));
        return (it != m_sum_table.end ());
      }

      bool hasSummary (fdecl_t d) const {
        auto it = m_sum_table.find (cfg::cfg_hasher<CFG>::hash (d));
        return (it != m_sum_table.end ());
      }

      // get the summary
      Summary& get (callsite_t cs) const {
        auto it = m_sum_table.find (cfg::cfg_hasher<CFG>::hash (cs));
        assert (it != m_sum_table.end ());

        return *(it->second);
      }

      Summary& get (fdecl_t d) const {
        auto it = m_sum_table.find (cfg::cfg_hasher<CFG>::hash (d));
        assert (it != m_sum_table.end ());

        return *(it->second);
      }

      void write (crab_os &o) const {
        o << "--- Begin summary table: \n";
        for (auto const &p: m_sum_table) {
          p.second->write (o);
          o << "\n";
        }
        o << "--- End summary table\n";
      }

      friend crab_os& operator<<(crab_os& o, const summary_table<CFG, AbsDomain>&t) {
        t.write (o);
        return o;
      }

      friend crab_os& operator<<(crab_os& o,
				 const typename summary_table<CFG,AbsDomain>::Summary &sum) {
        sum.write (o);
        return o;
      }

    };

  } // end namespace
} // end namespace

<commit_msg>Fix potential ambiguity error<commit_after>#pragma once

#include <boost/optional.hpp>
#include <boost/unordered_map.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>

#include <crab/common/types.hpp>
#include <crab/cfg/cfg.hpp>

/*
 * Datastructures needed during inter-procedural analysis
 */

namespace crab {

  namespace analyzer {

    // XXX: Currently we assume a _contex-insensitive_ approach so we
    // store a single summary per function. For implementing a
    // context-sensitive approach we would need to allow multiple
    // summaries per function.

    /* Store the calling contexts of each function */
    template <typename CFG, typename AbsDomain>
    class call_ctx_table: boost::noncopyable {
     public:

      typedef typename CFG::basic_block_t::callsite_t callsite_t;
      typedef typename CFG::fdecl_t fdecl_t;
      typedef typename CFG::varname_t varname_t;
      typedef typename CFG::variable_t variable_t;
      typedef AbsDomain abs_domain_t;

     private:
      typedef boost::unordered_map <std::size_t, abs_domain_t> call_table_t;

      call_table_t m_call_table;

      // XXX: assume context-insensitive analysis so it will merge all
      // calling contexts using abstract domain's join keeping a
      // single calling context per function.
      void insert_helper (std::size_t func_key, AbsDomain inv) {
        auto it = m_call_table.find (func_key);
        if (it != m_call_table.end ()) {
          it->second = it->second | inv;
        } else {
          m_call_table.insert (std::make_pair (func_key, inv));
	}
      }

     public:

      call_ctx_table() { }

      void insert (callsite_t cs, AbsDomain inv) {
        insert_helper (crab::cfg::cfg_hasher<CFG>::hash (cs), inv);
      }

      void insert (fdecl_t d, AbsDomain inv) {
        insert_helper (crab::cfg::cfg_hasher<CFG>::hash (d), inv);
      }

      AbsDomain get_call_ctx (fdecl_t d) const {
        auto it = m_call_table.find (crab::cfg::cfg_hasher<CFG>::hash (d));
        if (it != m_call_table.end ())
          return it->second;
        else
          return AbsDomain::top ();
      }

    };

    /* Store the summaries for each function*/
    template<typename CFG, typename AbsDomain>
    class summary_table: boost::noncopyable {

     public:

      typedef typename CFG::basic_block_t::callsite_t callsite_t;
      typedef typename CFG::fdecl_t fdecl_t;
      typedef AbsDomain abs_domain_t;
      typedef typename CFG::variable_t variable_t;

      // A summary is an input-output relationship between function
      // parameters. The relationship can be as expressive as
      // AbsDomain.
      class Summary {

        // --- function info
        fdecl_t m_fdecl;
        // --- Summary involving only m_params + m_ret_vals variables
        abs_domain_t m_sum;
        // --- Keep all the input original parameters of the function
        std::vector <variable_t> m_inputs;
        // --- Keep a copy of all input original parameters of the function
        std::vector <variable_t> m_internal_inputs;
        // --- Keep all the output original parameters of the function
        std::vector <variable_t> m_outputs;
        // --- Keep a copy of all output original parameters of the function
        std::vector <variable_t> m_internal_outputs;

	// - m_sum is defined in terms of m_internal_inputs  and m_internal_outputs.
	// - m_fdecl is defined in terms of m_inputs and m_outputs.

	// helper to rename summaries
	void rename (abs_domain_t &abs,
		     const std::vector<variable_t> &from_inputs,
		     const std::vector<variable_t> &from_outputs,
		     const std::vector<variable_t> &to_inputs,
		     const std::vector<variable_t> &to_outputs) const {

	  assert (from_inputs.size() == to_inputs.size());
	  assert (from_outputs.size() == to_outputs.size());

	  // append inputs and outputs
	  std::vector<variable_t> from_vars, to_vars;
	  from_vars.reserve(from_inputs.size() + from_outputs.size());
	  from_vars.insert(from_vars.end(), from_inputs.begin(), from_inputs.end() );
	  from_vars.insert(from_vars.end(), from_outputs.begin(), from_outputs.end() );
	  to_vars.reserve(to_inputs.size() + to_outputs.size());
	  to_vars.insert(to_vars.end(), to_inputs.begin(), to_inputs.end() );
	  to_vars.insert(to_vars.end(), to_outputs.begin(), to_outputs.end() );
	  abs.rename(from_vars, to_vars);
	}

       public:

        Summary (fdecl_t fdecl,
                 abs_domain_t sum,
                 const std::vector<variable_t> &inputs,
                 const std::vector<variable_t> &outputs):
	  m_fdecl(fdecl), m_sum(sum), m_inputs(inputs), m_outputs(outputs) {

	  m_internal_inputs.reserve(m_inputs.size());
	  m_internal_outputs.reserve(m_outputs.size());
	  for (auto v: m_inputs) {
	    variable_t fresh_v(v.name().get_var_factory().get(), v.get_type());
	    m_internal_inputs.push_back(fresh_v);
	  }
	  for (auto v: m_outputs) {
	    variable_t fresh_v(v.name().get_var_factory().get(), v.get_type());
	    m_internal_outputs.push_back(fresh_v);
	  }

          if (m_fdecl.get_num_inputs() != m_inputs.size ())
            CRAB_ERROR ("mismatch between function declaration and summary parameters");
          if (m_fdecl.get_num_outputs() != m_outputs.size ())
            CRAB_ERROR ("mismatch between function declaration and summary return vals");
	  if (m_inputs.size() != m_internal_inputs.size())
	    CRAB_ERROR("internal error in Summary class");
	  if (m_outputs.size() != m_internal_outputs.size())
	    CRAB_ERROR("internal error in Summary class");
        }

	// -- The summary, input, and output variables contain the
	// -- original variable names.
        abs_domain_t get_sum () const { return m_sum;}

	// return the input variables of the summary
        const std::vector<variable_t>& get_inputs () const
	{ return m_inputs;}

	// return the output variables of the summary
        const std::vector<variable_t>& get_outputs () const
	{ return m_outputs;}

	// -- The summary, input, and output variables are renamed so
	//    that they have unique variable names. This avoids naming
	//    clashes when summaries are used in the interprocedural
	//    analysis.
	//
        abs_domain_t get_renamed_sum() const {
	  abs_domain_t res(m_sum);
	  rename(res, m_inputs, m_outputs,
		 m_internal_inputs, m_internal_outputs);
	  return res;
	}

        const std::vector<variable_t>& get_renamed_inputs() const
	{ return m_internal_inputs;}

        const std::vector<variable_t>& get_renamed_outputs() const
	{ return m_internal_outputs;}

        // Check type consistency between function declaration and callsite
        // XXXX: this is needed because we don't type check crab programs.
        void check_type_consistency (callsite_t cs) const {

          if (m_fdecl.get_num_inputs() != cs.get_num_args())
            CRAB_ERROR ("Mismatch between number of callsite and summary parameters");
          if (m_fdecl.get_num_outputs() != cs.get_lhs().size())
            CRAB_ERROR ("Mismatch between number of callsite and summary return values");

          for (unsigned i=0; i < cs.get_num_args (); i++){
            if (m_fdecl.get_input_type(i) != cs.get_arg_type (i))
              CRAB_ERROR ("Mismatch between type of callsite and summary parameter");
          }

          for (unsigned i=0; i < cs.get_lhs().size(); i++){
            if (m_fdecl.get_output_type(i) != cs.get_lhs()[i].get_type())
              CRAB_ERROR ("Mismatch between type of callsite and summary return value");
          }
        }

        void write(crab_os &o) const {
	  o << m_fdecl.get_func_name() << "(IN:{";
	  for (unsigned i=0; i<m_fdecl.get_num_inputs(); i++){
	    o << m_inputs[i] << ":" <<  m_fdecl.get_input_type(i);
	    if (i != m_fdecl.get_num_inputs() - 1)
	      o << ",";
	  }
	  o << "},OUT:{";
	  for (unsigned i=0; i<m_fdecl.get_num_outputs(); i++){
	    o << m_outputs[i] << ":" <<  m_fdecl.get_output_type(i);
	    if (i != m_fdecl.get_num_outputs() - 1)
	      o << ",";
	  }
	  o << "}) ==>\n";
          abs_domain_t tmp (m_sum);
          o << tmp;
        }

      };

     private:

      typedef boost::shared_ptr <Summary> summary_ptr;
      typedef boost::unordered_map <std::size_t, summary_ptr> summary_table_t;

      summary_table_t m_sum_table;

     public:

      summary_table () { }

      // insert summary information
      void insert (fdecl_t d,
                   AbsDomain sum,
                   const std::vector<variable_t>& inputs,
                   const std::vector<variable_t>& outputs) {

        std::vector<variable_t> ins(inputs.begin(), inputs.end ());
        std::vector<variable_t> outs(outputs.begin(), outputs.end ());
        summary_ptr sum_tuple (new Summary (d, sum, ins, outs));
        m_sum_table.insert (std::make_pair (crab::cfg::cfg_hasher<CFG>::hash (d), sum_tuple));
      }

      // return true if there is a summary
      bool hasSummary (callsite_t cs) const {
        auto it = m_sum_table.find (crab::cfg::cfg_hasher<CFG>::hash (cs));
        return (it != m_sum_table.end ());
      }

      bool hasSummary (fdecl_t d) const {
        auto it = m_sum_table.find (crab::cfg::cfg_hasher<CFG>::hash (d));
        return (it != m_sum_table.end ());
      }

      // get the summary
      Summary& get (callsite_t cs) const {
        auto it = m_sum_table.find (crab::cfg::cfg_hasher<CFG>::hash (cs));
        assert (it != m_sum_table.end ());

        return *(it->second);
      }

      Summary& get (fdecl_t d) const {
        auto it = m_sum_table.find (crab::cfg::cfg_hasher<CFG>::hash (d));
        assert (it != m_sum_table.end ());

        return *(it->second);
      }

      void write (crab_os &o) const {
        o << "--- Begin summary table: \n";
        for (auto const &p: m_sum_table) {
          p.second->write (o);
          o << "\n";
        }
        o << "--- End summary table\n";
      }

      friend crab_os& operator<<(crab_os& o, const summary_table<CFG, AbsDomain>&t) {
        t.write (o);
        return o;
      }

      friend crab_os& operator<<(crab_os& o,
				 const typename summary_table<CFG,AbsDomain>::Summary &sum) {
        sum.write (o);
        return o;
      }

    };

  } // end namespace
} // end namespace

<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 *
 * Copyright (C) 1999 - 2014 by the deal.II authors
 *
 * This file is part of the deal.II library.
 *
 * The deal.II library is free software; you can use it, redistribute
 * it, and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * The full text of the license can be found in the file LICENSE at
 * the top level of the deal.II distribution.
 *
 * ---------------------------------------------------------------------

 *
 * Authors: Wolfgang Bangerth, 1999,
 *          Guido Kanschat, 2011
 */

#include <deal.II/grid/tria.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/grid/grid_generator.h>

#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_accessor.h>

#include <deal.II/fe/fe_q.h>

#include <deal.II/dofs/dof_tools.h>

#include <deal.II/fe/fe_values.h>

#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>

#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>
#include <deal.II/numerics/data_out.h>

#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/compressed_sparsity_pattern.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>

#include <deal.II/base/mpi.h>

#include <fstream>
#include <iostream>

#include "parsed_grid_generator.h"
#include "parsed_finite_element.h"
#include "parsed_function.h"
#include "parsed_data_out.h"
#include "utilities.h"

using namespace dealii;

template<int dim>
class SerialLaplace : public ParameterAcceptor
{
public:
  SerialLaplace ();

  virtual void declare_parameters(ParameterHandler &prm);

  void run ();

private:
  void make_grid_fe ();
  void setup_system ();
  void assemble_system ();
  void solve ();
  void output_results ();

  shared_ptr<Triangulation<dim> >    triangulation;
  shared_ptr<FiniteElement<dim,dim> >             fe;
  shared_ptr<DoFHandler<dim> >       dof_handler;

  ConstraintMatrix     constraints;
  SparsityPattern      sparsity_pattern;
  SparseMatrix<double> system_matrix;

  Vector<double>       solution;
  Vector<double>       system_rhs;

  ParsedGridGenerator<dim,dim> tria_builder;
  ParsedFiniteElement<dim,dim> fe_builder;

  ParsedFunction<dim> forcing_function;
  ParsedFunction<dim> permeability;
  ParsedFunction<dim> dirichlet_function;

  ParsedDataOut<dim,dim> data_out;

  std::vector<unsigned int> dirichlet_boundary_ids;
  unsigned int n_cycles;
  unsigned int initial_refinement;
};

template <int dim>
SerialLaplace<dim>::SerialLaplace ()
  :
  ParameterAcceptor("Global parameters"),
  tria_builder("Triangulation"),
  fe_builder("Finite element"),
  forcing_function("Rhs function"),
  permeability("Permeability"),
  dirichlet_function("Dirichlet function"),
  data_out("Data out", "vtu")
{}

template <int dim>
void SerialLaplace<dim>::declare_parameters(ParameterHandler &prm)
{
  add_parameter(prm, &dirichlet_boundary_ids, "Dirichlet boundary ids",
                "0", Patterns::List(Patterns::Integer(0)));

  add_parameter(prm, &n_cycles, "Number of cycles", "5",
                Patterns::Integer(0));

  add_parameter(prm, &initial_refinement, "Initial global refinement", "4",
                Patterns::Integer(0));

}

template <int dim>
void SerialLaplace<dim>::make_grid_fe ()
{

  ParameterAcceptor::initialize("parameters_ser.prm", "used_parameters_ser.prm");

  triangulation = SP(tria_builder.serial());
  dof_handler = SP(new DoFHandler<dim>(*triangulation));

  std::cout << "Number of active cells: "
            << triangulation->n_active_cells()
            << std::endl;

  fe=SP(fe_builder());

}

template <int dim>
void SerialLaplace<dim>::setup_system ()
{
  dof_handler->distribute_dofs (*fe);
  std::cout << "Number of degrees of freedom: "
            << dof_handler->n_dofs()
            << std::endl;

  constraints.clear ();

  DoFTools::make_hanging_node_constraints (*dof_handler, constraints);

  for (auto id : dirichlet_boundary_ids)
    {
      VectorTools::interpolate_boundary_values (*dof_handler,
                                                0,
                                                dirichlet_function,
                                                constraints);
    }
  constraints.close ();

  DynamicSparsityPattern d_sparsity(dof_handler->n_dofs());

  DoFTools::make_sparsity_pattern (*dof_handler, d_sparsity,
                                   constraints);

  sparsity_pattern.copy_from(d_sparsity);

  system_matrix.reinit (sparsity_pattern);

  solution.reinit (dof_handler->n_dofs());

  system_rhs.reinit (dof_handler->n_dofs());
}

template <int dim>
void SerialLaplace<dim>::assemble_system ()
{
  QGauss<dim>  quadrature_formula(4);

  MatrixCreator::create_laplace_matrix (StaticMappingQ1<dim, dim>::mapping,
                                        *dof_handler, quadrature_formula, system_matrix,
                                        forcing_function, system_rhs, &permeability, constraints);

}

template <int dim>
void SerialLaplace<dim>::solve ()
{
  SolverControl           solver_control (1000, 1e-12);
  SolverCG<>              solver (solver_control);
  solver.solve (system_matrix, solution, system_rhs,
                PreconditionIdentity());
}

template <int dim>
void SerialLaplace<dim>::output_results ()
{
  data_out.prepare_data_output(*dof_handler, "");
  data_out.add_data_vector (solution, "u");
  data_out.write_data_and_clear();
}

template <int dim>
void SerialLaplace<dim>::run ()
{
  make_grid_fe ();
  setup_system ();
  assemble_system ();
  solve ();
  output_results ();
}

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

  Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv);

  SerialLaplace<2> laplace_problem_2;
  laplace_problem_2.run ();

  return 0;
}
<commit_msg>seems more reasonable<commit_after>/* ---------------------------------------------------------------------
 *
 * Copyright (C) 1999 - 2014 by the deal.II authors
 *
 * This file is part of the deal.II library.
 *
 * The deal.II library is free software; you can use it, redistribute
 * it, and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * The full text of the license can be found in the file LICENSE at
 * the top level of the deal.II distribution.
 *
 * ---------------------------------------------------------------------

 *
 * Authors: Wolfgang Bangerth, 1999,
 *          Guido Kanschat, 2011
 */

#include <deal.II/grid/tria.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/grid/grid_generator.h>

#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_accessor.h>

#include <deal.II/fe/fe_q.h>

#include <deal.II/dofs/dof_tools.h>

#include <deal.II/fe/fe_values.h>

#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>

#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>
#include <deal.II/numerics/data_out.h>

#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/compressed_sparsity_pattern.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>

#include <deal.II/base/mpi.h>

#include <fstream>
#include <iostream>

#include "parsed_grid_generator.h"
#include "parsed_finite_element.h"
#include "parsed_function.h"
#include "parsed_data_out.h"
#include "utilities.h"

using namespace dealii;

template<int dim>
class SerialLaplace : public ParameterAcceptor
{
public:
  SerialLaplace ();

  virtual void declare_parameters(ParameterHandler &prm);

  void run ();

private:
  void make_grid_fe ();
  void setup_system ();
  void assemble_system ();
  void solve ();
  void output_results ();

  shared_ptr<Triangulation<dim> >    triangulation;
  shared_ptr<FiniteElement<dim,dim> >             fe;
  shared_ptr<DoFHandler<dim> >       dof_handler;

  ConstraintMatrix     constraints;
  SparsityPattern      sparsity_pattern;
  SparseMatrix<double> system_matrix;

  Vector<double>       solution;
  Vector<double>       system_rhs;

  ParsedGridGenerator<dim,dim> tria_builder;
  ParsedFiniteElement<dim,dim> fe_builder;

  ParsedFunction<dim> forcing_function;
  ParsedFunction<dim> permeability;
  ParsedFunction<dim> dirichlet_function;

  ParsedDataOut<dim,dim> data_out;

  std::vector<unsigned int> dirichlet_boundary_ids;
  unsigned int n_cycles;
  unsigned int initial_refinement;
};

template <int dim>
SerialLaplace<dim>::SerialLaplace ()
  :
  ParameterAcceptor("Global parameters"),
  tria_builder("Triangulation"),
  fe_builder("Finite element"),
  forcing_function("Rhs function"),
  permeability("Permeability","1."),
  dirichlet_function("Dirichlet function"),
  data_out("Data out", "vtu")
{}

template <int dim>
void SerialLaplace<dim>::declare_parameters(ParameterHandler &prm)
{
  add_parameter(prm, &dirichlet_boundary_ids, "Dirichlet boundary ids",
                "0", Patterns::List(Patterns::Integer(0)));

  add_parameter(prm, &initial_refinement, "Initial global refinement", "4",
                Patterns::Integer(0));

}

template <int dim>
void SerialLaplace<dim>::make_grid_fe ()
{

  ParameterAcceptor::initialize("parameters_ser.prm", "used_parameters_ser.prm");

  triangulation = SP(tria_builder.serial());

  triangulation->refine_global(initial_refinement);

  dof_handler = SP(new DoFHandler<dim>(*triangulation));

  std::cout << "Number of active cells: "
            << triangulation->n_active_cells()
            << std::endl;

  fe=SP(fe_builder());

}

template <int dim>
void SerialLaplace<dim>::setup_system ()
{
  dof_handler->distribute_dofs (*fe);
  std::cout << "Number of degrees of freedom: "
            << dof_handler->n_dofs()
            << std::endl;

  constraints.clear ();

  DoFTools::make_hanging_node_constraints (*dof_handler, constraints);

  for (auto id : dirichlet_boundary_ids)
    {
      VectorTools::interpolate_boundary_values (*dof_handler,
                                                id,
                                                dirichlet_function,
                                                constraints);
    }
  constraints.close ();

  DynamicSparsityPattern d_sparsity(dof_handler->n_dofs());

  DoFTools::make_sparsity_pattern (*dof_handler, d_sparsity,
                                   constraints);

  sparsity_pattern.copy_from(d_sparsity);

  system_matrix.reinit (sparsity_pattern);

  solution.reinit (dof_handler->n_dofs());

  system_rhs.reinit (dof_handler->n_dofs());
}

template <int dim>
void SerialLaplace<dim>::assemble_system ()
{
  QGauss<dim>  quadrature_formula(4);

  MatrixCreator::create_laplace_matrix (StaticMappingQ1<dim, dim>::mapping,
                                        *dof_handler, quadrature_formula, system_matrix,
                                        forcing_function, system_rhs, &permeability, constraints);

}

template <int dim>
void SerialLaplace<dim>::solve ()
{
  SolverControl           solver_control (1000, 1e-12);
  SolverCG<>              solver (solver_control);
  solver.solve (system_matrix, solution, system_rhs,
                PreconditionIdentity());
}

template <int dim>
void SerialLaplace<dim>::output_results ()
{
  data_out.prepare_data_output(*dof_handler);
  data_out.add_data_vector (solution, "u");
  data_out.write_data_and_clear();
}

template <int dim>
void SerialLaplace<dim>::run ()
{
  make_grid_fe ();
  setup_system ();
  assemble_system ();
  solve ();
  output_results ();
}

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

  Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv);

  SerialLaplace<2> laplace_problem_2;
  laplace_problem_2.run ();

  return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/tfrt/graph_executor/graph_execution_options.h"

#include "tensorflow/core/protobuf/rewriter_config.pb.h"
#include "tensorflow/core/tfrt/utils/bridge_graph_analysis.h"

namespace tensorflow {
namespace tfrt_stub {

tensorflow::SessionOptions CreateDefaultSessionOptions(
    const GraphExecutionOptions& options) {
  tensorflow::SessionOptions session_options;
  auto& config = session_options.config;

  config.mutable_graph_options()
      ->mutable_rewrite_options()
      ->set_disable_meta_optimizer(!options.compile_options.enable_grappler);

  // The following configs are constant.

  // Setting use_tfrt to true avoids grappler logic that lowers to v1 control
  // flow. Note that other function inlining (e.g. on StatefulPartitionedCall)
  // is still enabled.
  config.mutable_experimental()->set_use_tfrt(true);
  config.mutable_graph_options()
      ->mutable_rewrite_options()
      ->set_function_optimization(tensorflow::RewriterConfig::ON);
  // Do not skip grappler optimization even for small graphs.
  config.mutable_graph_options()
      ->mutable_rewrite_options()
      ->set_min_graph_nodes(-1);

  return session_options;
}

void UpdateTpuTargetByBridgeCompatibility(
    tensorflow::tfrt_stub::GraphExecutionOptions& options,
    const tensorflow::GraphDef& graph_def) {
  if (options.compile_options.tpu_target ==
      tensorflow::TfrtTpuInfraTarget::kBridgeFallback) {
    auto s = tfrt::CheckTpuMlirBridgeCompatibility(graph_def);
    if (!s.ok()) {
      LOG(INFO)
          << "TFRT detected Bridge unsupported feature, using TF fallback";
      options.compile_options.tpu_target =
          tensorflow::TfrtTpuInfraTarget::kTfFallback;
    } else {
      options.compile_options.tpu_target =
          tensorflow::TfrtTpuInfraTarget::kTpurt;
    }
  }
  LOG(INFO) << "TFRT uses TPU target " << options.compile_options.tpu_target;
}

}  // namespace tfrt_stub
}  // namespace tensorflow
<commit_msg>Enable inlining but disable v1 control flow lowering in TF-TFRT workflow<commit_after>/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/core/tfrt/graph_executor/graph_execution_options.h"

#include "tensorflow/core/protobuf/rewriter_config.pb.h"
#include "tensorflow/core/tfrt/utils/bridge_graph_analysis.h"

namespace tensorflow {
namespace tfrt_stub {

tensorflow::SessionOptions CreateDefaultSessionOptions(
    const GraphExecutionOptions& options) {
  tensorflow::SessionOptions session_options;
  auto& config = session_options.config;

  config.mutable_graph_options()
      ->mutable_rewrite_options()
      ->set_disable_meta_optimizer(!options.compile_options.enable_grappler);

  // The following configs are constant.

  // Avoid grappler logic that lowers to v1 control flow.
  config.mutable_experimental()->set_use_tfrt(true);
  config.mutable_graph_options()
      ->mutable_optimizer_options()
      ->set_do_function_inlining(false);
  // Do not skip grappler optimization even for small graphs.
  config.mutable_graph_options()
      ->mutable_rewrite_options()
      ->set_min_graph_nodes(-1);
  // Disable function inlining because it may cause restore graphs to be removed
  // as we optimize all graphs together.
  config.mutable_graph_options()
      ->mutable_rewrite_options()
      ->set_function_optimization(tensorflow::RewriterConfig::OFF);

  return session_options;
}

void UpdateTpuTargetByBridgeCompatibility(
    tensorflow::tfrt_stub::GraphExecutionOptions& options,
    const tensorflow::GraphDef& graph_def) {
  if (options.compile_options.tpu_target ==
      tensorflow::TfrtTpuInfraTarget::kBridgeFallback) {
    auto s = tfrt::CheckTpuMlirBridgeCompatibility(graph_def);
    if (!s.ok()) {
      LOG(INFO)
          << "TFRT detected Bridge unsupported feature, using TF fallback";
      options.compile_options.tpu_target =
          tensorflow::TfrtTpuInfraTarget::kTfFallback;
    } else {
      options.compile_options.tpu_target =
          tensorflow::TfrtTpuInfraTarget::kTpurt;
    }
  }
  LOG(INFO) << "TFRT uses TPU target " << options.compile_options.tpu_target;
}

}  // namespace tfrt_stub
}  // namespace tensorflow
<|endoftext|>


<commit_before>// Copyright (c) 2015 Felix Rieseberg <feriese@microsoft.com> and Jason Poon <jason.poon@microsoft.com>. All rights reserved.
// Copyright (c) 2015 Ryan McShane <rmcshane@bandwidth.com> and Brandon Smith <bsmith@bandwidth.com>
// Thanks to both of those folks mentioned above who first thought up a bunch of this code
// and released it as MIT to the world.

#include "browser/win/windows_toast_notification.h"

#include "base/strings/utf_string_conversions.h"
#include "browser/win/scoped_hstring.h"
#include "content/public/browser/desktop_notification_delegate.h"

using namespace ABI::Windows::Data::Xml::Dom;

namespace brightray {

namespace {

// Initialize Windows Runtime

HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED);

}  // namespace

WindowsToastNotification::WindowsToastNotification(
    const std::string& app_name,
    scoped_ptr<content::DesktopNotificationDelegate> delegate)
    : delegate_(delegate.Pass()),
      weak_factory_(this) {
  ScopedHString toast_manager_str(
      RuntimeClass_Windows_UI_Notifications_ToastNotificationManager);
  if (!toast_manager_str.success())
    return;
  HRESULT hr = Windows::Foundation::GetActivationFactory(
      toast_manager_str, &toast_manager_);
  if (FAILED(hr))
    return;

  ScopedHString app_id(base::UTF8ToUTF16(app_name).c_str());
  if (!app_id.success())
    return;

  toast_manager_->CreateToastNotifierWithId(app_id, &toast_notifier_);
}

WindowsToastNotification::~WindowsToastNotification() {
}

void WindowsToastNotification::ShowNotification(
    const std::wstring& title,
    const std::wstring& msg,
    std::string icon_path) {
  ComPtr<IXmlDocument> toast_xml;
  if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml)))
    return;

  ScopedHString toast_str(
      RuntimeClass_Windows_UI_Notifications_ToastNotification);
  if (!toast_str.success())
    return;

  ComPtr<ABI::Windows::UI::Notifications::IToastNotificationFactory> toast_factory;
  if (FAILED(Windows::Foundation::GetActivationFactory(toast_str,
                                                       &toast_factory)))
    return;

  if (FAILED(toast_factory->CreateToastNotification(toast_xml.Get(),
                                                    &toast_notification_)))
    return;

  if (FAILED(SetupCallbacks(toast_notification_.Get())))
    return;

  if (FAILED(toast_notifier_->Show(toast_notification_.Get())))
    return;

  delegate_->NotificationDisplayed();
}

void WindowsToastNotification::DismissNotification() {
  toast_notifier_->Hide(toast_notification_.Get());
}

void WindowsToastNotification::NotificationClicked() {
  delegate_->NotificationClick();
  delete this;
}

void WindowsToastNotification::NotificationDismissed() {
  delegate_->NotificationClosed();
  delete this;
}

bool WindowsToastNotification::GetToastXml(
    ABI::Windows::UI::Notifications::IToastNotificationManagerStatics* toastManager,
    const std::wstring& title,
    const std::wstring& msg,
    std::string icon_path,
    IXmlDocument** toast_xml) {
  ABI::Windows::UI::Notifications::ToastTemplateType template_type;
  if (title.empty() || msg.empty()) {
    // Single line toast.
    template_type = icon_path.empty() ? ABI::Windows::UI::Notifications::ToastTemplateType_ToastText01 :
                                        ABI::Windows::UI::Notifications::ToastTemplateType_ToastImageAndText01;
    if (FAILED(toast_manager_->GetTemplateContent(template_type, toast_xml)))
      return false;
    if (!SetXmlText(*toast_xml, title.empty() ? msg : title))
      return false;
  } else {
    // Title and body toast.
    template_type = icon_path.empty() ? ABI::Windows::UI::Notifications::ToastTemplateType_ToastText02 :
                                        ABI::Windows::UI::Notifications::ToastTemplateType_ToastImageAndText02;
    if (FAILED(toastManager->GetTemplateContent(template_type, toast_xml)))
      return false;
    if (!SetXmlText(*toast_xml, title, msg))
      return false;
  }

  // Toast has image
  if (!icon_path.empty())
    return SetXmlImage(*toast_xml, icon_path);

  return true;
}

bool WindowsToastNotification::SetXmlText(
    IXmlDocument* doc, const std::wstring& text) {
  ScopedHString tag;
  ComPtr<IXmlNodeList> node_list;
  if (!GetTextNodeList(&tag, doc, &node_list, 1))
    return false;

  ComPtr<IXmlNode> node;
  if (FAILED(node_list->Item(0, &node)))
    return false;

  return AppendTextToXml(doc, node.Get(), text);
}

bool WindowsToastNotification::SetXmlText(
    IXmlDocument* doc, const std::wstring& title, const std::wstring& body) {
  ScopedHString tag;
  ComPtr<IXmlNodeList> node_list;
  if (!GetTextNodeList(&tag, doc, &node_list, 2))
    return false;

  ComPtr<IXmlNode> node;
  if (FAILED(node_list->Item(0, &node)))
    return false;

  if (!AppendTextToXml(doc, node.Get(), title))
    return false;

  if (FAILED(node_list->Item(1, &node)))
    return false;

  return AppendTextToXml(doc, node.Get(), body);
}

bool WindowsToastNotification::SetXmlImage(
    IXmlDocument* doc, std::string icon_path) {
  ScopedHString tag(L"imag");
  if (!tag.success())
    return false;

  ComPtr<IXmlNodeList> node_list;
  if (FAILED(doc->GetElementsByTagName(tag, &node_list)))
    return false;

  ComPtr<IXmlNode> image_node;
  if (FAILED(node_list->Item(0, &image_node)))
    return false;

  ComPtr<IXmlNamedNodeMap> attrs;
  if (FAILED(image_node->get_Attributes(&attrs)))
    return false;

  ScopedHString src(L"src");
  if (!src.success())
    return false;

  ComPtr<IXmlNode> src_attr;
  if (FAILED(attrs->GetNamedItem(src, &src_attr)))
    return false;

  ScopedHString img_path(base::UTF8ToUTF16(icon_path).c_str());
  if (!img_path.success())
    return false;

  ComPtr<IXmlText> src_text;
  if (FAILED(doc->CreateTextNode(img_path, &src_text)))
    return false;

  ComPtr<IXmlNode> src_node;
  if (FAILED(src_text.As(&src_node)))
    return false;

  ComPtr<IXmlNode> child_node;
  return SUCCEEDED(src_attr->AppendChild(src_node.Get(), &child_node));
}

bool WindowsToastNotification::GetTextNodeList(
    ScopedHString* tag,
    IXmlDocument* doc,
    IXmlNodeList** node_list,
    UINT32 req_length) {
  tag->Set(L"text");
  if (!tag->success())
    return false;

  if (FAILED(doc->GetElementsByTagName(*tag, node_list)))
    return false;

  UINT32 node_length;
  if (FAILED((*node_list)->get_Length(&node_length)))
    return false;

  return node_length >= req_length;
}

bool WindowsToastNotification::AppendTextToXml(
    IXmlDocument* doc, IXmlNode* node, const std::wstring& text) {
  ScopedHString str(text);
  if (!str.success())
    return false;

  ComPtr<IXmlText> xml_text;
  if (FAILED(doc->CreateTextNode(str, &xml_text)))
    return false;

  ComPtr<IXmlNode> text_node;
  if (FAILED(xml_text.As(&text_node)))
    return false;

  ComPtr<IXmlNode> append_node;
  return SUCCEEDED(node->AppendChild(text_node.Get(), &append_node));
}

bool WindowsToastNotification::SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast) {
  EventRegistrationToken activatedToken, dismissedToken;
  event_handler_ = Make<ToastEventHandler>(this);
  if (FAILED(toast->add_Activated(event_handler_.Get(), &activatedToken)))
    return false;

  return SUCCEEDED(toast->add_Dismissed(event_handler_.Get(), &dismissedToken));
}

/*
/ Toast Event Handler
*/
ToastEventHandler::ToastEventHandler(WindowsToastNotification* notification)
    : notification_(notification) {
}

ToastEventHandler::~ToastEventHandler() {
}

IFACEMETHODIMP ToastEventHandler::Invoke(
    ABI::Windows::UI::Notifications::IToastNotification* sender, IInspectable* args) {
  notification_->NotificationClicked();
  return S_OK;
}

IFACEMETHODIMP ToastEventHandler::Invoke(
    ABI::Windows::UI::Notifications::IToastNotification* sender,
    ABI::Windows::UI::Notifications::IToastDismissedEventArgs* e) {
  notification_->NotificationDismissed();
  return S_OK;
}

}  // namespace brightray
<commit_msg>Windows Toasts: Don't call WFI statically<commit_after>// Copyright (c) 2015 Felix Rieseberg <feriese@microsoft.com> and Jason Poon <jason.poon@microsoft.com>. All rights reserved.
// Copyright (c) 2015 Ryan McShane <rmcshane@bandwidth.com> and Brandon Smith <bsmith@bandwidth.com>
// Thanks to both of those folks mentioned above who first thought up a bunch of this code
// and released it as MIT to the world.

#include "browser/win/windows_toast_notification.h"

#include "base/strings/utf_string_conversions.h"
#include "browser/win/scoped_hstring.h"
#include "content/public/browser/desktop_notification_delegate.h"

using namespace ABI::Windows::Data::Xml::Dom;

namespace brightray {

WindowsToastNotification::WindowsToastNotification(
    const std::string& app_name,
    scoped_ptr<content::DesktopNotificationDelegate> delegate)
    : delegate_(delegate.Pass()),
      weak_factory_(this) {
  // If it wasn't for Windows 7, we could do this statically
  HRESULT init = Windows::Foundation::Initialize(RO_INIT_MULTITHREADED);

  ScopedHString toast_manager_str(
      RuntimeClass_Windows_UI_Notifications_ToastNotificationManager);
  if (!toast_manager_str.success())
    return;
  HRESULT hr = Windows::Foundation::GetActivationFactory(
      toast_manager_str, &toast_manager_);
  if (FAILED(hr))
    return;

  ScopedHString app_id(base::UTF8ToUTF16(app_name).c_str());
  if (!app_id.success())
    return;

  toast_manager_->CreateToastNotifierWithId(app_id, &toast_notifier_);
}

WindowsToastNotification::~WindowsToastNotification() {
}

void WindowsToastNotification::ShowNotification(
    const std::wstring& title,
    const std::wstring& msg,
    std::string icon_path) {
  ComPtr<IXmlDocument> toast_xml;
  if(FAILED(GetToastXml(toast_manager_.Get(), title, msg, icon_path, &toast_xml)))
    return;

  ScopedHString toast_str(
      RuntimeClass_Windows_UI_Notifications_ToastNotification);
  if (!toast_str.success())
    return;

  ComPtr<ABI::Windows::UI::Notifications::IToastNotificationFactory> toast_factory;
  if (FAILED(Windows::Foundation::GetActivationFactory(toast_str,
                                                       &toast_factory)))
    return;

  if (FAILED(toast_factory->CreateToastNotification(toast_xml.Get(),
                                                    &toast_notification_)))
    return;

  if (FAILED(SetupCallbacks(toast_notification_.Get())))
    return;

  if (FAILED(toast_notifier_->Show(toast_notification_.Get())))
    return;

  delegate_->NotificationDisplayed();
}

void WindowsToastNotification::DismissNotification() {
  toast_notifier_->Hide(toast_notification_.Get());
}

void WindowsToastNotification::NotificationClicked() {
  delegate_->NotificationClick();
  delete this;
}

void WindowsToastNotification::NotificationDismissed() {
  delegate_->NotificationClosed();
  delete this;
}

bool WindowsToastNotification::GetToastXml(
    ABI::Windows::UI::Notifications::IToastNotificationManagerStatics* toastManager,
    const std::wstring& title,
    const std::wstring& msg,
    std::string icon_path,
    IXmlDocument** toast_xml) {
  ABI::Windows::UI::Notifications::ToastTemplateType template_type;
  if (title.empty() || msg.empty()) {
    // Single line toast.
    template_type = icon_path.empty() ? ABI::Windows::UI::Notifications::ToastTemplateType_ToastText01 :
                                        ABI::Windows::UI::Notifications::ToastTemplateType_ToastImageAndText01;
    if (FAILED(toast_manager_->GetTemplateContent(template_type, toast_xml)))
      return false;
    if (!SetXmlText(*toast_xml, title.empty() ? msg : title))
      return false;
  } else {
    // Title and body toast.
    template_type = icon_path.empty() ? ABI::Windows::UI::Notifications::ToastTemplateType_ToastText02 :
                                        ABI::Windows::UI::Notifications::ToastTemplateType_ToastImageAndText02;
    if (FAILED(toastManager->GetTemplateContent(template_type, toast_xml)))
      return false;
    if (!SetXmlText(*toast_xml, title, msg))
      return false;
  }

  // Toast has image
  if (!icon_path.empty())
    return SetXmlImage(*toast_xml, icon_path);

  return true;
}

bool WindowsToastNotification::SetXmlText(
    IXmlDocument* doc, const std::wstring& text) {
  ScopedHString tag;
  ComPtr<IXmlNodeList> node_list;
  if (!GetTextNodeList(&tag, doc, &node_list, 1))
    return false;

  ComPtr<IXmlNode> node;
  if (FAILED(node_list->Item(0, &node)))
    return false;

  return AppendTextToXml(doc, node.Get(), text);
}

bool WindowsToastNotification::SetXmlText(
    IXmlDocument* doc, const std::wstring& title, const std::wstring& body) {
  ScopedHString tag;
  ComPtr<IXmlNodeList> node_list;
  if (!GetTextNodeList(&tag, doc, &node_list, 2))
    return false;

  ComPtr<IXmlNode> node;
  if (FAILED(node_list->Item(0, &node)))
    return false;

  if (!AppendTextToXml(doc, node.Get(), title))
    return false;

  if (FAILED(node_list->Item(1, &node)))
    return false;

  return AppendTextToXml(doc, node.Get(), body);
}

bool WindowsToastNotification::SetXmlImage(
    IXmlDocument* doc, std::string icon_path) {
  ScopedHString tag(L"imag");
  if (!tag.success())
    return false;

  ComPtr<IXmlNodeList> node_list;
  if (FAILED(doc->GetElementsByTagName(tag, &node_list)))
    return false;

  ComPtr<IXmlNode> image_node;
  if (FAILED(node_list->Item(0, &image_node)))
    return false;

  ComPtr<IXmlNamedNodeMap> attrs;
  if (FAILED(image_node->get_Attributes(&attrs)))
    return false;

  ScopedHString src(L"src");
  if (!src.success())
    return false;

  ComPtr<IXmlNode> src_attr;
  if (FAILED(attrs->GetNamedItem(src, &src_attr)))
    return false;

  ScopedHString img_path(base::UTF8ToUTF16(icon_path).c_str());
  if (!img_path.success())
    return false;

  ComPtr<IXmlText> src_text;
  if (FAILED(doc->CreateTextNode(img_path, &src_text)))
    return false;

  ComPtr<IXmlNode> src_node;
  if (FAILED(src_text.As(&src_node)))
    return false;

  ComPtr<IXmlNode> child_node;
  return SUCCEEDED(src_attr->AppendChild(src_node.Get(), &child_node));
}

bool WindowsToastNotification::GetTextNodeList(
    ScopedHString* tag,
    IXmlDocument* doc,
    IXmlNodeList** node_list,
    UINT32 req_length) {
  tag->Set(L"text");
  if (!tag->success())
    return false;

  if (FAILED(doc->GetElementsByTagName(*tag, node_list)))
    return false;

  UINT32 node_length;
  if (FAILED((*node_list)->get_Length(&node_length)))
    return false;

  return node_length >= req_length;
}

bool WindowsToastNotification::AppendTextToXml(
    IXmlDocument* doc, IXmlNode* node, const std::wstring& text) {
  ScopedHString str(text);
  if (!str.success())
    return false;

  ComPtr<IXmlText> xml_text;
  if (FAILED(doc->CreateTextNode(str, &xml_text)))
    return false;

  ComPtr<IXmlNode> text_node;
  if (FAILED(xml_text.As(&text_node)))
    return false;

  ComPtr<IXmlNode> append_node;
  return SUCCEEDED(node->AppendChild(text_node.Get(), &append_node));
}

bool WindowsToastNotification::SetupCallbacks(ABI::Windows::UI::Notifications::IToastNotification* toast) {
  EventRegistrationToken activatedToken, dismissedToken;
  event_handler_ = Make<ToastEventHandler>(this);
  if (FAILED(toast->add_Activated(event_handler_.Get(), &activatedToken)))
    return false;

  return SUCCEEDED(toast->add_Dismissed(event_handler_.Get(), &dismissedToken));
}

/*
/ Toast Event Handler
*/
ToastEventHandler::ToastEventHandler(WindowsToastNotification* notification)
    : notification_(notification) {
}

ToastEventHandler::~ToastEventHandler() {
}

IFACEMETHODIMP ToastEventHandler::Invoke(
    ABI::Windows::UI::Notifications::IToastNotification* sender, IInspectable* args) {
  notification_->NotificationClicked();
  return S_OK;
}

IFACEMETHODIMP ToastEventHandler::Invoke(
    ABI::Windows::UI::Notifications::IToastNotification* sender,
    ABI::Windows::UI::Notifications::IToastDismissedEventArgs* e) {
  notification_->NotificationDismissed();
  return S_OK;
}

}  // namespace brightray
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2017 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP
#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP

#include <mapnik/json/json_value.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp>
#pragma GCC diagnostic pop

#include <vector>

namespace mapnik { namespace json {

namespace x3 = boost::spirit::x3;

namespace grammar {

using generic_json_grammar_type = x3::rule<class generic_json_tag, json_value>;
using generic_json_key_value_type = x3::rule<class json_object_element_tag, json_object_element>;
BOOST_SPIRIT_DECLARE(generic_json_grammar_type);
BOOST_SPIRIT_DECLARE(generic_json_key_value_type);
}

auto assign = [](auto const& ctx)
{
    _val(ctx) = _attr(ctx);
};

auto assign_key = [](auto const& ctx)
{
    std::get<0>(_val(ctx)) = _attr(ctx);
};

auto assign_value = [](auto const& ctx)
{
    std::get<1>(_val(ctx)) = std::move(_attr(ctx));
};

grammar::generic_json_grammar_type const& generic_json_grammar();
grammar::generic_json_key_value_type const& generic_json_key_value();

}}

#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP
<commit_msg>trying to `inline` lambdas (VS2017) (!)<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2017 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP
#define MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP

#include <mapnik/json/json_value.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp>
#pragma GCC diagnostic pop

#include <vector>

namespace mapnik { namespace json {

namespace x3 = boost::spirit::x3;

namespace grammar {

using generic_json_grammar_type = x3::rule<class generic_json_tag, json_value>;
using generic_json_key_value_type = x3::rule<class json_object_element_tag, json_object_element>;
BOOST_SPIRIT_DECLARE(generic_json_grammar_type);
BOOST_SPIRIT_DECLARE(generic_json_key_value_type);
}

inline auto assign = [](auto const& ctx)
{
    _val(ctx) = _attr(ctx);
};

inline auto assign_key = [](auto const& ctx)
{
    std::get<0>(_val(ctx)) = std::move(_attr(ctx));
};

inline auto assign_value = [](auto const& ctx)
{
    std::get<1>(_val(ctx)) = std::move(_attr(ctx));
};

grammar::generic_json_grammar_type const& generic_json_grammar();
grammar::generic_json_key_value_type const& generic_json_key_value();

}}

#endif // MAPNIK_JSON_GENERIC_JSON_GRAMMAR_X3_HPP
<|endoftext|>


<commit_before>#include "Node.h"
#include "sim/config.h"
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

namespace Simulator
{

// Memory management data
/*static*/ unsigned long                   COMA::Node::g_References   = 0;
/*static*/ COMA::Node::Message*            COMA::Node::g_FreeMessages = NULL;
/*static*/ std::list<COMA::Node::Message*> COMA::Node::g_Messages;

/*static*/ void* COMA::Node::Message::operator new(size_t size)
{
    // We allocate this many messages at once
    static const size_t ALLOCATE_SIZE = 1024;

    assert(size == sizeof(Message));
    if (g_FreeMessages == NULL)
    {
        // Allocate more messages
        Message* msg = new Message[ALLOCATE_SIZE];
        g_Messages.push_back(msg);

        // Link the new messages into the free list
        for (size_t i = 0; i < ALLOCATE_SIZE; ++i, ++msg)
        {
            msg->next = g_FreeMessages;
            g_FreeMessages = msg;
        }
    }
    assert(g_FreeMessages != NULL);

    // Grab a message off the free list
    Message* msg = g_FreeMessages;
    g_FreeMessages = msg->next;
    return msg;
}

/*static*/ void COMA::Node::Message::operator delete(void *p, size_t size)
{
    assert(size == sizeof(Message));
    Message* msg = static_cast<Message*>(p);

#ifndef NDEBUG
    // Fill the message with garbage
    memset(msg, 0xFE, sizeof(Message));
#endif

    // Append the message to the free list
    msg->next = g_FreeMessages;
    g_FreeMessages = msg;
}

/*static*/ void COMA::Node::PrintMessage(std::ostream& out, const Message& msg)
{
    switch (msg.type)
    {
    case Message::REQUEST:            out << "| Read Request        "; break;
    case Message::REQUEST_DATA:       out << "| Read Request (Data) "; break;
    case Message::REQUEST_DATA_TOKEN: out << "| Read Response       "; break;
    case Message::EVICTION:           out << "| Eviction            "; break;
    case Message::UPDATE:             out << "| Update              "; break;
    }

    out << " | "
        << "0x" << hex << setfill('0') << setw(16) << msg.address << " | "
        << dec << setfill(' ') << right
        << setw(6);

    switch (msg.type)
    {
    case Message::EVICTION:
    case Message::REQUEST_DATA_TOKEN:
        out << msg.tokens;
        break;

    case Message::REQUEST:
    case Message::REQUEST_DATA:
    case Message::UPDATE:
        out << "";
        break;
    }

    out << " | "
        << setw(6) << msg.sender << " | "
        << endl;
}

/*static*/ void COMA::Node::Print(std::ostream& out, const std::string& name, const Buffer<Message*>& buffer)
{
    std::string sp_left((61 - name.length()) / 2, ' ');
    std::string sp_right(61 - sp_left.length() - name.length(), ' ');

    out <<
    "+-------------------------------------------------------------+\n"
    "|" << sp_left << name << sp_right << "|\n"
    "+----------------------+--------------------+--------+--------+\n"
    "|         Type         |       Address      | Tokens | Sender |\n"
    "+----------------------+--------------------+--------+--------+\n";

    for (Buffer<Message*>::const_iterator p = buffer.begin(); p != buffer.end(); ++p)
    {
        PrintMessage(out, **p);
    }
    out << "+----------------------+--------------------+--------+--------+\n\n";
}

void COMA::Node::Print(std::ostream& out) const
{
    Print(out, "incoming", m_incoming);
    Print(out, "outgoing", m_outgoing);
}

void COMA::Node::Initialize(Node* next, Node* prev)
{
    m_prev = prev;
    m_next = next;
    p_Forward.SetStorageTraces(next->m_incoming);
}

Result COMA::Node::DoForward()
{
    // Forward requests to the next node
    assert(!m_outgoing.Empty());
    assert(m_next != NULL);

    if (!m_next->m_incoming.Push( m_outgoing.Front() ))
    {
        DeadlockWrite("Unable to send request to next node");
        return FAILED;
    }
    m_outgoing.Pop();
    return SUCCESS;
}

// Send a message to the next node.
// Only succeeds if there's min_space left before the push.
bool COMA::Node::SendMessage(Message* message, size_t min_space)
{
    if (!m_outgoing.Push(message, min_space))
    {
        return false;
    }
    return true;
}

COMA::Node::Node(const std::string& name, COMA& parent, Clock& clock, Config& config)
    : Simulator::Object(name, parent),
      COMA::Object(name, parent),
      m_prev(NULL),
      m_next(NULL),
      m_incoming("b_incoming", *this, clock, config.getValue<BufferSize>(*this, "NodeBufferSize")),
      m_outgoing("b_outgoing", *this, clock, config.getValue<BufferSize>(*this, "NodeBufferSize")),
      p_Forward(*this, "forward", delegate::create<Node, &Node::DoForward>(*this))
{
    g_References++;

    m_outgoing.Sensitive(p_Forward);
}

COMA::Node::~Node()
{
    assert(g_References > 0);
    if (--g_References == 0)
    {
        // Clean up the allocated messages
        for (std::list<Message*>::const_iterator p = g_Messages.begin(); p != g_Messages.end(); ++p)
        {
            delete[] *p;
        }
        g_Messages.clear();
    }
}

}
<commit_msg>[mgsim] Report the name of the next node in COMA network deadlock messages.<commit_after>#include "Node.h"
#include "sim/config.h"
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

namespace Simulator
{

// Memory management data
/*static*/ unsigned long                   COMA::Node::g_References   = 0;
/*static*/ COMA::Node::Message*            COMA::Node::g_FreeMessages = NULL;
/*static*/ std::list<COMA::Node::Message*> COMA::Node::g_Messages;

/*static*/ void* COMA::Node::Message::operator new(size_t size)
{
    // We allocate this many messages at once
    static const size_t ALLOCATE_SIZE = 1024;

    assert(size == sizeof(Message));
    if (g_FreeMessages == NULL)
    {
        // Allocate more messages
        Message* msg = new Message[ALLOCATE_SIZE];
        g_Messages.push_back(msg);

        // Link the new messages into the free list
        for (size_t i = 0; i < ALLOCATE_SIZE; ++i, ++msg)
        {
            msg->next = g_FreeMessages;
            g_FreeMessages = msg;
        }
    }
    assert(g_FreeMessages != NULL);

    // Grab a message off the free list
    Message* msg = g_FreeMessages;
    g_FreeMessages = msg->next;
    return msg;
}

/*static*/ void COMA::Node::Message::operator delete(void *p, size_t size)
{
    assert(size == sizeof(Message));
    Message* msg = static_cast<Message*>(p);

#ifndef NDEBUG
    // Fill the message with garbage
    memset(msg, 0xFE, sizeof(Message));
#endif

    // Append the message to the free list
    msg->next = g_FreeMessages;
    g_FreeMessages = msg;
}

/*static*/ void COMA::Node::PrintMessage(std::ostream& out, const Message& msg)
{
    switch (msg.type)
    {
    case Message::REQUEST:            out << "| Read Request        "; break;
    case Message::REQUEST_DATA:       out << "| Read Request (Data) "; break;
    case Message::REQUEST_DATA_TOKEN: out << "| Read Response       "; break;
    case Message::EVICTION:           out << "| Eviction            "; break;
    case Message::UPDATE:             out << "| Update              "; break;
    }

    out << " | "
        << "0x" << hex << setfill('0') << setw(16) << msg.address << " | "
        << dec << setfill(' ') << right
        << setw(6);

    switch (msg.type)
    {
    case Message::EVICTION:
    case Message::REQUEST_DATA_TOKEN:
        out << msg.tokens;
        break;

    case Message::REQUEST:
    case Message::REQUEST_DATA:
    case Message::UPDATE:
        out << "";
        break;
    }

    out << " | "
        << setw(6) << msg.sender << " | "
        << endl;
}

/*static*/ void COMA::Node::Print(std::ostream& out, const std::string& name, const Buffer<Message*>& buffer)
{
    std::string sp_left((61 - name.length()) / 2, ' ');
    std::string sp_right(61 - sp_left.length() - name.length(), ' ');

    out <<
    "+-------------------------------------------------------------+\n"
    "|" << sp_left << name << sp_right << "|\n"
    "+----------------------+--------------------+--------+--------+\n"
    "|         Type         |       Address      | Tokens | Sender |\n"
    "+----------------------+--------------------+--------+--------+\n";

    for (Buffer<Message*>::const_iterator p = buffer.begin(); p != buffer.end(); ++p)
    {
        PrintMessage(out, **p);
    }
    out << "+----------------------+--------------------+--------+--------+\n\n";
}

void COMA::Node::Print(std::ostream& out) const
{
    Print(out, "incoming", m_incoming);
    Print(out, "outgoing", m_outgoing);
}

void COMA::Node::Initialize(Node* next, Node* prev)
{
    m_prev = prev;
    m_next = next;
    p_Forward.SetStorageTraces(next->m_incoming);
}

Result COMA::Node::DoForward()
{
    // Forward requests to the next node
    assert(!m_outgoing.Empty());
    assert(m_next != NULL);

    if (!m_next->m_incoming.Push( m_outgoing.Front() ))
    {
        DeadlockWrite("Unable to send request to next node (%s)", m_next->GetFQN().c_str());
        return FAILED;
    }
    m_outgoing.Pop();
    return SUCCESS;
}

// Send a message to the next node.
// Only succeeds if there's min_space left before the push.
bool COMA::Node::SendMessage(Message* message, size_t min_space)
{
    if (!m_outgoing.Push(message, min_space))
    {
        return false;
    }
    return true;
}

COMA::Node::Node(const std::string& name, COMA& parent, Clock& clock, Config& config)
    : Simulator::Object(name, parent),
      COMA::Object(name, parent),
      m_prev(NULL),
      m_next(NULL),
      m_incoming("b_incoming", *this, clock, config.getValue<BufferSize>(*this, "NodeBufferSize")),
      m_outgoing("b_outgoing", *this, clock, config.getValue<BufferSize>(*this, "NodeBufferSize")),
      p_Forward(*this, "forward", delegate::create<Node, &Node::DoForward>(*this))
{
    g_References++;

    m_outgoing.Sensitive(p_Forward);
}

COMA::Node::~Node()
{
    assert(g_References > 0);
    if (--g_References == 0)
    {
        // Clean up the allocated messages
        for (std::list<Message*>::const_iterator p = g_Messages.begin(); p != g_Messages.end(); ++p)
        {
            delete[] *p;
        }
        g_Messages.clear();
    }
}

}
<|endoftext|>