text:
/*
 * Copyright (c) 2014 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "treent/ResponsiveTextRenderSystem.h"
#include "treent/LocationComponent.h"
#include <boost/algorithm/string.hpp>
#include "cinder/app/App.h"
#include "cinder/Rand.h"

using namespace std;
using namespace cinder;

namespace treent
{

	RespTextComponent::RespTextComponent( ci::gl::TextureFontRef font, const string &text, const float &rank, const ci::ColorA &col, const ci::Vec2f &vel ) :
  _font( font ),
  _color( col ),
  _curr_value( rank ),
  _prev_value( rank ),
  _velocity( vel ),
  _content( text )
{
	// dimensions of text box, increased based on rank
	_rect_width = 50.0f;
	_rect_height = 100.0f;

	// default dimensions of text box and font
	_base_rect_width = _rect_width;
	_base_rect_height = _rect_height;
	_base_font_size = _font->getFont().getSize();

	// ideal max number of characters is a default value for now
	_max_chars = 12; // setMaxChars( text );
  _line_aspect_ratio = _max_chars * 0.519; // using a default font aspect ratio value for now
  reflowLayout( rank, text );
}

void RespTextComponent::setText( const std::string &text )
{
	gl::TextureFont::DrawOptions opt;
	opt.scale( 1.0f / app::getWindow()->getContentScale() ).pixelSnap( false );
	auto gp = _font->getGlyphPlacements( text, opt );
}

int RespTextComponent::setMaxChars( const std::string &text )
{
	string workingWord = "";  //working string
	string maxWord = "";  //biggest word

	// find longest word in string
	for (int i = 0; i < text.size( ); i++)
	{
		//If it's not a space, semicolon, colon, or comma, add it to the word, if it is, reset workingWord
		if (text[i] != ' ' && text[i] != ';' && text[i] != ':' && text[i] != ',')
		{	workingWord += text[i]; }
		else
		{	workingWord = ""; }

		// If workingword > maxWord, we have a new maxWord
		if (workingWord.size( ) > maxWord.size( ))
		{	maxWord = workingWord; }
	}

	return maxWord.size();
}

// split the headline into lines based on character count and word length
void RespTextComponent::splitLines( const std::string &text, int charLimit )
{
	// split text into vector of words
	vector<std::string> words;
	boost::split( words, text, boost::is_any_of( " " ) );

	std::string line = ""; // line to be added, filled with default text

	std::string currWord = ""; // current word
	std::string remainder = ""; // remainder of original text
	std::string nextTwoWords = ""; // next two words
	int wordIndex = 0;

	if ( wordIndex < words.size( ) )
	{
		// currWord is always one word behind nextTwoWords
		// add words to both until the length of one string is less than charLimit
        // per line, while the length of the other is greater than charLimit
		while (nextTwoWords.length() < charLimit)
		{
			currWord = nextTwoWords;
			nextTwoWords += words[wordIndex] + " ";
			wordIndex++;
			if (wordIndex >= words.size())
				break;
		}

		// add a line for whichever string is closer to the character limit
		if ((math<int>::abs( currWord.length() - charLimit ) < math<int>::abs( nextTwoWords.length() - charLimit )) && nextTwoWords.length() > 2)
		{
			line = currWord;
			wordIndex--;
		}
		else
		{
			line = nextTwoWords;
		}

		gl::TextureFont::DrawOptions opt;

		float lineSize = line.size( );
		float lineScale = lmap( lineSize, 1.0f, (float) charLimit, 0.1f, 1.0f );
		opt.scale( lineScale ).pixelSnap( true );
		auto gp = _font->getGlyphPlacements( line, Rectf( 0, 0, _rect_width, _line_height*2 ),opt );
		_glyph_placements.push_back( gp );
		_opts.push_back( opt );

		// repeat with the remainder of the original string
		for (int i = wordIndex; i < words.size(); i++)
		{
			remainder += words[i] + " ";
		}

		if (remainder.size() > charLimit)
		{
			splitLines( remainder, charLimit );
		}

		// if the length of the text is less than charLimit, add
		// this as the last line.
		else
		{
			float lineSize = remainder.size();
			float lineScale = lmap( lineSize, 1.0f, (float) charLimit, 0.1f, 1.0f );

			opt.scale( lineScale ).pixelSnap( true );
			app::console() << "scale: " << opt.getScale() << endl;
			auto gp = _font->getGlyphPlacements( remainder, Rectf( 0, 0, _rect_width, _line_height * 2 ),opt );
			_glyph_placements.push_back( gp );
			_opts.push_back( opt );
		}
	}
}

void RespTextComponent::reflowLayout( float val, const std::string &text )
{
	// change rect dimensions & font size based on rank
	float scaler = lmap( val, 1.0f, 10.0f, 0.5f, 2.0f );

	// with the assumption that val > 0, scale text box width and height by scaler
	_rect_height = _base_rect_height * scaler;
	_rect_width = _base_rect_width * scaler;

	// scale font size with text box
	auto currfont = _font->getFont();
	_font = gl::TextureFont::create( Font( currfont.getName(), _base_font_size * scaler ) );

	auto ideal_line_height = _rect_width /( _line_aspect_ratio*scaler);
	int line_count = ceil( _rect_height / ideal_line_height );

	_line_height = _rect_height / line_count;

	// target character count per line is length of total string divided by number of lines
	int char_ct_per_line = ceil( text.length() / line_count );

	if (char_ct_per_line < setMaxChars( text ))
	{
		// make sure the longest word in the headline is not longer than the
		// per-line character count
		char_ct_per_line = setMaxChars( text );
	}

	_opts.clear();
	_glyph_placements.clear();
	splitLines( text, char_ct_per_line);
}

//
//  MARK: - ResponsiveTextRenderSystem
//
void ResponsiveTextRenderSystem::update( EntityManagerRef entities, EventManagerRef events, double dt )
{
  _grouped_text.clear();
  for (auto entity : entities->entities_with_components<LocationComponent, RespTextComponent>( ))
  {
    LocationComponentRef location;
	RespTextComponentRef     text;
    entity.unpack( location, text );

    _grouped_text[text->_font].push_back( make_pair( location, text ) );
  }
}

void ResponsiveTextRenderSystem::draw( ) const
{
  for( auto &pair : _grouped_text )
  {
    // TODO: custom extension of TextureFont so we can bind each font texture once per draw.
    auto &blocks = pair.second;
    for( auto &pair : blocks )
    {
      LocationComponentRef location = pair.first;
	  RespTextComponentRef text = pair.second;

      gl::ScopedModelMatrix matrix;
      gl::multModelMatrix( Matrix44f( location->matrix ) );

	  for (int i = 0; i < text->_glyph_placements.size(); i++)
	  {
		  auto gp = text->_glyph_placements[i];

		  // if above a certain rank, display the headline in color
		  if (text->_curr_value >= 7)
			  gl::color( text->_color );
		  else
			  gl::color( ColorA::white() );

		  // need a good way to calculate line separation value
		  text->_font->drawGlyphs( gp, Vec2f( 0, (text->_font->getFont().getSize()) * i ), text->_opts[i] );
	  }
    }
  }
}

} // treent::

max_stars_repo_name: pourpluie/Pockets-team

max_issues_repo_name: pourpluie/Pockets-team

max_forks_repo_name: pourpluie/Pockets-team


text:
#include "extractor/extractor.hpp"

#include "extractor/edge_based_edge.hpp"
#include "extractor/extraction_containers.hpp"
#include "extractor/extraction_node.hpp"
#include "extractor/extraction_relation.hpp"
#include "extractor/extraction_way.hpp"
#include "extractor/extractor_callbacks.hpp"
#include "extractor/files.hpp"
#include "extractor/maneuver_override_relation_parser.hpp"
#include "extractor/node_based_graph_factory.hpp"
#include "extractor/raster_source.hpp"
#include "extractor/restriction_filter.hpp"
#include "extractor/restriction_parser.hpp"
#include "extractor/scripting_environment.hpp"

#include "guidance/files.hpp"
#include "guidance/guidance_processing.hpp"
#include "guidance/segregated_intersection_classification.hpp"
#include "guidance/turn_data_container.hpp"

#include "storage/io.hpp"

#include "util/exception.hpp"
#include "util/exception_utils.hpp"
#include "util/graph_loader.hpp"
#include "util/integer_range.hpp"
#include "util/log.hpp"
#include "util/name_table.hpp"
#include "util/range_table.hpp"
#include "util/timing_util.hpp"

#include "extractor/compressed_edge_container.hpp"
#include "extractor/restriction_index.hpp"
#include "extractor/way_restriction_map.hpp"
#include "util/static_graph.hpp"
#include "util/static_rtree.hpp"

// Keep debug include to make sure the debug header is in sync with types.
#include "util/debug.hpp"

#include "extractor/tarjan_scc.hpp"

#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/iterator/function_input_iterator.hpp>
#include <boost/optional/optional.hpp>
#include <boost/scope_exit.hpp>

#include <osmium/handler/node_locations_for_ways.hpp>
#include <osmium/index/map/flex_mem.hpp>
#include <osmium/io/any_input.hpp>
#include <osmium/thread/pool.hpp>
#include <osmium/visitor.hpp>

#include <tbb/pipeline.h>
#include <tbb/task_scheduler_init.h>

#include <cstdlib>

#include <algorithm>
#include <atomic>
#include <bitset>
#include <chrono>
#include <future>
#include <iostream>
#include <iterator>
#include <memory>
#include <thread>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <vector>

namespace osrm
{
namespace extractor
{

namespace
{
// Converts the class name map into a fixed mapping of index to name
void SetClassNames(const std::vector<std::string> &class_names,
                   ExtractorCallbacks::ClassesMap &classes_map,
                   ProfileProperties &profile_properties)
{
    // if we get a list of class names we can validate if we set invalid classes
    // and add classes that were never reference
    if (!class_names.empty())
    {
        // add class names that were never used explicitly on a way
        // this makes sure we can correctly validate unkown class names later
        for (const auto &name : class_names)
        {
            if (!isValidClassName(name))
            {
                throw util::exception("Invalid class name " + name + " only [a-Z0-9] allowed.");
            }

            auto iter = classes_map.find(name);
            if (iter == classes_map.end())
            {
                auto index = classes_map.size();
                if (index > MAX_CLASS_INDEX)
                {
                    throw util::exception("Maximum number of classes is " +
                                          std::to_string(MAX_CLASS_INDEX + 1));
                }

                classes_map[name] = getClassData(index);
            }
        }

        // check if class names are only from the list supplied by the user
        for (const auto &pair : classes_map)
        {
            auto iter = std::find(class_names.begin(), class_names.end(), pair.first);
            if (iter == class_names.end())
            {
                throw util::exception("Profile used unknown class name: " + pair.first);
            }
        }
    }

    for (const auto &pair : classes_map)
    {
        auto range = getClassIndexes(pair.second);
        BOOST_ASSERT(range.size() == 1);
        profile_properties.SetClassName(range.front(), pair.first);
    }
}

// Converts the class name list to a mask list
void SetExcludableClasses(const ExtractorCallbacks::ClassesMap &classes_map,
                          const std::vector<std::vector<std::string>> &excludable_classes,
                          ProfileProperties &profile_properties)
{
    if (excludable_classes.size() > MAX_EXCLUDABLE_CLASSES)
    {
        throw util::exception("Only " + std::to_string(MAX_EXCLUDABLE_CLASSES) +
                              " excludable combinations allowed.");
    }

    // The exclude index 0 is reserve for not excludeing anything
    profile_properties.SetExcludableClasses(0, 0);

    std::size_t combination_index = 1;
    for (const auto &combination : excludable_classes)
    {
        ClassData mask = 0;
        for (const auto &name : combination)
        {
            auto iter = classes_map.find(name);
            if (iter == classes_map.end())
            {
                util::Log(logWARNING)
                    << "Unknown class name " + name + " in excludable combination. Ignoring.";
            }
            else
            {
                mask |= iter->second;
            }
        }

        if (mask > 0)
        {
            profile_properties.SetExcludableClasses(combination_index++, mask);
        }
    }
}
}

/**
 * TODO: Refactor this function into smaller functions for better readability.
 *
 * This function is the entry point for the whole extraction process. The goal of the extraction
 * step is to filter and convert the OSM geometry to something more fitting for routing.
 * That includes:
 *  - extracting turn restrictions
 *  - splitting ways into (directional!) edge segments
 *  - checking if nodes are barriers or traffic signal
 *  - discarding all tag information: All relevant type information for nodes/ways
 *    is extracted at this point.
 *
 * The result of this process are the following files:
 *  .names : Names of all streets, stored as long consecutive string with prefix sum based index
 *  .osrm  : Nodes and edges in a intermediate format that easy to digest for osrm-contract
 *  .restrictions : Turn restrictions that are used by osrm-contract to construct the edge-expanded
 * graph
 *
 */
int Extractor::run(ScriptingEnvironment &scripting_environment)
{
    util::LogPolicy::GetInstance().Unmute();

    const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
    const auto number_of_threads = std::min(recommended_num_threads, config.requested_num_threads);
    tbb::task_scheduler_init init(number_of_threads ? number_of_threads
                                                    : tbb::task_scheduler_init::automatic);
    BOOST_ASSERT(init.is_active());

    LaneDescriptionMap turn_lane_map;
    std::vector<TurnRestriction> turn_restrictions;
    std::vector<ConditionalTurnRestriction> conditional_turn_restrictions;
    std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
    std::tie(turn_lane_map,
             turn_restrictions,
             conditional_turn_restrictions,
             unresolved_maneuver_overrides) =
        ParseOSMData(scripting_environment, number_of_threads);

    // Transform the node-based graph that OSM is based on into an edge-based graph
    // that is better for routing.  Every edge becomes a node, and every valid
    // movement (e.g. turn from A->B, and B->A) becomes an edge
    util::Log() << "Generating edge-expanded graph representation";

    TIMER_START(expansion);

    EdgeBasedNodeDataContainer edge_based_nodes_container;
    std::vector<EdgeBasedNodeSegment> edge_based_node_segments;
    util::DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
    std::vector<bool> node_is_startpoint;
    std::vector<EdgeWeight> edge_based_node_weights;
    std::uint32_t ebg_connectivity_checksum = 0;

    // Create a node-based graph from the OSRM file
    NodeBasedGraphFactory node_based_graph_factory(config.GetPath(".osrm"),
                                                   scripting_environment,
                                                   turn_restrictions,
                                                   conditional_turn_restrictions,
                                                   unresolved_maneuver_overrides);

    util::Log() << "Find segregated edges in node-based graph ..." << std::flush;
    TIMER_START(segregated);

    util::NameTable names(config.GetPath(".osrm.names").string());
    auto segregated_edges = guidance::findSegregatedNodes(node_based_graph_factory, names);

    TIMER_STOP(segregated);
    util::Log() << "ok, after " << TIMER_SEC(segregated) << "s";
    util::Log() << "Segregated edges count = " << segregated_edges.size();

    util::Log() << "Writing nodes for nodes-based and edges-based graphs ...";
    auto const &coordinates = node_based_graph_factory.GetCoordinates();
    files::writeNodes(
        config.GetPath(".osrm.nbg_nodes"), coordinates, node_based_graph_factory.GetOsmNodes());
    node_based_graph_factory.ReleaseOsmNodes();

    auto const &node_based_graph = node_based_graph_factory.GetGraph();

    // The osrm-partition tool requires the compressed node based graph with an embedding.
    //
    // The `Run` function above re-numbers non-reverse compressed node based graph edges
    // to a continuous range so that the nodes in the edge based graph are continuous.
    //
    // Luckily node based node ids still coincide with the coordinate array.
    // That's the reason we can only here write out the final compressed node based graph.

    // Dumps to file asynchronously and makes sure we wait for its completion.
    std::future<void> compressed_node_based_graph_writing;

    BOOST_SCOPE_EXIT_ALL(&)
    {
        if (compressed_node_based_graph_writing.valid())
            compressed_node_based_graph_writing.wait();
    };

    compressed_node_based_graph_writing = std::async(std::launch::async, [&] {
        WriteCompressedNodeBasedGraph(
            config.GetPath(".osrm.cnbg").string(), node_based_graph, coordinates);
    });

    node_based_graph_factory.GetCompressedEdges().PrintStatistics();

    const auto &barrier_nodes = node_based_graph_factory.GetBarriers();
    const auto &traffic_signals = node_based_graph_factory.GetTrafficSignals();
    // stealing the annotation data from the node-based graph
    edge_based_nodes_container =
        EdgeBasedNodeDataContainer({}, std::move(node_based_graph_factory.GetAnnotationData()));

    conditional_turn_restrictions =
        removeInvalidRestrictions(std::move(conditional_turn_restrictions), node_based_graph);

    const auto number_of_node_based_nodes = node_based_graph.GetNumberOfNodes();

    const util::NameTable name_table(config.GetPath(".osrm.names").string());

    const auto number_of_edge_based_nodes =
        BuildEdgeExpandedGraph(node_based_graph,
                               coordinates,
                               node_based_graph_factory.GetCompressedEdges(),
                               barrier_nodes,
                               traffic_signals,
                               turn_restrictions,
                               conditional_turn_restrictions,
                               segregated_edges,
                               name_table,
                               unresolved_maneuver_overrides,
                               turn_lane_map,
                               scripting_environment,
                               edge_based_nodes_container,
                               edge_based_node_segments,
                               node_is_startpoint,
                               edge_based_node_weights,
                               edge_based_edge_list,
                               ebg_connectivity_checksum);

    ProcessGuidanceTurns(node_based_graph,
                         edge_based_nodes_container,
                         coordinates,
                         node_based_graph_factory.GetCompressedEdges(),
                         barrier_nodes,
                         turn_restrictions,
                         conditional_turn_restrictions,
                         name_table,
                         std::move(turn_lane_map),
                         scripting_environment);

    TIMER_STOP(expansion);

    // output the geometry of the node-based graph, needs to be done after the last usage, since it
    // destroys internal containers
    files::writeSegmentData(config.GetPath(".osrm.geometry"),
                            *node_based_graph_factory.GetCompressedEdges().ToSegmentData());

    util::Log() << "Saving edge-based node weights to file.";
    TIMER_START(timer_write_node_weights);
    {
        storage::io::FileWriter writer(config.GetPath(".osrm.enw"),
                                       storage::io::FileWriter::GenerateFingerprint);
        storage::serialization::write(writer, edge_based_node_weights);
    }
    TIMER_STOP(timer_write_node_weights);
    util::Log() << "Done writing. (" << TIMER_SEC(timer_write_node_weights) << ")";

    util::Log() << "Computing strictly connected components ...";
    FindComponents(number_of_edge_based_nodes,
                   edge_based_edge_list,
                   edge_based_node_segments,
                   edge_based_nodes_container);

    util::Log() << "Building r-tree ...";
    TIMER_START(rtree);
    BuildRTree(std::move(edge_based_node_segments), std::move(node_is_startpoint), coordinates);

    TIMER_STOP(rtree);

    files::writeNodeData(config.GetPath(".osrm.ebg_nodes"), edge_based_nodes_container);

    util::Log() << "Writing edge-based-graph edges       ... " << std::flush;
    TIMER_START(write_edges);
    files::writeEdgeBasedGraph(config.GetPath(".osrm.ebg"),
                               number_of_edge_based_nodes,
                               edge_based_edge_list,
                               ebg_connectivity_checksum);
    TIMER_STOP(write_edges);
    util::Log() << "ok, after " << TIMER_SEC(write_edges) << "s";

    util::Log() << "Processed " << edge_based_edge_list.size() << " edges";

    const auto nodes_per_second =
        static_cast<std::uint64_t>(number_of_node_based_nodes / TIMER_SEC(expansion));
    const auto edges_per_second =
        static_cast<std::uint64_t>((number_of_edge_based_nodes) / TIMER_SEC(expansion));

    util::Log() << "Expansion: " << nodes_per_second << " nodes/sec and " << edges_per_second
                << " edges/sec";
    util::Log() << "To prepare the data for routing, run: "
                << "./osrm-contract " << config.GetPath(".osrm");

    return 0;
}

std::tuple<LaneDescriptionMap,
           std::vector<TurnRestriction>,
           std::vector<ConditionalTurnRestriction>,
           std::vector<UnresolvedManeuverOverride>>
Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
                        const unsigned number_of_threads)
{
    TIMER_START(extracting);

    util::Log() << "Input file: " << config.input_path.filename().string();
    if (!config.profile_path.empty())
    {
        util::Log() << "Profile: " << config.profile_path.filename().string();
    }
    util::Log() << "Threads: " << number_of_threads;

    const osmium::io::File input_file(config.input_path.string());
    osmium::thread::Pool pool(number_of_threads);

    util::Log() << "Parsing in progress..";
    TIMER_START(parsing);

    { // Parse OSM header
        osmium::io::Reader reader(input_file, pool, osmium::osm_entity_bits::nothing);
        osmium::io::Header header = reader.header();

        std::string generator = header.get("generator");
        if (generator.empty())
        {
            generator = "unknown tool";
        }
        util::Log() << "input file generated by " << generator;

        // write .timestamp data file
        std::string timestamp = header.get("osmosis_replication_timestamp");
        if (timestamp.empty())
        {
            timestamp = "n/a";
        }
        util::Log() << "timestamp: " << timestamp;

        storage::io::FileWriter timestamp_file(config.GetPath(".osrm.timestamp"),
                                               storage::io::FileWriter::GenerateFingerprint);

        timestamp_file.WriteFrom(timestamp.c_str(), timestamp.length());
    }

    // Extraction containers and restriction parser
    ExtractionContainers extraction_containers;
    ExtractorCallbacks::ClassesMap classes_map;
    LaneDescriptionMap turn_lane_map;
    auto extractor_callbacks =
        std::make_unique<ExtractorCallbacks>(extraction_containers,
                                             classes_map,
                                             turn_lane_map,
                                             scripting_environment.GetProfileProperties());

    // get list of supported relation types
    auto relation_types = scripting_environment.GetRelations();
    std::sort(relation_types.begin(), relation_types.end());

    std::vector<std::string> restrictions = scripting_environment.GetRestrictions();
    // setup restriction parser
    const RestrictionParser restriction_parser(
        scripting_environment.GetProfileProperties().use_turn_restrictions,
        config.parse_conditionals,
        restrictions);

    const ManeuverOverrideRelationParser maneuver_override_parser;

    // OSM data reader
    using SharedBuffer = std::shared_ptr<osmium::memory::Buffer>;
    struct ParsedBuffer
    {
        SharedBuffer buffer;
        std::vector<std::pair<const osmium::Node &, ExtractionNode>> resulting_nodes;
        std::vector<std::pair<const osmium::Way &, ExtractionWay>> resulting_ways;
        std::vector<std::pair<const osmium::Relation &, ExtractionRelation>> resulting_relations;
        std::vector<InputConditionalTurnRestriction> resulting_restrictions;
        std::vector<InputManeuverOverride> resulting_maneuver_overrides;
    };

    ExtractionRelationContainer relations;

    const auto buffer_reader = [](osmium::io::Reader &reader) {
        return tbb::filter_t<void, SharedBuffer>(
            tbb::filter::serial_in_order, [&reader](tbb::flow_control &fc) {
                if (auto buffer = reader.read())
                {
                    return std::make_shared<osmium::memory::Buffer>(std::move(buffer));
                }
                else
                {
                    fc.stop();
                    return SharedBuffer{};
                }
            });
    };

    // Node locations cache (assumes nodes are placed before ways)
    using osmium_index_type =
        osmium::index::map::FlexMem<osmium::unsigned_object_id_type, osmium::Location>;
    using osmium_location_handler_type = osmium::handler::NodeLocationsForWays<osmium_index_type>;

    osmium_index_type location_cache;
    osmium_location_handler_type location_handler(location_cache);

    tbb::filter_t<SharedBuffer, SharedBuffer> location_cacher(
        tbb::filter::serial_in_order, [&location_handler](SharedBuffer buffer) {
            osmium::apply(buffer->begin(), buffer->end(), location_handler);
            return buffer;
        });

    // OSM elements Lua parser
    tbb::filter_t<SharedBuffer, ParsedBuffer> buffer_transformer(
        tbb::filter::parallel, [&](const SharedBuffer buffer) {

            ParsedBuffer parsed_buffer;
            parsed_buffer.buffer = buffer;
            scripting_environment.ProcessElements(*buffer,
                                                  restriction_parser,
                                                  maneuver_override_parser,
                                                  relations,
                                                  parsed_buffer.resulting_nodes,
                                                  parsed_buffer.resulting_ways,
                                                  parsed_buffer.resulting_restrictions,
                                                  parsed_buffer.resulting_maneuver_overrides);
            return parsed_buffer;
        });

    // Parsed nodes and ways handler
    unsigned number_of_nodes = 0;
    unsigned number_of_ways = 0;
    unsigned number_of_restrictions = 0;
    unsigned number_of_maneuver_overrides = 0;
    tbb::filter_t<ParsedBuffer, void> buffer_storage(
        tbb::filter::serial_in_order, [&](const ParsedBuffer &parsed_buffer) {

            number_of_nodes += parsed_buffer.resulting_nodes.size();
            // put parsed objects thru extractor callbacks
            for (const auto &result : parsed_buffer.resulting_nodes)
            {
                extractor_callbacks->ProcessNode(result.first, result.second);
            }
            number_of_ways += parsed_buffer.resulting_ways.size();
            for (const auto &result : parsed_buffer.resulting_ways)
            {
                extractor_callbacks->ProcessWay(result.first, result.second);
            }

            number_of_restrictions += parsed_buffer.resulting_restrictions.size();
            for (const auto &result : parsed_buffer.resulting_restrictions)
            {
                extractor_callbacks->ProcessRestriction(result);
            }

            number_of_maneuver_overrides = parsed_buffer.resulting_maneuver_overrides.size();
            for (const auto &result : parsed_buffer.resulting_maneuver_overrides)
            {
                extractor_callbacks->ProcessManeuverOverride(result);
            }

        });

    tbb::filter_t<SharedBuffer, std::shared_ptr<ExtractionRelationContainer>> buffer_relation_cache(
        tbb::filter::parallel, [&](const SharedBuffer buffer) {
            if (!buffer)
                return std::shared_ptr<ExtractionRelationContainer>{};

            auto relations = std::make_shared<ExtractionRelationContainer>();
            for (auto entity = buffer->cbegin(), end = buffer->cend(); entity != end; ++entity)
            {
                if (entity->type() != osmium::item_type::relation)
                    continue;

                const auto &rel = static_cast<const osmium::Relation &>(*entity);

                const char *rel_type = rel.get_value_by_key("type");
                if (!rel_type ||
                    !std::binary_search(
                        relation_types.begin(), relation_types.end(), std::string(rel_type)))
                    continue;

                ExtractionRelation extracted_rel({rel.id(), osmium::item_type::relation});
                for (auto const &t : rel.tags())
                    extracted_rel.attributes.emplace_back(std::make_pair(t.key(), t.value()));

                for (auto const &m : rel.members())
                {
                    ExtractionRelation::OsmIDTyped const mid(m.ref(), m.type());
                    extracted_rel.AddMember(mid, m.role());
                    relations->AddRelationMember(extracted_rel.id, mid);
                }

                relations->AddRelation(std::move(extracted_rel));
            };
            return relations;
        });

    unsigned number_of_relations = 0;
    tbb::filter_t<std::shared_ptr<ExtractionRelationContainer>, void> buffer_storage_relation(
        tbb::filter::serial_in_order,
        [&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations) {

            number_of_relations += parsed_relations->GetRelationsNum();
            relations.Merge(std::move(*parsed_relations));
        });

    // Parse OSM elements with parallel transformer
    // Number of pipeline tokens that yielded the best speedup was about 1.5 * num_cores
    const auto num_threads = tbb::task_scheduler_init::default_num_threads() * 1.5;
    const auto read_meta =
        config.use_metadata ? osmium::io::read_meta::yes : osmium::io::read_meta::no;

    { // Relations reading pipeline
        util::Log() << "Parse relations ...";
        osmium::io::Reader reader(input_file, pool, osmium::osm_entity_bits::relation, read_meta);
        tbb::parallel_pipeline(
            num_threads, buffer_reader(reader) & buffer_relation_cache & buffer_storage_relation);
    }

    { // Nodes and ways reading pipeline
        util::Log() << "Parse ways and nodes ...";
        osmium::io::Reader reader(input_file,
                                  pool,
                                  osmium::osm_entity_bits::node | osmium::osm_entity_bits::way |
                                      osmium::osm_entity_bits::relation,
                                  read_meta);

        const auto pipeline =
            scripting_environment.HasLocationDependentData() && config.use_locations_cache
                ? buffer_reader(reader) & location_cacher & buffer_transformer & buffer_storage
                : buffer_reader(reader) & buffer_transformer & buffer_storage;
        tbb::parallel_pipeline(num_threads, pipeline);
    }

    TIMER_STOP(parsing);
    util::Log() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds";

    util::Log() << "Raw input contains " << number_of_nodes << " nodes, " << number_of_ways
                << " ways, and " << number_of_relations << " relations, " << number_of_restrictions
                << " restrictions";

    extractor_callbacks.reset();

    if (extraction_containers.all_edges_list.empty())
    {
        throw util::exception(std::string("There are no edges remaining after parsing.") +
                              SOURCE_REF);
    }

    extraction_containers.PrepareData(scripting_environment,
                                      config.GetPath(".osrm").string(),
                                      config.GetPath(".osrm.names").string());

    auto profile_properties = scripting_environment.GetProfileProperties();
    SetClassNames(scripting_environment.GetClassNames(), classes_map, profile_properties);
    auto excludable_classes = scripting_environment.GetExcludableClasses();
    SetExcludableClasses(classes_map, excludable_classes, profile_properties);
    files::writeProfileProperties(config.GetPath(".osrm.properties").string(), profile_properties);

    TIMER_STOP(extracting);
    util::Log() << "extraction finished after " << TIMER_SEC(extracting) << "s";

    return std::make_tuple(std::move(turn_lane_map),
                           std::move(extraction_containers.unconditional_turn_restrictions),
                           std::move(extraction_containers.conditional_turn_restrictions),
                           std::move(extraction_containers.internal_maneuver_overrides));
}

void Extractor::FindComponents(unsigned number_of_edge_based_nodes,
                               const util::DeallocatingVector<EdgeBasedEdge> &input_edge_list,
                               const std::vector<EdgeBasedNodeSegment> &input_node_segments,
                               EdgeBasedNodeDataContainer &nodes_container) const
{
    using InputEdge = util::static_graph_details::SortableEdgeWithData<void>;
    using UncontractedGraph = util::StaticGraph<void>;
    std::vector<InputEdge> edges;
    edges.reserve(input_edge_list.size() * 2);

    for (const auto &edge : input_edge_list)
    {
        BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(edge.data.weight, 1)) > 0,
                         "edge distance < 1");
        BOOST_ASSERT(edge.source < number_of_edge_based_nodes);
        BOOST_ASSERT(edge.target < number_of_edge_based_nodes);
        if (edge.data.forward)
        {
            edges.push_back({edge.source, edge.target});
        }

        if (edge.data.backward)
        {
            edges.push_back({edge.target, edge.source});
        }
    }

    // Connect forward and backward nodes of each edge to enforce
    // forward and backward edge-based nodes be in one strongly-connected component
    for (const auto &segment : input_node_segments)
    {
        if (segment.reverse_segment_id.enabled)
        {
            BOOST_ASSERT(segment.forward_segment_id.id < number_of_edge_based_nodes);
            BOOST_ASSERT(segment.reverse_segment_id.id < number_of_edge_based_nodes);
            edges.push_back({segment.forward_segment_id.id, segment.reverse_segment_id.id});
            edges.push_back({segment.reverse_segment_id.id, segment.forward_segment_id.id});
        }
    }

    tbb::parallel_sort(edges.begin(), edges.end());
    edges.erase(std::unique(edges.begin(), edges.end()), edges.end());

    auto uncontracted_graph = UncontractedGraph(number_of_edge_based_nodes, edges);

    TarjanSCC<UncontractedGraph> component_search(uncontracted_graph);
    component_search.Run();

    for (NodeID node_id = 0; node_id < number_of_edge_based_nodes; ++node_id)
    {
        const auto forward_component = component_search.GetComponentID(node_id);
        const auto component_size = component_search.GetComponentSize(forward_component);
        const auto is_tiny = component_size < config.small_component_size;
        BOOST_ASSERT(node_id < nodes_container.NumberOfNodes());
        nodes_container.nodes[node_id].component_id = {1 + forward_component, is_tiny};
    }
}

/**
 \brief Building an edge-expanded graph from node-based input and turn restrictions
*/

EdgeID Extractor::BuildEdgeExpandedGraph(
    // input data
    const util::NodeBasedDynamicGraph &node_based_graph,
    const std::vector<util::Coordinate> &coordinates,
    const CompressedEdgeContainer &compressed_edge_container,
    const std::unordered_set<NodeID> &barrier_nodes,
    const std::unordered_set<NodeID> &traffic_signals,
    const std::vector<TurnRestriction> &turn_restrictions,
    const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
    const std::unordered_set<EdgeID> &segregated_edges,
    const util::NameTable &name_table,
    const std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
    const LaneDescriptionMap &turn_lane_map,
    // for calculating turn penalties
    ScriptingEnvironment &scripting_environment,
    // output data
    EdgeBasedNodeDataContainer &edge_based_nodes_container,
    std::vector<EdgeBasedNodeSegment> &edge_based_node_segments,
    std::vector<bool> &node_is_startpoint,
    std::vector<EdgeWeight> &edge_based_node_weights,
    util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
    std::uint32_t &connectivity_checksum)
{
    EdgeBasedGraphFactory edge_based_graph_factory(node_based_graph,
                                                   edge_based_nodes_container,
                                                   compressed_edge_container,
                                                   barrier_nodes,
                                                   traffic_signals,
                                                   coordinates,
                                                   name_table,
                                                   segregated_edges,
                                                   turn_lane_map);

    const auto create_edge_based_edges = [&]() {
        // scoped to relase intermediate datastructures right after the call
        std::vector<TurnRestriction> node_restrictions;
        for (auto const &t : turn_restrictions)
            if (t.Type() == RestrictionType::NODE_RESTRICTION)
                node_restrictions.push_back(t);

        std::vector<ConditionalTurnRestriction> conditional_node_restrictions;
        for (auto const &t : conditional_turn_restrictions)
            if (t.Type() == RestrictionType::NODE_RESTRICTION)
                conditional_node_restrictions.push_back(t);

        RestrictionMap via_node_restriction_map(node_restrictions, IndexNodeByFromAndVia());
        WayRestrictionMap via_way_restriction_map(conditional_turn_restrictions);
        ConditionalRestrictionMap conditional_node_restriction_map(conditional_node_restrictions,
                                                                   IndexNodeByFromAndVia());
        edge_based_graph_factory.Run(scripting_environment,
                                     config.GetPath(".osrm.turn_weight_penalties").string(),
                                     config.GetPath(".osrm.turn_duration_penalties").string(),
                                     config.GetPath(".osrm.turn_penalties_index").string(),
                                     config.GetPath(".osrm.cnbg_to_ebg").string(),
                                     config.GetPath(".osrm.restrictions").string(),
                                     config.GetPath(".osrm.maneuver_overrides").string(),
                                     via_node_restriction_map,
                                     conditional_node_restriction_map,
                                     via_way_restriction_map,
                                     maneuver_overrides);
        return edge_based_graph_factory.GetNumberOfEdgeBasedNodes();
    };

    const auto number_of_edge_based_nodes = create_edge_based_edges();

    edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
    edge_based_graph_factory.GetEdgeBasedNodeSegments(edge_based_node_segments);
    edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);
    edge_based_graph_factory.GetEdgeBasedNodeWeights(edge_based_node_weights);
    connectivity_checksum = edge_based_graph_factory.GetConnectivityChecksum();

    return number_of_edge_based_nodes;
}

/**
    \brief Building rtree-based nearest-neighbor data structure

    Saves tree into '.ramIndex' and leaves into '.fileIndex'.
 */
void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_segments,
                           std::vector<bool> node_is_startpoint,
                           const std::vector<util::Coordinate> &coordinates)
{
    util::Log() << "Constructing r-tree of " << edge_based_node_segments.size()
                << " segments build on-top of " << coordinates.size() << " coordinates";

    BOOST_ASSERT(node_is_startpoint.size() == edge_based_node_segments.size());

    // Filter node based edges based on startpoint
    auto out_iter = edge_based_node_segments.begin();
    auto in_iter = edge_based_node_segments.begin();
    for (auto index : util::irange<std::size_t>(0UL, node_is_startpoint.size()))
    {
        BOOST_ASSERT(in_iter != edge_based_node_segments.end());
        if (node_is_startpoint[index])
        {
            *out_iter = *in_iter;
            out_iter++;
        }
        in_iter++;
    }
    auto new_size = out_iter - edge_based_node_segments.begin();
    if (new_size == 0)
    {
        throw util::exception("There are no snappable edges left after processing.  Are you "
                              "setting travel modes correctly in the profile?  Cannot continue." +
                              SOURCE_REF);
    }
    edge_based_node_segments.resize(new_size);

    TIMER_START(construction);
    util::StaticRTree<EdgeBasedNodeSegment> rtree(edge_based_node_segments,
                                                  config.GetPath(".osrm.ramIndex").string(),
                                                  config.GetPath(".osrm.fileIndex").string(),
                                                  coordinates);

    TIMER_STOP(construction);
    util::Log() << "finished r-tree construction in " << TIMER_SEC(construction) << " seconds";
}

void Extractor::WriteCompressedNodeBasedGraph(const std::string &path,
                                              const util::NodeBasedDynamicGraph &graph,
                                              const std::vector<util::Coordinate> &coordinates)
{
    const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;

    storage::io::FileWriter writer{path, fingerprint};

    // Writes:  | Fingerprint | #e | #n | edges | coordinates |
    // - uint64: number of edges (from, to) pairs
    // - uint64: number of nodes and therefore also coordinates
    // - (uint32_t, uint32_t): num_edges * edges
    // - (int32_t, int32_t: num_nodes * coordinates (lon, lat)

    const auto num_edges = graph.GetNumberOfEdges();
    const auto num_nodes = graph.GetNumberOfNodes();

    BOOST_ASSERT_MSG(num_nodes == coordinates.size(), "graph and embedding out of sync");

    writer.WriteElementCount64(num_edges);
    writer.WriteElementCount64(num_nodes);

    // For all nodes iterate over its edges and dump (from, to) pairs
    for (const NodeID from_node : util::irange(0u, num_nodes))
    {
        for (const EdgeID edge : graph.GetAdjacentEdgeRange(from_node))
        {
            const auto to_node = graph.GetTarget(edge);

            writer.WriteOne(from_node);
            writer.WriteOne(to_node);
        }
    }

    // FIXME this is unneccesary: We have this data
    for (const auto &qnode : coordinates)
    {
        writer.WriteOne(qnode.lon);
        writer.WriteOne(qnode.lat);
    }
}

template <typename Map> auto convertIDMapToVector(const Map &map)
{
    std::vector<typename Map::key_type> result(map.size());
    for (const auto &pair : map)
    {
        BOOST_ASSERT(pair.second < map.size());
        result[pair.second] = pair.first;
    }
    return result;
}

void Extractor::ProcessGuidanceTurns(
    const util::NodeBasedDynamicGraph &node_based_graph,
    const extractor::EdgeBasedNodeDataContainer &edge_based_node_container,
    const std::vector<util::Coordinate> &node_coordinates,
    const CompressedEdgeContainer &compressed_edge_container,
    const std::unordered_set<NodeID> &barrier_nodes,
    const std::vector<TurnRestriction> &turn_restrictions,
    const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
    const util::NameTable &name_table,
    LaneDescriptionMap lane_description_map,
    ScriptingEnvironment &scripting_environment)
{
    // Output data
    osrm::guidance::TurnDataExternalContainer turn_data_container;
    util::guidance::LaneDataIdMap lane_data_map;
    osrm::guidance::BearingClassesVector bearing_class_by_node_based_node;
    osrm::guidance::BearingClassesMap bearing_class_hash;
    osrm::guidance::EntryClassesMap entry_class_hash;
    std::uint32_t connectivity_checksum = 0;

    TIMER_START(turn_annotations);

    {
        SuffixTable street_name_suffix_table(scripting_environment);
        const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map);

        std::vector<TurnRestriction> node_restrictions;
        for (auto const &t : turn_restrictions)
            if (t.Type() == RestrictionType::NODE_RESTRICTION)
                node_restrictions.push_back(t);

        RestrictionMap node_restriction_map(node_restrictions, IndexNodeByFromAndVia());
        WayRestrictionMap way_restriction_map(conditional_turn_restrictions);

        osrm::guidance::annotateTurns(node_based_graph,
                                      edge_based_node_container,
                                      node_coordinates,
                                      compressed_edge_container,
                                      barrier_nodes,
                                      node_restriction_map,
                                      way_restriction_map,
                                      name_table,
                                      street_name_suffix_table,
                                      turn_lanes_data,
                                      lane_description_map,
                                      lane_data_map,
                                      turn_data_container,
                                      bearing_class_by_node_based_node,
                                      bearing_class_hash,
                                      entry_class_hash,
                                      connectivity_checksum);
    }

    TIMER_STOP(turn_annotations);
    util::Log() << "Guidance turn annotations took " << TIMER_SEC(turn_annotations) << "s";

    util::Log() << "Writing Intersection Classification Data";
    TIMER_START(write_intersections);
    files::writeIntersections(
        config.GetPath(".osrm.icd").string(),
        IntersectionBearingsContainer{bearing_class_by_node_based_node,
                                      convertIDMapToVector(bearing_class_hash.data)},
        convertIDMapToVector(entry_class_hash.data));
    TIMER_STOP(write_intersections);
    util::Log() << "ok, after " << TIMER_SEC(write_intersections) << "s";

    util::Log() << "Writing Turns and Lane Data...";
    TIMER_START(write_guidance_data);
    storage::io::FileWriter writer(config.GetPath(".osrm.tld").string(),
                                   storage::io::FileWriter::GenerateFingerprint);
    storage::serialization::write(writer, convertIDMapToVector(lane_data_map.data));

    { // Turn lanes handler modifies lane_description_map, so another transformation is needed
        std::vector<std::uint32_t> turn_lane_offsets;
        std::vector<TurnLaneType::Mask> turn_lane_masks;
        std::tie(turn_lane_offsets, turn_lane_masks) =
            transformTurnLaneMapIntoArrays(lane_description_map);
        files::writeTurnLaneDescriptions(
            config.GetPath(".osrm.tls"), turn_lane_offsets, turn_lane_masks);
    }

    osrm::guidance::files::writeTurnData(
        config.GetPath(".osrm.edges").string(), turn_data_container, connectivity_checksum);
    TIMER_STOP(write_guidance_data);
    util::Log() << "ok, after " << TIMER_SEC(write_guidance_data) << "s";
}

} // namespace extractor
} // namespace osrm

ext: cpp

max_stars_repo_name: AugustoQueiroz/pedalavel-backend

max_issues_repo_name: AugustoQueiroz/pedalavel-backend

max_forks_repo_name: AugustoQueiroz/pedalavel-backend


text:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <boost/log/trivial.hpp>
#include "lib/comma_separated_values.h"

/**
 * Split CSV data into a multi-dimensional array
 *
 * @note Rows must currently be separated by "\r\n".
 * @note 6 columns expected: date, open, high, low, close, volume.
 *
 * @return stock** and sets rows
 */
struct stock *comma_separated_values::parse(const char *block, long *rows)
{
	char *data, *line, *col, *ptr, *ptr_orig;
	struct stock *ret;
	int cols;
	long x;

	ptr_orig = ptr = (char *)malloc(strlen(block) + 1);
	strcpy(ptr, block);

	cols = *rows = 0;
	col = line = strsep(&ptr, "\r\n");
	while (*col != '\0')
		cols += (*col++ == ',');

	if (cols < 5)
	{
		BOOST_LOG_TRIVIAL(error) << "Required: 5 columns. Found: " << cols;
		fprintf(stderr, "Error: Not enough columns!\n");
		free(ptr_orig);
		return nullptr;
	}

	do
	{
		if ((isdigit(*line)) && (strchr(line, ',')))
			(*rows)++;
	} while ((line = strsep(&ptr, "\r\n")));
	free(ptr_orig);

	BOOST_LOG_TRIVIAL(trace) << "CSV rows found: " << *rows;

	data = (char *)malloc(strlen(block) + 1);
	strcpy(data, block);

	ret = (struct stock *)malloc((*rows) * sizeof(struct stock));
	for (x = 0; x < *rows; x++)
	{
		ret[x].date = nullptr;
		ret[x].open = ret[x].high = ret[x].low = ret[x].close = 0;
		ret[x].volume = 0;
	}

	x = 0;
	while ((line = strsep(&data, "\r\n")))
	{
		if ((!isdigit(*line)) || (!strchr(line, ',')))
			continue;

		ptr = (char *)malloc(strlen(line) + 1);
		strcpy(ptr, line);

		// Hack: We are going to use this ptr as our "date" column.
		ret[x].date = strsep(&ptr, ",");
		ret[x].open = atof(strsep(&ptr, ","));
		ret[x].high = atof(strsep(&ptr, ","));
		ret[x].low = atof(strsep(&ptr, ","));
		ret[x].close = atof(strsep(&ptr, ","));
		ret[x].volume = strtol(strsep(&ptr, ","), NULL, 10);

		x++;
	}

	free(data);
	return ret;
}

max_stars_repo_name: EpicVoyage/rsiscan

max_issues_repo_name: EpicVoyage/rsiscan

max_forks_repo_name: EpicVoyage/rsiscan


text:
// (C) Copyright Renaud Detry   2007-2011.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//#define TRSL_USE_BSD_BETTER_RANDOM_GENERATOR
//#define TRSL_USE_SYSTEMATIC_INTUITIVE_ALGORITHM

#include <trsl/sort_iterator.hpp>
#include <trsl/is_picked_systematic.hpp>
#include <trsl/random_permutation_iterator.hpp>
#include <trsl/ppfilter_iterator.hpp>

#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <vector>
#include <iostream>
#include <numeric> // accumulate

// In this example, population elements are floats, and an element's
// weight is the element itself. The weight accessor is:
struct wac
{
  double operator()(float const& e) const
    {
      return e;
    }
};

int main()
{

  //-----------------------//
  // Generate a population //
  //-----------------------//

#define C_ARRAY_ITERATOR_SAMPLING
//#define STD_VECTOR_ITERATOR_SAMPLING

#if defined(C_ARRAY_ITERATOR_SAMPLING)
  float population[] = { 0, 1, 4, 3, 5, 8, 2 };
  const size_t POPULATION_SIZE = sizeof(population)/sizeof(float);
  const size_t SAMPLE_SIZE = 3;

  typedef float* population_iterator;
  population_iterator populationIteratorBegin(population),
    populationIteratorEnd(population + POPULATION_SIZE);
#elif defined(STD_VECTOR_ITERATOR_SAMPLING)
  boost::mt19937 rng;
  boost::uniform_real<float> dist(0, 100);
  boost::variate_generator<
    boost::mt19937&,
    boost::uniform_real<float>
    > uni(rng, dist);

  const size_t POPULATION_SIZE = 100;
  std::vector<float> population(POPULATION_SIZE);
  std::generate(population.begin(), population.end(), uni);
  const size_t SAMPLE_SIZE = 10;

  typedef std::vector<float>::iterator population_iterator;
  population_iterator populationIteratorBegin = population.begin(),
    populationIteratorEnd = population.end();
#else
#  error Please choose an example.
#endif

  std::cout << "Population ("
            << std::distance(populationIteratorBegin,
                             populationIteratorEnd)
            << " elements):" << std::endl;
  std::copy(populationIteratorBegin,
            populationIteratorEnd,
            std::ostream_iterator<float>(std::cout, " "));
  std::cout << std::endl;

  {
    //----------------------------//
    // Sample from the population //
    //----------------------------//

    typedef trsl::is_picked_systematic<
      float,
      double,
      wac
      > is_picked;

    typedef trsl::persistent_filter_iterator
      <is_picked, population_iterator> sample_iterator;

    is_picked predicate(SAMPLE_SIZE,
                        std::accumulate(populationIteratorBegin,
                                        populationIteratorEnd,
                                        float(0)),
                        wac());

    sample_iterator sampleIteratorBegin(predicate,
                                        populationIteratorBegin,
                                        populationIteratorEnd);
    sample_iterator sampleIteratorEnd(predicate,
                                      populationIteratorEnd,
                                      populationIteratorEnd);

    std::cout << "Sample of " << SAMPLE_SIZE << " elements:" << std::endl;
    std::copy(sampleIteratorBegin,
              sampleIteratorEnd,
              std::ostream_iterator<float>(std::cout, " "));
    std::cout << std::endl;
  }

  {
    //-------------------------------------------------------------------//
    // Sample from the population (robust to patterns in the population) //
    //-------------------------------------------------------------------//

    typedef trsl::is_picked_systematic<
    float,
    double,
    wac
    > is_picked;

    typedef trsl::ppfilter_iterator
    <is_picked, population_iterator> sample_iterator;

    is_picked predicate(SAMPLE_SIZE,
                        std::accumulate(populationIteratorBegin,
                                        populationIteratorEnd,
                                        float(0)),
                        wac());

    sample_iterator sampleIteratorBegin(predicate,
                                        populationIteratorBegin,
                                        populationIteratorEnd);
    sample_iterator sampleIteratorEnd = sampleIteratorBegin.end();

    std::cout << "Probabilistic sample of " << SAMPLE_SIZE << " elements:" << std::endl;
    std::copy(sampleIteratorBegin,
              sampleIteratorEnd,
              std::ostream_iterator<float>(std::cout, " "));
    std::cout << std::endl;
  }

  {
    //-------------------------------------//
    // Get a permutation of the population //
    //-------------------------------------//

    typedef trsl::reorder_iterator
      <population_iterator> permutation_iterator;

    {
      permutation_iterator pi =
        trsl::random_permutation_iterator(populationIteratorBegin,
                                          populationIteratorEnd);

      std::cout << "Permutation:" << std::endl;
      std::copy(pi,
                pi.end(),
                std::ostream_iterator<float>(std::cout, " "));
      std::cout << std::endl;
    }
    {
      permutation_iterator pi =
        trsl::random_permutation_iterator(populationIteratorBegin,
                                          populationIteratorEnd,
                                          SAMPLE_SIZE);

      std::cout << "Permutation of a subset of " << SAMPLE_SIZE
                << " elements:" << std::endl;
      std::copy(pi,
                pi.end(),
                std::ostream_iterator<float>(std::cout, " "));
      std::cout << std::endl;
    }
  }

  {
    //---------------------//
    // Sort the population //
    //---------------------//

    typedef trsl::reorder_iterator
      <population_iterator> permutation_iterator;

    {
      permutation_iterator pi =
        trsl::sort_iterator(populationIteratorBegin,
                            populationIteratorEnd);

      std::cout << "Sorted population:" << std::endl;
      std::copy(pi,
                pi.end(),
                std::ostream_iterator<float>(std::cout, " "));
      std::cout << std::endl;
    }
    {
      permutation_iterator pi =
        trsl::sort_iterator(populationIteratorBegin,
                            populationIteratorEnd,
                            std::less<float>(), SAMPLE_SIZE);

      std::cout << "Sorted " << SAMPLE_SIZE
                << " smallest elements:" << std::endl;
      std::copy(pi,
                pi.end(),
                std::ostream_iterator<float>(std::cout, " "));
      std::cout << std::endl;
    }
  }

  return 0;
}

max_stars_repo_name: renauddetry/trsl

max_issues_repo_name: renauddetry/trsl

max_forks_repo_name: renauddetry/trsl


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/cppalliance/json
//

#ifndef BOOST_JSON_DETAIL_VALUE_HPP
#define BOOST_JSON_DETAIL_VALUE_HPP

#include <boost/json/kind.hpp>
#include <boost/json/storage_ptr.hpp>
#include <new>
#include <utility>

BOOST_JSON_NS_BEGIN
namespace detail {

struct value_access
{
    template<class Value, class... Args>
    static
    Value&
    construct_value(Value* p, Args&&... args)
    {
        return *reinterpret_cast<
            Value*>(::new(p) Value(
            std::forward<Args>(args)...));
    }

    template<class KeyValuePair, class... Args>
    static
    KeyValuePair&
    construct_key_value_pair(
        KeyValuePair* p, Args&&... args)
    {
        return *reinterpret_cast<
            KeyValuePair*>(::new(p)
                KeyValuePair(
                    std::forward<Args>(args)...));
    }

    template<class Value>
    static
    char const*
    release_key(
        Value& jv,
        std::size_t& len) noexcept
    {
        BOOST_ASSERT(jv.is_string());
        return jv.str_.impl_.release_key(len);
    }

    using index_t = std::uint32_t;

    template<class KeyValuePair>
    static
    index_t&
    next(KeyValuePair& e) noexcept
    {
        return e.next_;
    }

    template<class KeyValuePair>
    static
    index_t const&
    next(KeyValuePair const& e) noexcept
    {
        return e.next_;
    }
};

} // detail
BOOST_JSON_NS_END

#endif

ext: hpp

max_stars_repo_name: djarek/json

max_issues_repo_name: djarek/json

max_forks_repo_name: djarek/json


text:
#include "url.hpp"

#include <boost/algorithm/string/split.hpp>
#include <deque>

namespace Rest
{
//#######################################################################################################
    std::vector <std::unique_ptr <PathPart>> Url::parsePath(bool disableIds) const
    {
        std::deque <std::string> splitted;
        boost::algorithm::split(splitted, path, [](char c) {return c == '/';});
        splitted.pop_front();

        std::vector <std::unique_ptr <PathPart>> splitPath;
        for (auto const& i : splitted) {
            if (!disableIds && i.front() == ':')
                splitPath.emplace_back(new PathParameter(i.substr(1, i.length() - 1)));
            else
                splitPath.emplace_back(new PathString(i));
        }
        return splitPath;
    }
//#######################################################################################################
    PathParameter::PathParameter(std::string id)
        : value_()
        , id_(id)
    {

    }
//-------------------------------------------------------------------------------------------------------
    std::string PathParameter::getValue() const
    {
        return value_;
    }
//-------------------------------------------------------------------------------------------------------
    std::string PathParameter::getId() const
    {
        return id_;
    }
//-------------------------------------------------------------------------------------------------------
    void PathParameter::setValue(std::string const& value)
    {
        value_ = value;
    }
//-------------------------------------------------------------------------------------------------------
    PathType PathParameter::getType() const
    {
        return PathType::PARAMETER;
    }
//#######################################################################################################
    PathString::PathString(std::string value)
        : value_(value)
    {

    }
//-------------------------------------------------------------------------------------------------------
    std::string PathString::getValue() const
    {
        return value_;
    }
//-------------------------------------------------------------------------------------------------------
    PathType PathString::getType() const
    {
        return PathType::STRING;
    }
//#######################################################################################################
}


text:
#define BOOST_TEST_MODULE lue raster
#include <boost/test/unit_test.hpp>
#include "lue/test.hpp"

BOOST_FIXTURE_TEST_CASE(create, lue::data_model::test::DatasetFixture)
{
    std::string const phenomenon_name = "areas";
    std::string const property_set_name = "areas";

    lue::data_model::Count const nr_areas = 10;

    // Space domain
    lue::data_model::SpaceConfiguration space_configuration{
        lue::data_model::Mobility::stationary,
            lue::data_model::SpaceDomainItemType::box
        };
    lue::hdf5::Datatype const coordinate_datatype{
        lue::hdf5::NativeDatatypeTraits<int>::type_id()};
    std::size_t const rank = 2;
    std::vector<int> boxes(40 /* -> nr_areas * rank * 2 */);
    lue::data_model::test::generate_random_values(boxes, 0, 1000);

    // IDs
    std::vector<lue::data_model::ID> ids(nr_areas);
    lue::data_model::test::generate_random_ids(ids);

    // Discretization property
    std::string const discretization_property_name = "discretization";
    lue::hdf5::Datatype const shape_datatype{
        lue::hdf5::NativeDatatypeTraits<
            lue::hdf5::Shape::value_type>::type_id()};
    std::vector<lue::hdf5::Shape::value_type> shapes(nr_areas * rank);
    lue::data_model::test::generate_random_values(shapes, 10, 20);

    // Elevation property
    std::string const elevation_property_name = "elevation";
    using ElevationValueType = double;
    lue::hdf5::Datatype const elevation_datatype{
        lue::hdf5::NativeDatatypeTraits<ElevationValueType>::type_id()};
    std::vector<std::vector<ElevationValueType>> values(nr_areas);
    for(std::size_t o = 0, s = 0; o < nr_areas; ++o, s += rank) {
        values[o].resize(shapes[s] * shapes[s + 1]);
    }
    lue::data_model::test::generate_random_values(values, 5.0, 15.0);

    // Create and write
    {
        // Phenomenon
        auto& areas = dataset().add_phenomenon(phenomenon_name);

        // Property set
        auto& area_boxes = areas.property_sets().add(
                property_set_name,
                space_configuration,
                coordinate_datatype,
                rank
            );

        // IDs
        areas.object_id().expand(nr_areas);
        areas.object_id().write(ids.data());

        // Time domain
        {
            // N/A
        }

        // Space domain
        {
            auto& space_domain = area_boxes.space_domain();
            auto value = space_domain.value<lue::data_model::StationarySpaceBox>();
            value.expand(nr_areas);
            value.write(boxes.data());
        }

        // Discretization property
        auto& discretization_property = area_boxes.properties().add(
            discretization_property_name, shape_datatype,
            lue::hdf5::Shape{2});  // nr rows, nr_cols
        {
            auto& value = discretization_property.value();
            value.expand(nr_areas);
            value.write(shapes.data());
        }

        // Elevation property
        auto& elevation_property = area_boxes.properties().add(
            elevation_property_name, elevation_datatype, rank);
        {
            auto& value = elevation_property.value();
            value.expand(nr_areas, ids.data(), shapes.data());

            for(std::size_t o = 0; o < nr_areas; ++o) {
                value[ids[o]].write(values[o].data());
            }
        }

        // Link from elevation property to discretization property
        elevation_property.set_space_discretization(
            lue::data_model::SpaceDiscretization::regular_grid,
            discretization_property);
    }

    lue::data_model::assert_is_valid(pathname());

    // Open and read
    {
        // Phenomenon
        auto& areas = dataset().phenomena()[phenomenon_name];

        //Property set
        auto& area_boxes = areas.property_sets()[property_set_name];

        // Time domain
        {
            BOOST_CHECK(!area_boxes.has_time_domain());
        }

        // Space domain
        {
            BOOST_REQUIRE(area_boxes.has_space_domain());

            auto& space_domain = area_boxes.space_domain();
            BOOST_REQUIRE_EQUAL(
                space_domain.configuration(), space_configuration);

            auto value = space_domain.value<lue::data_model::StationarySpaceBox>();

            BOOST_REQUIRE_EQUAL(value.nr_arrays(), nr_areas);
            BOOST_REQUIRE_EQUAL(value.memory_datatype(), coordinate_datatype);
            BOOST_REQUIRE_EQUAL(
                value.array_shape(), lue::hdf5::Shape{rank * 2});

            std::vector<int> boxes_read(nr_areas * rank * 2);
            value.read(boxes_read.data());

            BOOST_CHECK_EQUAL_COLLECTIONS(
                    boxes_read.begin(), boxes_read.end(),
                    boxes.begin(), boxes.end());
        }

        {
            // Elevation property
            BOOST_REQUIRE(
                area_boxes.properties().contains(elevation_property_name));
            BOOST_REQUIRE_EQUAL(
                area_boxes.properties().shape_per_object(
                    elevation_property_name),
                lue::data_model::ShapePerObject::different);
            BOOST_REQUIRE_EQUAL(
                area_boxes.properties().value_variability(
                    elevation_property_name),
                lue::data_model::ValueVariability::constant);

            auto& properties =
                area_boxes.properties().collection<lue::data_model::different_shape::Properties>();
            auto& elevation_property = properties[elevation_property_name];
            auto& value = elevation_property.value();

            BOOST_REQUIRE_EQUAL(value.nr_objects(), nr_areas);
            BOOST_REQUIRE_EQUAL(value.memory_datatype(), elevation_datatype);

            for(std::size_t o = 0; o < nr_areas; ++o) {
                auto array = value[ids[o]];

                lue::hdf5::Shape shape{shapes[o * rank], shapes[o * rank + 1]};
                BOOST_REQUIRE_EQUAL(array.shape(), shape);

                std::vector<ElevationValueType> values_read(
                    lue::hdf5::size_of_shape(array.shape()));

                array.read(values_read.data());

                BOOST_CHECK_EQUAL_COLLECTIONS(
                        values_read.begin(), values_read.end(),
                        values[o].begin(), values[o].end());
            }

            // Discretization property

            // Figure out whether property is discretized
            BOOST_REQUIRE(!elevation_property.time_is_discretized());
            BOOST_REQUIRE(elevation_property.space_is_discretized());

            // Figure out how the property is discretized
            auto discretization_type =
                elevation_property.space_discretization_type();
            BOOST_CHECK_EQUAL(
                discretization_type, lue::data_model::SpaceDiscretization::regular_grid);

            // Verify discretization parameters
            auto discretization_property =
                elevation_property.space_discretization_property();

            auto property_set{lue::data_model::property_set(discretization_property)};

            BOOST_CHECK(
                property_set.properties().contains(
                    discretization_property_name));

            BOOST_REQUIRE_EQUAL(
                property_set.properties().shape_per_object(
                    discretization_property_name),
                lue::data_model::ShapePerObject::same);
            BOOST_REQUIRE_EQUAL(
                property_set.properties().value_variability(
                    discretization_property_name),
                lue::data_model::ValueVariability::constant);

            // Discretization property value
            {
                auto& properties =
                    property_set.properties().collection<lue::data_model::same_shape::Properties>();
                auto& discretization_property =
                    properties[discretization_property_name];
                auto& value = discretization_property.value();

                BOOST_REQUIRE_EQUAL(value.nr_arrays(), nr_areas);
                BOOST_REQUIRE_EQUAL(value.memory_datatype(), shape_datatype);
                BOOST_REQUIRE_EQUAL(
                    value.array_shape(), lue::hdf5::Shape{rank});

                std::vector<lue::hdf5::Shape::value_type> shapes_read(
                    nr_areas * 2);
                value.read(shapes_read.data());
                BOOST_CHECK_EQUAL_COLLECTIONS(
                    shapes_read.begin(), shapes_read.end(),
                    shapes.begin(), shapes.end());
            }
        }
    }
}

max_stars_repo_name: computationalgeography/lue

max_issues_repo_name: pcraster/lue

max_forks_repo_name: computationalgeography/lue


text:
// Copyright (c) 2017 Amaury SÉCHET
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <protocol.h>

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(inv_tests)

static void CheckType(int type, int expected, bool IsTx, bool IsBlock) {
    CInv inv(type, uint256());
    BOOST_CHECK_EQUAL(inv.GetKind(), expected);
    BOOST_CHECK_EQUAL(inv.IsMsgTx(), IsTx);
    BOOST_CHECK_EQUAL(inv.IsGenBlkMsg(), IsBlock);
}

/* Validate various inv facilities. */
BOOST_AUTO_TEST_CASE(validate_kind) {
    CheckType(GetDataMsg::UNDEFINED, GetDataMsg::UNDEFINED, false, false);
    CheckType(GetDataMsg::MSG_TX, GetDataMsg::MSG_TX, true, false);
    CheckType(GetDataMsg::MSG_BLOCK, GetDataMsg::MSG_BLOCK, false, true);
    CheckType(GetDataMsg::MSG_FILTERED_BLOCK, GetDataMsg::MSG_FILTERED_BLOCK,
              false, true);
    CheckType(GetDataMsg::MSG_CMPCT_BLOCK, GetDataMsg::MSG_CMPCT_BLOCK, false,
              true);
    CheckType(GetDataMsg::MSG_AVA_PROOF, GetDataMsg::MSG_AVA_PROOF, false,
              false);
}

static void CheckCommand(int type, std::string expected) {
    CInv inv(type, uint256());
    BOOST_CHECK_EQUAL(inv.GetCommand(), expected);
}

/* Validate various inv facilities. */
BOOST_AUTO_TEST_CASE(validate_cmd) {
    CheckCommand(GetDataMsg::MSG_TX, "tx");
    CheckCommand(GetDataMsg::MSG_BLOCK, "block");
    CheckCommand(GetDataMsg::MSG_FILTERED_BLOCK, "merkleblock");
    CheckCommand(GetDataMsg::MSG_CMPCT_BLOCK, "cmpctblock");
    CheckCommand(GetDataMsg::MSG_AVA_PROOF, "avaproof");
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: syedrizwanmy/bitcoin-abc

max_issues_repo_name: EGYVOICE/bitcoin-abc-avalanche

max_forks_repo_name: EGYVOICE/bitcoin-abc-avalanche


text:
#define CATCH_CONFIG_MAIN
#define CATCH_CONFIG_COUNTER
#include "Catch.hpp"

#include <vector>
#include <functional>
#include <boost/asio.hpp>
#include "ModbusConsts.hpp"
#include "ModbusTypes.hpp"
#include "ModbusDecoder.hpp"
#include "ModbusEncoder.hpp"
#include "ModbusServerDevice.hpp"
#include "ModbusServer.hpp"

class ServerDevice : public modbus::tcp::ServerDevice {
public:
    ServerDevice(const modbus::tcp::UnitId& unitId) : modbus::tcp::ServerDevice(unitId) {}
};

TEST_CASE("server must respond to read coils req", "[server]") {
    ServerDevice dev(modbus::tcp::UnitId(0xab));

    boost::asio::io_service io;
    modbus::tcp::Server server(io, dev);
    bool serverDone = false;

    const boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 50000);
    server.start(ep, [&serverDone](){
        serverDone = true;
    });
    io.run_one();

    boost::asio::ip::tcp::socket client(io);
    client.connect(ep);
    io.run_one();

    std::vector<uint8_t> req;
    modbus::tcp::Encoder encoder(modbus::tcp::UnitId(0xab), modbus::tcp::TransactionId(0x02));
    encoder.encodeReadCoilsReq(modbus::tcp::Address(0x1020), modbus::tcp::NumBits(4), req);

    boost::asio::write(client, boost::asio::buffer(req));

    io.run_one();
    io.run_one();

    std::vector<uint8_t> rsp;
    rsp.resize(sizeof(modbus::tcp::ExceptionRsp));
    boost::asio::read(client, boost::asio::buffer(rsp));

    server.stop();
    io.run_one();
    io.run_one();
    io.run_one();
    io.run_one();
    io.run_one();
    io.run_one();
    io.run_one();
    io.run_one();

    REQUIRE(serverDone == true);
    REQUIRE(rsp == (std::vector<uint8_t>{0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0xab, 0x81, 0x01}));
}

max_stars_repo_name: gkarvounis/libmodbusc-

max_issues_repo_name: gkarvounis/libmodbusc-

max_forks_repo_name: gkarvounis/libmodbusc-


text:
#ifndef RESOURCEHANDLECACHE_H_
#define RESOURCEHANDLECACHE_H_

#include <unordered_map>
#include <utility>
#include <string>
#include <mutex>

#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/shared_lock_guard.hpp>

#include "ModelHandle.hpp"
#include "SkeletonHandle.hpp"
#include "AnimationHandle.hpp"

#include "graphics/MeshHandle.hpp"
#include "graphics/TextureHandle.hpp"
#include "graphics/TerrainHandle.hpp"
#include "graphics/SkyboxHandle.hpp"

#include "audio/SoundHandle.hpp"

#include "physics/CollisionShapeHandle.hpp"

#include "pathfinding/PolygonMeshHandle.hpp"
#include "pathfinding/NavigationMeshHandle.hpp"

#include "exceptions/Exception.hpp"

#include "Types.hpp"

namespace ice_engine
{

class ResourceHandleCache
{
public:
	void addCollisionShapeHandle(const std::string& name, const physics::CollisionShapeHandle& handle)
	{
		std::unique_lock<boost::shared_mutex> lock(collisionShapeHandleMutex_);

		if (collisionShapeHandleMap_.find(name) != collisionShapeHandleMap_.end())
		{
			throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
		}

		collisionShapeHandleMap_[name] = handle;
	}

	void removeCollisionShapeHandle(const std::string& name)
	{
		std::unique_lock<boost::shared_mutex> lock(collisionShapeHandleMutex_);

		auto it = collisionShapeHandleMap_.find(name);
		if (it != collisionShapeHandleMap_.end())
		{
			collisionShapeHandleMap_.erase(it);
		}
	}

	void removeAllCollisionShapeHandles()
	{
		std::unique_lock<boost::shared_mutex> lock(collisionShapeHandleMutex_);

		collisionShapeHandleMap_.clear();
	}

	physics::CollisionShapeHandle getCollisionShapeHandle(const std::string& name) const
	{
		boost::shared_lock_guard<boost::shared_mutex> lock(collisionShapeHandleMutex_);

        const auto it = collisionShapeHandleMap_.find(name);
		if (it != collisionShapeHandleMap_.end()) return it->second;

		return physics::CollisionShapeHandle();
	}

	void addModelHandle(const std::string& name, const ModelHandle& handle)
    {
        std::unique_lock<boost::shared_mutex> lock(modelHandleMutex_);

        if (modelHandleMap_.find(name) != modelHandleMap_.end())
        {
            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
        }

        modelHandleMap_[name] = handle;
    }

    void removeModelHandle(const std::string& name)
    {
        std::unique_lock<boost::shared_mutex> lock(modelHandleMutex_);

        auto it = modelHandleMap_.find(name);
        if (it != modelHandleMap_.end())
        {
            modelHandleMap_.erase(it);
        }
    }

    void removeAllModelHandles()
    {
        std::unique_lock<boost::shared_mutex> lock(modelHandleMutex_);

        modelHandleMap_.clear();
    }

    ModelHandle getModelHandle(const std::string& name) const
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(modelHandleMutex_);

        const auto it = modelHandleMap_.find(name);
        if (it != modelHandleMap_.end()) return it->second;

        return ModelHandle();
    }

	void addSkeletonHandle(const std::string& name, const SkeletonHandle& handle)
    {
        std::unique_lock<boost::shared_mutex> lock(skeletonHandleMutex_);

        if (skeletonHandleMap_.find(name) != skeletonHandleMap_.end())
        {
            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
        }

        skeletonHandleMap_[name] = handle;
    }

    void removeSkeletonHandle(const std::string& name)
    {
        std::unique_lock<boost::shared_mutex> lock(skeletonHandleMutex_);

        auto it = skeletonHandleMap_.find(name);
        if (it != skeletonHandleMap_.end())
        {
            skeletonHandleMap_.erase(it);
        }
    }

    void removeAllSkeletonHandles()
    {
        std::unique_lock<boost::shared_mutex> lock(skeletonHandleMutex_);

        skeletonHandleMap_.clear();
    }

    SkeletonHandle getSkeletonHandle(const std::string& name) const
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(skeletonHandleMutex_);

        const auto it = skeletonHandleMap_.find(name);
        if (it != skeletonHandleMap_.end()) return it->second;

        return SkeletonHandle();
    }

	void addAnimationHandle(const std::string& name, const AnimationHandle& handle)
    {
        std::unique_lock<boost::shared_mutex> lock(animationHandleMutex_);

        if (animationHandleMap_.find(name) != animationHandleMap_.end())
        {
            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
        }

        animationHandleMap_[name] = handle;
    }

    void removeAnimationHandle(const std::string& name)
    {
        std::unique_lock<boost::shared_mutex> lock(animationHandleMutex_);

        auto it = animationHandleMap_.find(name);
        if (it != animationHandleMap_.end())
        {
            animationHandleMap_.erase(it);
        }
    }

    void removeAllAnimationHandles()
    {
        std::unique_lock<boost::shared_mutex> lock(animationHandleMutex_);

        animationHandleMap_.clear();
    }

    AnimationHandle getAnimationHandle(const std::string& name) const
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(animationHandleMutex_);

        const auto it = animationHandleMap_.find(name);
        if (it != animationHandleMap_.end()) return it->second;

        return AnimationHandle();
    }

	void addMeshHandle(const std::string& name, const graphics::MeshHandle& handle)
    {
        std::unique_lock<boost::shared_mutex> lock(meshHandleMutex_);

        if (meshHandleMap_.find(name) != meshHandleMap_.end())
        {
            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
        }

        meshHandleMap_[name] = handle;
    }

    void removeMeshHandle(const std::string& name)
    {
        std::unique_lock<boost::shared_mutex> lock(meshHandleMutex_);

        auto it = meshHandleMap_.find(name);
        if (it != meshHandleMap_.end())
        {
            meshHandleMap_.erase(it);
        }
    }

    void removeAllMeshHandles()
    {
        std::unique_lock<boost::shared_mutex> lock(meshHandleMutex_);

        meshHandleMap_.clear();
    }

    graphics::MeshHandle getMeshHandle(const std::string& name) const
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(meshHandleMutex_);

        const auto it = meshHandleMap_.find(name);
        if (it != meshHandleMap_.end()) return it->second;

        return graphics::MeshHandle();
    }

	void addTextureHandle(const std::string& name, const graphics::TextureHandle& handle)
    {
        std::unique_lock<boost::shared_mutex> lock(textureHandleMutex_);

        if (textureHandleMap_.find(name) != textureHandleMap_.end())
        {
            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
        }

        textureHandleMap_[name] = handle;
    }

    void removeTextureHandle(const std::string& name)
    {
        std::unique_lock<boost::shared_mutex> lock(textureHandleMutex_);

        auto it = textureHandleMap_.find(name);
        if (it != textureHandleMap_.end())
        {
            textureHandleMap_.erase(it);
        }
    }

    void removeAllTextureHandles()
    {
        std::unique_lock<boost::shared_mutex> lock(textureHandleMutex_);

        textureHandleMap_.clear();
    }

    graphics::TextureHandle getTextureHandle(const std::string& name) const
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(textureHandleMutex_);

        const auto it = textureHandleMap_.find(name);
        if (it != textureHandleMap_.end()) return it->second;

        return graphics::TextureHandle();
    }

	void addTerrainHandle(const std::string& name, const graphics::TerrainHandle& handle)
    {
        std::unique_lock<boost::shared_mutex> lock(terrainHandleMutex_);

        if (terrainHandleMap_.find(name) != terrainHandleMap_.end())
        {
            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
        }

        terrainHandleMap_[name] = handle;
    }

    void removeTerrainHandle(const std::string& name)
    {
        std::unique_lock<boost::shared_mutex> lock(terrainHandleMutex_);

        auto it = terrainHandleMap_.find(name);
        if (it != terrainHandleMap_.end())
        {
            terrainHandleMap_.erase(it);
        }
    }

    void removeAllTerrainHandles()
    {
        std::unique_lock<boost::shared_mutex> lock(terrainHandleMutex_);

        terrainHandleMap_.clear();
    }

    graphics::TerrainHandle getTerrainHandle(const std::string& name) const
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(terrainHandleMutex_);

        const auto it = terrainHandleMap_.find(name);
        if (it != terrainHandleMap_.end()) return it->second;

        return graphics::TerrainHandle();
    }

	void addSkyboxHandle(const std::string& name, const graphics::SkyboxHandle& handle)
	{
		std::unique_lock<boost::shared_mutex> lock(skyboxHandleMutex_);

		if (skyboxHandleMap_.find(name) != skyboxHandleMap_.end())
		{
			throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
		}

		skyboxHandleMap_[name] = handle;
	}

	void removeSkyboxHandle(const std::string& name)
	{
		std::unique_lock<boost::shared_mutex> lock(skyboxHandleMutex_);

		auto it = skyboxHandleMap_.find(name);
		if (it != skyboxHandleMap_.end())
		{
			skyboxHandleMap_.erase(it);
		}
	}

	void removeAllSkyboxHandles()
	{
		std::unique_lock<boost::shared_mutex> lock(skyboxHandleMutex_);

		skyboxHandleMap_.clear();
	}

	graphics::SkyboxHandle getSkyboxHandle(const std::string& name) const
	{
		boost::shared_lock_guard<boost::shared_mutex> lock(skyboxHandleMutex_);

        const auto it = skyboxHandleMap_.find(name);
		if (it != skyboxHandleMap_.end()) return it->second;

		return graphics::SkyboxHandle();
	}

	void addSoundHandle(const std::string& name, const audio::SoundHandle& handle)
	{
		std::unique_lock<boost::shared_mutex> lock(soundHandleMutex_);

		if (soundHandleMap_.find(name) != soundHandleMap_.end())
		{
			throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
		}

		soundHandleMap_[name] = handle;
	}

	void removeSoundHandle(const std::string& name)
	{
		std::unique_lock<boost::shared_mutex> lock(soundHandleMutex_);

		auto it = soundHandleMap_.find(name);
		if (it != soundHandleMap_.end())
		{
			soundHandleMap_.erase(it);
		}
	}

	void removeAllSoundHandles()
	{
		std::unique_lock<boost::shared_mutex> lock(soundHandleMutex_);

		soundHandleMap_.clear();
	}

    audio::SoundHandle getSoundHandle(const std::string& name) const
	{
		boost::shared_lock_guard<boost::shared_mutex> lock(soundHandleMutex_);

		const auto it = soundHandleMap_.find(name);
		if (it != soundHandleMap_.end()) return it->second;

		return audio::SoundHandle();
	}

	void addPolygonMeshHandle(const std::string& name, const pathfinding::PolygonMeshHandle& handle)
	{
		std::unique_lock<boost::shared_mutex> lock(polygonMeshHandleMutex_);

		if (polygonMeshHandleMap_.find(name) != polygonMeshHandleMap_.end())
		{
			throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
		}

		polygonMeshHandleMap_[name] = handle;
	}

	void removePolygonMeshHandle(const std::string& name)
	{
		std::unique_lock<boost::shared_mutex> lock(polygonMeshHandleMutex_);

		auto it = polygonMeshHandleMap_.find(name);
		if (it != polygonMeshHandleMap_.end())
		{
			polygonMeshHandleMap_.erase(it);
		}
	}

	void removeAllPolygonMeshHandles()
	{
		std::unique_lock<boost::shared_mutex> lock(polygonMeshHandleMutex_);

		polygonMeshHandleMap_.clear();
	}

	pathfinding::PolygonMeshHandle getPolygonMeshHandle(const std::string& name) const
	{
		boost::shared_lock_guard<boost::shared_mutex> lock(polygonMeshHandleMutex_);

        const auto it = polygonMeshHandleMap_.find(name);
		if (it != polygonMeshHandleMap_.end()) return it->second;

		return pathfinding::PolygonMeshHandle();
	}

	void addNavigationMeshHandle(const std::string& name, const pathfinding::NavigationMeshHandle& handle)
	{
		std::unique_lock<boost::shared_mutex> lock(navigationMeshHandleMutex_);

		if (navigationMeshHandleMap_.find(name) != navigationMeshHandleMap_.end())
		{
			throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
		}

		navigationMeshHandleMap_[name] = handle;
	}

	void removeNavigationMeshHandle(const std::string& name)
	{
		std::unique_lock<boost::shared_mutex> lock(navigationMeshHandleMutex_);

		auto it = navigationMeshHandleMap_.find(name);
		if (it != navigationMeshHandleMap_.end())
		{
			navigationMeshHandleMap_.erase(it);
		}
	}

	void removeAllNavigationMeshHandles()
	{
		std::unique_lock<boost::shared_mutex> lock(navigationMeshHandleMutex_);

		navigationMeshHandleMap_.clear();
	}

	pathfinding::NavigationMeshHandle getNavigationMeshHandle(const std::string& name) const
	{
		boost::shared_lock_guard<boost::shared_mutex> lock(navigationMeshHandleMutex_);

		const auto it = navigationMeshHandleMap_.find(name);
		if (it != navigationMeshHandleMap_.end()) return it->second;

		return pathfinding::NavigationMeshHandle();
	}

	std::unordered_map<std::string, physics::CollisionShapeHandle> collisionShapeHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(collisionShapeHandleMutex_);

        return collisionShapeHandleMap_;
    }

	std::unordered_map<std::string, ModelHandle> modelHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(modelHandleMutex_);

        return modelHandleMap_;
    }

	std::unordered_map<std::string, SkeletonHandle> skeletonHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(skeletonHandleMutex_);

        return skeletonHandleMap_;
    }

	std::unordered_map<std::string, AnimationHandle> animationHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(animationHandleMutex_);

        return animationHandleMap_;
    }

	std::unordered_map<std::string, graphics::MeshHandle> meshHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(meshHandleMutex_);

        return meshHandleMap_;
    }

	std::unordered_map<std::string, graphics::TextureHandle> textureHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(textureHandleMutex_);

        return textureHandleMap_;
    }

	std::unordered_map<std::string, graphics::TerrainHandle> terrainHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(terrainHandleMutex_);

        return terrainHandleMap_;
    }

	std::unordered_map<std::string, graphics::SkyboxHandle> skyboxHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(skyboxHandleMutex_);

			return skyboxHandleMap_;
    }

    std::unordered_map<std::string, audio::SoundHandle> soundHandleMap()
    {
		boost::shared_lock_guard<boost::shared_mutex> lock(soundHandleMutex_);

        return soundHandleMap_;
    }

	std::unordered_map<std::string, pathfinding::PolygonMeshHandle> polygonMeshHandleMap()
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(polygonMeshHandleMutex_);

         return polygonMeshHandleMap_;
    }

	std::unordered_map<std::string, pathfinding::NavigationMeshHandle> navigationMeshHandleMap()
    {
        boost::shared_lock_guard<boost::shared_mutex> lock(navigationMeshHandleMutex_);

        return navigationMeshHandleMap_;
    }

private:
	mutable boost::shared_mutex collisionShapeHandleMutex_;
	mutable boost::shared_mutex modelHandleMutex_;
	mutable boost::shared_mutex skeletonHandleMutex_;
	mutable boost::shared_mutex animationHandleMutex_;
	mutable boost::shared_mutex meshHandleMutex_;
	mutable boost::shared_mutex textureHandleMutex_;
	mutable boost::shared_mutex terrainHandleMutex_;
	mutable boost::shared_mutex skyboxHandleMutex_;
	mutable boost::shared_mutex soundHandleMutex_;
	mutable boost::shared_mutex polygonMeshHandleMutex_;
	mutable boost::shared_mutex navigationMeshHandleMutex_;

	std::unordered_map<std::string, physics::CollisionShapeHandle> collisionShapeHandleMap_;
	std::unordered_map<std::string, ModelHandle> modelHandleMap_;
	std::unordered_map<std::string, SkeletonHandle> skeletonHandleMap_;
	std::unordered_map<std::string, AnimationHandle> animationHandleMap_;
	std::unordered_map<std::string, graphics::MeshHandle> meshHandleMap_;
	std::unordered_map<std::string, graphics::TextureHandle> textureHandleMap_;
	std::unordered_map<std::string, graphics::TerrainHandle> terrainHandleMap_;
	std::unordered_map<std::string, graphics::SkyboxHandle> skyboxHandleMap_;
	std::unordered_map<std::string, audio::SoundHandle> soundHandleMap_;
	std::unordered_map<std::string, pathfinding::PolygonMeshHandle> polygonMeshHandleMap_;
	std::unordered_map<std::string, pathfinding::NavigationMeshHandle> navigationMeshHandleMap_;
};

//template <typename T>
//class ResourceCache
//{
//public:
//    void add(const std::string& name, const T resource)
//    {
//        std::unique_lock<boost::shared_mutex> lock(mutex_);
//
//        if (resourceMap_.find(name) != resourceMap_.end())
//        {
//            throw RuntimeException(detail::format("Resource with name '%s' already exists.", name));
//        }
//
//        resourceMap_[name] = resource;
//    }
//
//    void remove(const std::string& name)
//    {
//        std::unique_lock<boost::shared_mutex> lock(mutex_);
//
//        auto it = resourceMap_.find(name);
//        if (it != resourceMap_.end())
//        {
//            resourceMap_.erase(it);
//        }
//    }
//
//    void removeAll()
//    {
//        std::unique_lock<boost::shared_mutex> lock(mutex_);
//
//        resourceMap_.clear();
//    }
//
//    T get(const std::string& name) const
//    {
//        boost::shared_lock_guard<boost::shared_mutex> lock(mutex_);
//
//        const auto it = resourceMap_.find(name);
//        if (it != resourceMap_.end()) return it->second;
//
//        return T();
//    }
//
//    std::unordered_map<std::string, T> resourceMap() const
//    {
//        boost::shared_lock_guard<boost::shared_mutex> lock(mutex_);
//
//        return resourceMap_;
//    }
//
//private:
//    mutable boost::shared_mutex mutex_;
//
//    std::unordered_map<std::string, T> resourceMap_;
//};

}

#endif /* RESOURCEHANDLECACHE_H_ */


text: #include <boost/math/tools/real_cast.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino