text:
#include "stored_queries/StoredForecastQueryHandler.h"
#include "FeatureID.h"
#include "StoredQueryHandlerFactoryDef.h"
#include "WfsConvenience.h"
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <macgyver/StringConversion.h>
#include <macgyver/TimeParser.h>
#include <macgyver/TimeFormatter.h>
#include <macgyver/TypeName.h>
#include <newbase/NFmiPoint.h>
#include <newbase/NFmiQueryData.h>
#include <smartmet/engines/querydata/MetaQueryOptions.h>
#include <smartmet/macgyver/Exception.h>
#include <smartmet/spine/Convenience.h>
#include <smartmet/spine/ParameterFactory.h>
#include <smartmet/spine/Table.h>
#include <smartmet/spine/TimeSeriesGenerator.h>
#include <smartmet/spine/TimeSeriesOutput.h>
#include <smartmet/spine/Value.h>
#include <limits>
#include <locale>
#include <map>

namespace bw = SmartMet::Plugin::WFS;
namespace ba = boost::algorithm;
namespace pt = boost::posix_time;
namespace lt = boost::local_time;
using namespace SmartMet::Spine;

using boost::format;
using boost::str;

const char* bw::StoredForecastQueryHandler::P_MODEL = "model";
const char* bw::StoredForecastQueryHandler::P_ORIGIN_TIME = "originTime";
const char* bw::StoredForecastQueryHandler::P_LEVEL_HEIGHTS = "levelHeights";
const char* bw::StoredForecastQueryHandler::P_LEVEL = "level";
const char* bw::StoredForecastQueryHandler::P_LEVEL_TYPE = "levelType";
const char* bw::StoredForecastQueryHandler::P_PARAM = "param";
const char* bw::StoredForecastQueryHandler::P_FIND_NEAREST_VALID = "findNearestValid";
const char* bw::StoredForecastQueryHandler::P_LOCALE = "locale";
const char* bw::StoredForecastQueryHandler::P_MISSING_TEXT = "missingText";
const char* bw::StoredForecastQueryHandler::P_CRS = "crs";

bw::StoredForecastQueryHandler::StoredForecastQueryHandler(
    SmartMet::Spine::Reactor* reactor,
    bw::StoredQueryConfig::Ptr config,
    PluginImpl& plugin_data,
    boost::optional<std::string> template_file_name)

    : bw::StoredQueryParamRegistry(config),
      bw::SupportsExtraHandlerParams(config, false),
      bw::RequiresGeoEngine(reactor),
      bw::RequiresQEngine(reactor),
      bw::StoredQueryHandlerBase(reactor, config, plugin_data, template_file_name),
      bw::SupportsLocationParameters(
          reactor,
          config,
          SUPPORT_KEYWORDS | INCLUDE_GEOIDS | INCLUDE_FMISIDS | INCLUDE_WMOS | INCLUDE_LPNNS),
      bw::SupportsMeteoParameterOptions(config),
      bw::SupportsTimeParameters(config),
      bw::SupportsTimeZone(reactor, config),
      common_params(),
      ind_geoid(SmartMet::add_param(common_params, "geoid", Parameter::Type::DataIndependent, kFmiGEOID)),
      ind_epoch(SmartMet::add_param(common_params, "time", Parameter::Type::DataIndependent, kFmiTime)),
      ind_place(SmartMet::add_param(common_params, "name", Parameter::Type::DataIndependent, kFmiName)),
      ind_lat(SmartMet::add_param(common_params, "latitude", Parameter::Type::DataIndependent, kFmiLatitude)),
      ind_lon(SmartMet::add_param(common_params, "longitude", Parameter::Type::DataIndependent, kFmiLongitude)),
      ind_elev(SmartMet::add_param(common_params, "elevation", Parameter::Type::DataIndependent, kFmiElevation)),
      ind_level(SmartMet::add_param(common_params, "level", Parameter::Type::DataIndependent, kFmiLevel)),
      ind_region(SmartMet::add_param(common_params, "region", Parameter::Type::DataIndependent, kFmiRegion)),
      ind_country(SmartMet::add_param(common_params, "country", Parameter::Type::DataIndependent, kFmiCountry)),
      ind_country_iso(SmartMet::add_param(common_params, "iso2", Parameter::Type::DataIndependent, kFmiISO2)),
      ind_localtz(SmartMet::add_param(common_params, "localtz", Parameter::Type::DataIndependent, kFmiLocalTZ))
{
  try
  {
    register_array_param<std::string>(P_MODEL);
    register_scalar_param<pt::ptime>(P_ORIGIN_TIME, false);
    register_array_param<double>(P_LEVEL_HEIGHTS, 0, 99);
    register_array_param<int64_t>(P_LEVEL, 0, 99);
    register_scalar_param<std::string>(P_LEVEL_TYPE);
    register_array_param<std::string>(P_PARAM, 1, 99);
    register_scalar_param<int64_t>(P_FIND_NEAREST_VALID);
    register_scalar_param<std::string>(P_LOCALE);
    register_scalar_param<std::string>(P_MISSING_TEXT);
    register_scalar_param<std::string>(P_CRS);

    max_np_distance = config->get_optional_config_param<double>("maxNpDistance", -1.0);
    separate_groups = config->get_optional_config_param<bool>("separateGroups", false);
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

bw::StoredForecastQueryHandler::~StoredForecastQueryHandler() {}

void bw::StoredForecastQueryHandler::query(const StoredQuery& stored_query,
                                           const std::string& language,
                                           const boost::optional<std::string>& hostname,
                                           std::ostream& output) const
{
  try
  {
    namespace pt = boost::posix_time;
    using namespace SmartMet;
    using namespace SmartMet::Plugin::WFS;

    static const long ref_jd = boost::gregorian::date(1970, 1, 1).julian_day();

    int debug_level = get_config()->get_debug_level();
    if (debug_level > 0)
      stored_query.dump_query_info(std::cout);

    bw::StoredForecastQueryHandler::Query query(get_config());

    query.language = language;
    const auto& params = stored_query.get_param_map();

    try
    {
      // Parsing request parameters
      try
      {
        SmartMet::Spine::ValueFormatterParam vf_param;

        query.missing_text = params.get_single<std::string>(P_MISSING_TEXT);
        vf_param.missingText = query.missing_text;
        query.set_locale(params.get_single<std::string>(P_LOCALE));
        query.max_distance = params.get_single<double>(P_MAX_DISTANCE);
        query.max_np_distance = max_np_distance > 0.0 ? max_np_distance : query.max_distance;
        query.keyword = params.get_optional<std::string>(P_KEYWORD, "");
        query.find_nearest_valid_point = params.get_single<int64_t>(P_FIND_NEAREST_VALID) != 0;
        query.tz_name = get_tz_name(params);

        parse_models(params, query);
        get_location_options(params, query.language, &query.locations);

        parse_level_heights(params, query);
        parse_levels(params, query);
        parse_params(params, query);
        query.value_formatter.reset(new SmartMet::Spine::ValueFormatter(vf_param));
        query.time_formatter.reset(Fmi::TimeFormatter::create("iso"));
        parse_times(params, query);

        const std::string crs = params.get_single<std::string>(P_CRS);
        auto transformation =
            plugin_impl.get_crs_registry().create_transformation("urn:ogc:def:crs:EPSG::4326", crs);
        bool show_height = false;
        std::string proj_uri = "UNKNOWN";
        std::string proj_epoch_uri = "UNKNOWN";
        plugin_impl.get_crs_registry().get_attribute(crs, "showHeight", &show_height);
        plugin_impl.get_crs_registry().get_attribute(crs, "projUri", &proj_uri);
        plugin_impl.get_crs_registry().get_attribute(crs, "projEpochUri", &proj_epoch_uri);

        query.result = extract_forecast(query);
        const std::size_t num_rows = query.result->rows().size();

        std::set<std::string> geo_id_set;
        std::multimap<int, std::string> group_map;
        std::multimap<std::string, std::size_t> result_map;
        for (std::size_t i = 0; i < num_rows; i++)
        {
          const std::string geo_id = query.result->get(ind_geoid, i);
          result_map.insert(std::make_pair(geo_id, i));
          geo_id_set.insert(geo_id);
        }

        std::size_t num_groups = 0;
        BOOST_FOREACH (const auto& geo_id, geo_id_set)
        {
          group_map.insert(std::make_pair(num_groups, geo_id));
          if (separate_groups)
            num_groups++;
        }

        if (not separate_groups and (geo_id_set.size() > 0))
          num_groups++;

        CTPP::CDT hash;

        hash["language"] = language;

        hash["responseTimestamp"] =
            Fmi::to_iso_extended_string(get_plugin_impl().get_time_stamp()) + "Z";
        hash["numMatched"] = num_groups;
        hash["numReturned"] = num_groups;
        hash["numParam"] = query.last_data_ind - query.first_data_ind + 1;

        hash["fmi_apikey"] = bw::QueryBase::FMI_APIKEY_SUBST;
        hash["fmi_apikey_prefix"] = bw::QueryBase::FMI_APIKEY_PREFIX_SUBST;
        hash["hostname"] = QueryBase::HOSTNAME_SUBST;
        hash["protocol"] = QueryBase::PROTOCOL_SUBST;
        hash["srsName"] = proj_uri;
        hash["srsDim"] = show_height ? 3 : 2;
        hash["srsEpochName"] = proj_epoch_uri;
        hash["srsEpochDim"] = show_height ? 4 : 3;

        int sq_id = stored_query.get_query_id();
        const char* location_params[] = {P_PLACES, P_LATLONS, P_GEOIDS, P_KEYWORD};

        for (std::size_t group_id = 0; group_id < num_groups; group_id++)
        {
          std::size_t station_ind = 0;
          auto site_range = group_map.equal_range(group_id);
          CTPP::CDT& group = hash["groups"][group_id];

          FeatureID feature_id(get_config()->get_query_id(), params.get_map(), sq_id);
          for (std::size_t i = 0; i < sizeof(location_params) / sizeof(*location_params); i++)
          {
            feature_id.erase_param(location_params[i]);
          }
          auto geoid_range = group_map.equal_range(group_id);
          for (auto it = geoid_range.first; it != geoid_range.second; ++it)
          {
            feature_id.add_param(P_GEOIDS, it->second);
          }
          group["featureId"] = feature_id.get_id();

          group["groupId"] = str(format("%1%-%2%") % sq_id % (group_id + 1));
          if (query.origin_time)
          {
            const std::string origin_time_str =
                Fmi::to_iso_extended_string(*query.origin_time) + "Z";
            group["dataOriginTime"] = origin_time_str;
          }

          if (query.modification_time != boost::posix_time::not_a_date_time)
          {
            const std::string modification_time_str =
                Fmi::to_iso_extended_string(query.modification_time) + "Z";
            group["resultTime"] = modification_time_str;
          }

          for (std::size_t i = query.first_data_ind; i <= query.last_data_ind; i++)
          {
            const std::string& name = query.data_params.at(i).name();
            feature_id.erase_param(P_PARAM);
            feature_id.add_param(P_PARAM, name);
            group["paramList"][i - query.first_data_ind]["name"] = name;
            group["paramList"][i - query.first_data_ind]["featureId"] = feature_id.get_id();
          }

          group["metadata"]["boundingBox"]["lowerLeft"]["lat"] = query.bottom_left.Y();
          group["metadata"]["boundingBox"]["lowerLeft"]["lon"] = query.bottom_left.X();

          group["metadata"]["boundingBox"]["lowerRight"]["lat"] = query.bottom_right.Y();
          group["metadata"]["boundingBox"]["lowerRight"]["lon"] = query.bottom_right.X();

          group["metadata"]["boundingBox"]["upperLeft"]["lat"] = query.top_left.Y();
          group["metadata"]["boundingBox"]["upperLeft"]["lon"] = query.top_left.X();

          group["metadata"]["boundingBox"]["upperRight"]["lat"] = query.top_right.Y();
          group["metadata"]["boundingBox"]["upperRight"]["lon"] = query.top_right.X();

          group["producerName"] = query.producer_name;
#ifdef ENABLE_MODEL_PATH
          group["modelPath"] = query.model_path;
#endif

          std::size_t row_counter = 0;

          pt::ptime interval_begin = boost::date_time::pos_infin;
          pt::ptime interval_end = boost::date_time::neg_infin;

          for (auto site_iter = site_range.first; site_iter != site_range.second; ++site_iter)
          {
            const auto& geo_id = site_iter->second;
            auto row_range = result_map.equal_range(geo_id);
            lt::time_zone_ptr tzp;
            for (auto row_iter = row_range.first; row_iter != row_range.second; ++row_iter)
            {
              std::size_t i = row_iter->second;
              if (row_iter == row_range.first)
              {
                const std::string name = query.result->get(ind_place, i);
                const std::string country_code = query.result->get(ind_country_iso, i);
                const std::string country = query.result->get(ind_country, i);
                const std::string region = query.result->get(ind_region, i);
                const std::string localtz = query.result->get(ind_localtz, i);
                const double latitude = Fmi::stod(query.result->get(ind_lat, i));
                const double longitude = Fmi::stod(query.result->get(ind_lon, i));
                tzp = get_tz_for_site(longitude, latitude, query.tz_name);
                group["stationList"][station_ind]["geoid"] = geo_id;
                group["stationList"][station_ind]["name"] = name;
                set_2D_coord(
                    transformation, latitude, longitude, group["stationList"][station_ind]);
                if (show_height)
                {
                  group["stationList"][station_ind]["elev"] = query.result->get(ind_elev, i);
                  ;
                }

                group["stationList"][station_ind]["iso2"] = country_code;
                group["stationList"][station_ind]["country"] = country;
                group["stationList"][station_ind]["localtz"] = localtz;
                if ((country_code == "FI") or (name != region))
                {
                  group["stationList"][station_ind]["region"] = region;
                }

                station_ind++;
              }

              CTPP::CDT& row_data = group["returnArray"][row_counter++];

              set_2D_coord(transformation,
                           query.result->get(ind_lat, i),
                           query.result->get(ind_lon, i),
                           row_data);

              if (show_height)
              {
                row_data["elev"] = query.result->get(ind_level, i);
              }

              pt::ptime epoch = Fmi::TimeParser::parse_iso(query.result->get(ind_epoch, i));
              long long jd = epoch.date().julian_day();
              long seconds = epoch.time_of_day().total_seconds();
              INT_64 s_epoch = 86400LL * (jd - ref_jd) + seconds;
              row_data["epochTime"] = s_epoch;
              row_data["epochTimeStr"] = format_local_time(epoch, tzp);

              for (std::size_t k = query.first_data_ind; k <= query.last_data_ind; k++)
              {
                row_data["data"][k - query.first_data_ind] =
                    remove_trailing_0(query.result->get(k, i));
              }

              interval_begin = i == 0 ? epoch : std::min(interval_begin, epoch);
              interval_end = i == 0 ? epoch : std::max(interval_end, epoch);
            }
          }

          group["phenomenonStartTime"] = Fmi::to_iso_extended_string(interval_begin) + "Z";
          group["phenomenonEndTime"] = Fmi::to_iso_extended_string(interval_end) + "Z";
        }

        format_output(hash, output, stored_query.get_use_debug_format());
      }
      catch (...)
      {
        throw Fmi::Exception::Trace(BCP, "Operation parsing failed!")
            .addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PARSING_FAILED);
      }
    }
    catch (...)
    {
      Fmi::Exception exception(BCP, "Operation parsing failed!", nullptr);
      if (exception.getExceptionByParameterName(WFS_EXCEPTION_CODE) == nullptr)
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PARSING_FAILED);
      exception.addParameter(WFS_LANGUAGE, query.language);
      throw exception;
    }
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

namespace
{
struct StationRec
{
  std::string geoid;
  std::string name;
  std::string lat;
  std::string lon;
  std::string elev;
};
}  // namespace

boost::shared_ptr<SmartMet::Spine::Table> bw::StoredForecastQueryHandler::extract_forecast(
    Query& query) const
{
  try
  {
    using namespace SmartMet;

    int debug_level = get_config()->get_debug_level();

    boost::shared_ptr<SmartMet::Spine::Table> ennusteet(new SmartMet::Spine::Table);

#ifdef ENABLE_MODEL_PATH
    boost::optional<std::string> model_path;
#endif

    std::string language = Fmi::ascii_tolower_copy(query.language);
    SupportsLocationParameters::engOrFinToEnOrFi(language);

    decltype(query.origin_time) origin_time;
    if (query.origin_time)
    {
      origin_time.reset(new pt::ptime(*query.origin_time));
    }

    int row = 0;
    BOOST_FOREACH (const auto& tloc, query.locations)
    {
      SmartMet::Spine::LocationPtr loc = tloc.second;
      const std::string place = tloc.second->name;
      const std::string country = geo_engine->countryName(loc->iso2, language);
      if (debug_level > 0)
      {
        std::cout << "Location: " << loc->name << " in " << country << std::endl;
      }

      SmartMet::Engine::Querydata::Producer producer = select_producer(*loc, query);

      if (debug_level > 0)
      {
        std::cout << "Selected producer: " << producer << std::endl;
      }

      if (producer.empty())
      {
        if (query.keyword.empty())
        {
          Fmi::Exception exception(BCP, "No data available for '" + loc->name + "'!");
          exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED);
          throw exception.disableStackTrace();
        }
      }

      auto q = (origin_time ? q_engine->get(producer, *origin_time) : q_engine->get(producer));
      query.modification_time = q->modificationTime();

// FIXME: try to use the same model instead of searching model again
#ifdef ENABLE_MODEL_PATH
      if (model_path and q->path().string() != *model_path)
      {
        Fmi::Exception exception(BCP, "Weather model mixing is not allowed!");
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED);
        exception.addParameter("Config name", configName);
        throw exception.disableStackTrace();
      }

      model_path = q->path().string();
#endif

      if (not query.origin_time)
      {
        // With multifile data q_engine->get() origintime must not be set/locked

        query.origin_time.reset(new pt::ptime(q->originTime()));

        if (not q_engine->getProducerConfig(producer).ismultifile)
        {
          origin_time.reset(new pt::ptime(*query.origin_time));
        }
      }

      query.have_model_area = false;

      if (q->isArea())
      {
        const NFmiArea& area = q->area();
        query.have_model_area = true;
        query.top_left = area.TopLeftLatLon();
        query.top_right = area.TopRightLatLon();
        query.bottom_left = area.BottomLeftLatLon();
        query.bottom_right = area.BottomRightLatLon();
      }

      if (debug_level > 0 and not query.have_model_area)
      {
        std::ostringstream msg;
        msg << METHOD_NAME << ": WARNING: model area not available";
#ifdef ENABLE_MODEL_PATH
        if (model_path)
          msg << " for " << *model_path;
#endif
        msg << std::endl;
        std::cout << msg.str() << std::flush;
      }

      // If we accept nearest valid points, find it now for this location
      // This is fast if the nearest point is already valid

      NFmiPoint nearestpoint(kFloatMissing, kFloatMissing);
      if (query.find_nearest_valid_point)
      {
        NFmiPoint latlon(loc->longitude, loc->latitude);
        // Querydata is using kilometers and WFS meters for a distance.
        nearestpoint = q->validPoint(latlon, query.max_np_distance / 1000.0);
      }

      if (debug_level > 0)
      {
        std::cout << "Producer : " << producer << std::endl;
#ifdef ENABLE_MODEL_PATH
        std::cout << "Selected model: " << q->path() << std::endl;
#endif
      }

      query.producer_name = producer;
#ifdef ENABLE_MODEL_PATH
      query.model_path = q->path().string();
#endif

      const std::string zone = "UTC";

      query.toptions->setDataTimes(q->validTimes(), q->isClimatology());
      if (debug_level > 2)
      {
        std::cout << *query.toptions << "\n";
      }

      auto tz = geo_engine->getTimeZones().time_zone_from_string(zone);
      auto tlist = SmartMet::Spine::TimeSeriesGenerator::generate(*query.toptions, tz);

      if (debug_level > 2)
      {
        std::cout << __FILE__ << "#" << __LINE__ << ": generated times:";
        BOOST_FOREACH (const auto& t, tlist)
        {
          std::cout << " '" << t << "'";
        }
        std::cout << std::endl;
      }

      const int default_prec = 6;
      const auto param_map = get_model_parameters(producer, q->originTime());
      std::map<std::string, int> param_precision_map;
      BOOST_FOREACH (const Parameter& param, query.data_params)
      {
        const std::string& name = param.name();
        auto pos = param_map.find(Fmi::ascii_tolower_copy(name));
        if (pos == param_map.end())
        {
          param_precision_map[name] = default_prec;
        }
        else
        {
          param_precision_map[name] = pos->second.precision;
        }

        if (have_meteo_param_options(name))
        {
          param_precision_map[name] = get_meteo_parameter_options(name)->precision;
        }
      }

      if (not query.level_heights.empty() and q->levelType() != FmiLevelType::kFmiHybridLevel)
      {
        Fmi::Exception exception(
            BCP, "Only hybrid data supports data fetching from an arbitrary height.");
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED);
        throw exception.disableStackTrace();
      }

      if (not query.levels.empty() and not query.level_heights.empty())
      {
        Fmi::Exception exception(BCP,
                                 "Fetching data from a level and an arbitrary height is not "
                                 "supported in a same request.");
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED);
        throw exception.disableStackTrace();
      }

      /*
      if (query.levels.empty() and query.level_heights.empty())
      {
        Fmi::Exception exception(BCP, "No level selected.");
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED);
        throw exception;
      }
      */

      // Fetch data from an arbitrary height.
      for (const auto& level_height : query.level_heights)
      {
        for (const lt::local_date_time& dt : tlist)
        {
          using SmartMet::Spine::Parameter;

          int column = 0;
          for (const Parameter& param : query.data_params)
          {
            int prec = param_precision_map.at(param.name());

            const std::string timestring = "";

            SmartMet::Engine::Querydata::ParameterOptions qengine_param(
                param,
                producer,
                *loc,
                country,
                place,
                *query.time_formatter,
                timestring,
                query.language,
                *query.output_locale,
                zone,
                query.find_nearest_valid_point,
                nearestpoint,
                query.lastpoint);
            SmartMet::Spine::TimeSeries::Value val =
                q->valueAtHeight(qengine_param, dt, level_height);

            std::stringstream ss;
            SmartMet::Spine::TimeSeries::OStreamVisitor osv(ss, *query.value_formatter, prec);
            boost::apply_visitor(osv, val);

            ennusteet->set(column, row, ss.str());

            ++column;
          }

          ++row;
        }
      }

      for (q->resetLevel(); q->nextLevel() and query.level_heights.empty();)
      {
        if (query.levels.empty() || query.levels.count(static_cast<int>(q->levelValue())) > 0)
        {
          BOOST_FOREACH (const lt::local_date_time& d, tlist)
          {
            using SmartMet::Spine::Parameter;

            int column = 0;
            BOOST_FOREACH (const Parameter& param, query.data_params)
            {
              int prec = param_precision_map.at(param.name());

              const std::string timestring = "";

              SmartMet::Engine::Querydata::ParameterOptions qengine_param(
                  param,
                  producer,
                  *loc,
                  country,
                  place,
                  *query.time_formatter,
                  timestring,
                  query.language,
                  *query.output_locale,
                  zone,
                  query.find_nearest_valid_point,
                  nearestpoint,
                  query.lastpoint);
              SmartMet::Spine::TimeSeries::Value val = q->value(qengine_param, d);

              std::stringstream ss;
              SmartMet::Spine::TimeSeries::OStreamVisitor osv(ss, *query.value_formatter, prec);
              boost::apply_visitor(osv, val);

              ennusteet->set(column, row, ss.str());

              ++column;
            }

            ++row;
          }
        }
      }
    }

    return ennusteet;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

SmartMet::Engine::Querydata::Producer bw::StoredForecastQueryHandler::select_producer(
    const SmartMet::Spine::Location& location, const Query& query) const
{
  try
  {
    SmartMet::Engine::Querydata::Producer producer;

    const bool use_data_specific_max_distance = false;
    if (query.models.empty())
    {
      // Querydata is using kilometers and WFS meters for a distance.
      producer = q_engine->find(location.longitude,
                                location.latitude,
                                query.max_distance / 1000.0,
                                use_data_specific_max_distance,
                                query.level_type);
    }
    else
    {
      producer = q_engine->find(query.models,
                                location.longitude,
                                location.latitude,
                                query.max_distance / 1000.0,
                                use_data_specific_max_distance,
                                query.level_type);
    }

    if (producer.empty() && query.keyword.empty())
    {
      throw Fmi::Exception(BCP, "No data available for '" + location.name + "'!")
          .addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED)
          .disableStackTrace();
    }

    return producer;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

void bw::StoredForecastQueryHandler::parse_models(const RequestParameterMap& params,
                                                  StoredForecastQueryHandler::Query& dest) const
{
  try
  {
    dest.models.clear();
    params.get<std::string>(P_MODEL, std::back_inserter(dest.models));
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

void bw::StoredForecastQueryHandler::parse_level_heights(const RequestParameterMap& params,
                                                         Query& dest) const
{
  try
  {
    dest.level_heights.clear();
    std::vector<double> heights;
    params.get<double>(P_LEVEL_HEIGHTS, std::back_inserter(heights));
    for (const auto& item : heights)
    {
      float tmp = static_cast<float>(item);
      if (!dest.level_heights.insert(tmp).second)
      {
        Fmi::Exception exception(BCP, "Duplicate geometric height '" + std::to_string(tmp) + "'!");
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PARSING_FAILED);
        throw exception;
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Geometric height parsing failed!");
  }
}
void bw::StoredForecastQueryHandler::parse_levels(const RequestParameterMap& params,
                                                  Query& dest) const
{
  try
  {
    dest.levels.clear();

    dest.level_type = params.get_single<std::string>(P_LEVEL_TYPE);

    std::vector<int64_t> levels;
    params.get<int64_t>(P_LEVEL, std::back_inserter(levels));
    BOOST_FOREACH (int64_t level, levels)
    {
      int tmp = cast_int_type<int>(level);
      if (!dest.levels.insert(tmp).second)
      {
        Fmi::Exception exception(BCP, "Duplicate level '" + std::to_string(tmp) + "'!");
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PARSING_FAILED);
        throw exception;
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

void bw::StoredForecastQueryHandler::parse_times(const RequestParameterMap& param,
                                                 Query& dest) const
{
  try
  {
    dest.toptions = get_time_generator_options(param);

    // boost::optional + gcc-4.4.X käytäytyy huonosti
    if (param.count(P_ORIGIN_TIME) > 0)
      dest.origin_time.reset(new pt::ptime(param.get_single<pt::ptime>(P_ORIGIN_TIME)));
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

void bw::StoredForecastQueryHandler::parse_params(const RequestParameterMap& param,
                                                  Query& dest) const
{
  try
  {
    using SmartMet::Spine::Parameter;
    using SmartMet::Spine::ParameterFactory;

    dest.data_params = common_params;

    std::vector<std::string> names;
    param.get<std::string>(P_PARAM, std::back_inserter(names));
    BOOST_FOREACH (const std::string& name, names)
    {
      std::size_t ind = dest.data_params.size();
      auto p = ParameterFactory::instance().parse(name);
      dest.data_params.push_back(p);

      if (dest.first_data_ind == 0)
        dest.first_data_ind = ind;
      dest.last_data_ind = ind;
    }
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

std::map<std::string, SmartMet::Engine::Querydata::ModelParameter>
bw::StoredForecastQueryHandler::get_model_parameters(const std::string& producer,
                                                     const pt::ptime& origin_time) const
{
  try
  {
    using SmartMet::Engine::Querydata::MetaData;
    using SmartMet::Engine::Querydata::MetaQueryOptions;

    MetaQueryOptions qopt;
    qopt.setProducer(producer);
    qopt.setOriginTime(origin_time);
    std::list<MetaData> meta_info = q_engine->getEngineMetadata(qopt);
    std::map<std::string, SmartMet::Engine::Querydata::ModelParameter> result;
    BOOST_FOREACH (const auto& item, meta_info)
    {
      // std::cout << "### " << item.producer << std::endl;
      BOOST_FOREACH (const auto& param, item.parameters)
      {
        // std::cout << "=== " << param.name << " : " << param.precision << " : "
        //          << param.description << std::endl;
        result.insert(std::make_pair(Fmi::ascii_tolower_copy(param.name), param));
      }
    }

    return result;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

bw::StoredForecastQueryHandler::Query::Query(boost::shared_ptr<const StoredQueryConfig> config)
    : max_distance(20000.0),
      missing_text("nan"),
      language("lan"),
      find_nearest_valid_point(false),
      value_formatter(new SmartMet::Spine::ValueFormatter(SmartMet::Spine::ValueFormatterParam())),
      have_model_area(false),
      top_left(NFmiPoint::gMissingLatlon),
      top_right(NFmiPoint::gMissingLatlon),
      bottom_left(NFmiPoint::gMissingLatlon),
      bottom_right(NFmiPoint::gMissingLatlon),
      first_data_ind(0),
      last_data_ind(0)
{
  try
  {
    output_locale = config->get_locale();
    time_formatter.reset(Fmi::TimeFormatter::create("iso"));
    value_formatter->setMissingText(missing_text);
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

bw::StoredForecastQueryHandler::Query::~Query() {}

void bw::StoredForecastQueryHandler::Query::set_locale(const std::string& locale_name)
{
  try
  {
    try
    {
      output_locale.reset(new std::locale(locale_name.c_str()));
    }
    catch (...)
    {
      Fmi::Exception exception(BCP, "Failed to set locale '" + locale_name + "'!", nullptr);
      if (exception.getExceptionByParameterName(WFS_EXCEPTION_CODE) == nullptr)
        exception.addParameter(WFS_EXCEPTION_CODE, WFS_OPERATION_PROCESSING_FAILED);
      throw exception.disableStackTrace();
    }
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}

namespace
{
using namespace SmartMet::Plugin::WFS;

boost::shared_ptr<SmartMet::Plugin::WFS::StoredQueryHandlerBase> wfs_forecast_handler_create(
    SmartMet::Spine::Reactor* reactor,
    StoredQueryConfig::Ptr config,
    PluginImpl& plugin_impl,
    boost::optional<std::string> template_file_name)
{
  try
  {
    StoredForecastQueryHandler* qh =
        new StoredForecastQueryHandler(reactor, config, plugin_impl, template_file_name);
    boost::shared_ptr<SmartMet::Plugin::WFS::StoredQueryHandlerBase> result(qh);
    return result;
  }
  catch (...)
  {
    throw Fmi::Exception::Trace(BCP, "Operation failed!");
  }
}
}  // namespace

SmartMet::Plugin::WFS::StoredQueryHandlerFactoryDef wfs_forecast_handler_factory(
    &wfs_forecast_handler_create);

/**

@page WFS_SQ_FORECAST_QUERY_HANDLER Stored Query handler for querying weather forecast data

@section WFS_SQ_FORECAST_QUERY_HANDLER_INTRO Introduction

This stored query handler provides support of querying weather forecast data from
<a href="../../../engines/querydata/index.html">Querydata</a>

<table border="1">
  <tr>
    <td>Implementation</td>
    <td>SmartMet::Plugin::WFS::StoredForecastQueryHandler</td>
  </tr>
  <tr>
    <td>constructor name (for stored query configuration)</td>
    <td>@b wfs_forecast_handler_factory</td>
</table>

@section WFS_SQ_FORECAST_QUERY_HANDLER_PARAMS Query handler built-in parameters

The following stored query handler parameter groups are being used by this stored query handler:
- @ref WFS_SQ_LOCATION_PARAMS
- @ref WFS_SQ_TIME_PARAMS
- @ref WFS_SQ_TIME_ZONE

Additionally to parameters from these groups the following parameters are also in use

<table border="1">

<tr>
<th>Entry name</th>
<th>Type</th>
<th>Data type</th>
<th>Description</th>
</tr>

<tr>
  <td>model</td>
  <td>@ref WFS_CFG_ARRAY_PARAM_TMPL</td>
  <td>string</td>
  <td>Specifies weather models to use. Specifying an empty array allows to use all models
      available to Querydata</td>
</tr>

<tr>
  <td>originTime</td>
  <td>@ref WFS_CFG_SCALAR_PARAM_TMPL</td>
  <td>time</td>
  <td>Specifies origin time of weather models to use when specified. May be omitted in query.
      All available origin time values are acceptable when omitted</td>
</tr>

<tr>
  <td>level</td>
  <td>@ref WFS_CFG_ARRAY_PARAM_TMPL</td>
  <td>integer</td>
  <td>Model levels to query.</td>
</tr>

<tr>
  <td>levelHeights</td>
  <td>@ref WFS_CFG_ARRAY_PARAM_TMPL</td>
  <td>doulbeList</td>
  <td>Arbitrary level heighs to query.</td>
</tr>

<tr>
  <td>levelType</td>
  <td>@ref WFS_CFG_SCALAR_PARAM_TMPL</td>
  <td>string</td>
  <td>Specifies model level typo to use/td>
</tr>

<tr>
  <td>findNearestValid</td>
  <td>@ref WFS_CFG_SCALAR_PARAM_TMPL</td>
  <td>integer</td>
  <td>Specifying non zero value causes look-up of nearest point from model</td>
</tr>

<tr>
  <td>locale</td>
  <td>@ref WFS_CFG_SCALAR_PARAM_TMPL</td>
  <td>string</td>
  <td>Specifies locale to use (for example @b fi_FI.utf8 )</td>
</tr>

<tr>
  <td>missingText</td>
  <td>@ref WFS_CFG_SCALAR_PARAM_TMPL</td>
  <td>string</td>
  <td>Specifies text to use for missing values</td>
</tr>

<tr>
  <td>crs</td>
  <td>@ref WFS_CFG_SCALAR_PARAM_TMPL</td>
  <td>string</td>
  <td>Specifies coordinate projection to use</td>
</tr>

</table>

@section WFS_SQ_GENERIC_OBS_EXTRA_CFG_PARAM Additional parameters

This section describes this stored query handler configuration parameters which does not map to
stored query parameters
and must be specified on top level of stored query configuration file when present

<table border="1">

<tr>
<th>Entry name</th>
<th>Type</th>
<th>Use</th>
<th>Description</th>
</tr>

<tr>
  <td>max_np_distance</td>
  <td>double</td>
  <td>optional</td>
  <td>Specifies maximal distance (meters) for looking up nearest valid point. Only matters if
      query handler parameter @b findNearestValid is non zero.</td>
</tr>

<tr>
  <td>separateGroups</td>
  <td>boolean</td>
  <td>optional (default false)</td>
  <td>Specifying @b true causes separate response group to be generated for each site/td>
</tr>

</table>

*/

ext: cpp

max_stars_repo_name: nakkim/smartmet-plugin-wfs

max_issues_repo_name: nakkim/smartmet-plugin-wfs

max_forks_repo_name: nakkim/smartmet-plugin-wfs


text:
//  boost/endian/buffers.hpp
//  ----------------------------------------------------------//

//  (C) Copyright Darin Adler 2000
//  (C) Copyright Beman Dawes 2006, 2009, 2014
//  (C) Copyright Peter Dimov 2019

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

//  See library home page at http://www.boost.org/libs/endian

//--------------------------------------------------------------------------------------//

//  Original design developed by Darin Adler based on classes developed by Mark
//  Borgerding. Four original class templates were combined into a single endian
//  class template by Beman Dawes, who also added the unrolled_byte_loops sign
//  partial specialization to correctly extend the sign when cover integer size
//  differs from endian representation size.

// TODO: When a compiler supporting constexpr becomes available, try possible
// uses.

#ifndef BOOST_ENDIAN_BUFFERS_HPP
#define BOOST_ENDIAN_BUFFERS_HPP

#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
#endif

#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/core/scoped_enum.hpp>
#include <boost/cstdint.hpp>
#include <boost/endian/detail/endian_load.hpp>
#include <boost/endian/detail/endian_store.hpp>
#include <boost/predef/other/endian.h>
#include <boost/static_assert.hpp>
#include <climits>
#include <cstring>
#include <iosfwd>

#if defined(__BORLANDC__) || defined(__CODEGEARC__)
#pragma pack(push, 1)
#endif

#if CHAR_BIT != 8
#error Platforms with CHAR_BIT != 8 are not supported
#endif

#ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
#define BOOST_ENDIAN_DEFAULT_CONSTRUCT                                         \
  {} // C++03
#else
#define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
#endif

// g++ pre-4.6 does not support unrestricted unions, but we have no Config macro
// for that
#if (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) ||                            \
     BOOST_WORKAROUND(BOOST_GCC, < 40600)) &&                                  \
    defined(BOOST_ENDIAN_FORCE_PODNESS)
#define BOOST_ENDIAN_NO_CTORS
#endif

//----------------------------------  synopsis
//----------------------------------------//

namespace boost {
namespace endian {

BOOST_SCOPED_ENUM_START(align){no, yes
#ifdef BOOST_ENDIAN_DEPRECATED_NAMES
                               ,
                               unaligned = no, aligned = yes
#endif
};
BOOST_SCOPED_ENUM_END

template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
          BOOST_SCOPED_ENUM(align) A = align::no>
class endian_buffer;

// aligned big endian signed integer buffers
typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at;
typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at;
typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at;
typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at;

// aligned big endian unsigned integer buffers
typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at;
typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at;
typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at;
typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at;

// aligned little endian signed integer buffers
typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at;
typedef endian_buffer<order::little, int16_t, 16, align::yes>
    little_int16_buf_at;
typedef endian_buffer<order::little, int32_t, 32, align::yes>
    little_int32_buf_at;
typedef endian_buffer<order::little, int64_t, 64, align::yes>
    little_int64_buf_at;

// aligned little endian unsigned integer buffers
typedef endian_buffer<order::little, uint8_t, 8, align::yes>
    little_uint8_buf_at;
typedef endian_buffer<order::little, uint16_t, 16, align::yes>
    little_uint16_buf_at;
typedef endian_buffer<order::little, uint32_t, 32, align::yes>
    little_uint32_buf_at;
typedef endian_buffer<order::little, uint64_t, 64, align::yes>
    little_uint64_buf_at;

// aligned floating point buffers
typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_at;
typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_at;
typedef endian_buffer<order::little, float, 32, align::yes>
    little_float32_buf_at;
typedef endian_buffer<order::little, double, 64, align::yes>
    little_float64_buf_at;

// aligned native endian typedefs are not provided because
// <cstdint> types are superior for this use case

// unaligned big endian signed integer buffers
typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t;
typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t;
typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t;
typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t;
typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t;
typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t;
typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t;
typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t;

// unaligned big endian unsigned integer buffers
typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t;
typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t;
typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t;
typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t;
typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t;
typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t;
typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t;
typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t;

// unaligned little endian signed integer buffers
typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t;
typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t;
typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t;
typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t;
typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t;
typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t;
typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t;
typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t;

// unaligned little endian unsigned integer buffers
typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t;
typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t;
typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t;
typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t;
typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t;
typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t;
typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t;
typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t;

#if BOOST_ENDIAN_BIG_BYTE
// unaligned native endian signed integer buffers
typedef big_int8_buf_t native_int8_buf_t;
typedef big_int16_buf_t native_int16_buf_t;
typedef big_int24_buf_t native_int24_buf_t;
typedef big_int32_buf_t native_int32_buf_t;
typedef big_int40_buf_t native_int40_buf_t;
typedef big_int48_buf_t native_int48_buf_t;
typedef big_int56_buf_t native_int56_buf_t;
typedef big_int64_buf_t native_int64_buf_t;

// unaligned native endian unsigned integer buffers
typedef big_uint8_buf_t native_uint8_buf_t;
typedef big_uint16_buf_t native_uint16_buf_t;
typedef big_uint24_buf_t native_uint24_buf_t;
typedef big_uint32_buf_t native_uint32_buf_t;
typedef big_uint40_buf_t native_uint40_buf_t;
typedef big_uint48_buf_t native_uint48_buf_t;
typedef big_uint56_buf_t native_uint56_buf_t;
typedef big_uint64_buf_t native_uint64_buf_t;
#else
// unaligned native endian signed integer buffers
typedef little_int8_buf_t native_int8_buf_t;
typedef little_int16_buf_t native_int16_buf_t;
typedef little_int24_buf_t native_int24_buf_t;
typedef little_int32_buf_t native_int32_buf_t;
typedef little_int40_buf_t native_int40_buf_t;
typedef little_int48_buf_t native_int48_buf_t;
typedef little_int56_buf_t native_int56_buf_t;
typedef little_int64_buf_t native_int64_buf_t;

// unaligned native endian unsigned integer buffers
typedef little_uint8_buf_t native_uint8_buf_t;
typedef little_uint16_buf_t native_uint16_buf_t;
typedef little_uint24_buf_t native_uint24_buf_t;
typedef little_uint32_buf_t native_uint32_buf_t;
typedef little_uint40_buf_t native_uint40_buf_t;
typedef little_uint48_buf_t native_uint48_buf_t;
typedef little_uint56_buf_t native_uint56_buf_t;
typedef little_uint64_buf_t native_uint64_buf_t;
#endif

// unaligned floating point buffers
typedef endian_buffer<order::big, float, 32, align::no> big_float32_buf_t;
typedef endian_buffer<order::big, double, 64, align::no> big_float64_buf_t;
typedef endian_buffer<order::little, float, 32, align::no> little_float32_buf_t;
typedef endian_buffer<order::little, double, 64, align::no>
    little_float64_buf_t;
typedef endian_buffer<order::native, float, 32, align::no> native_float32_buf_t;
typedef endian_buffer<order::native, double, 64, align::no>
    native_float64_buf_t;

// Stream inserter
template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
          std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
std::basic_ostream<charT, traits> &
operator<<(std::basic_ostream<charT, traits> &os,
           const endian_buffer<Order, T, n_bits, A> &x) {
  return os << x.value();
}

// Stream extractor
template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
          std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
std::basic_istream<charT, traits> &
operator>>(std::basic_istream<charT, traits> &is,
           endian_buffer<Order, T, n_bits, A> &x) {
  T i;
  if (is >> i)
    x = i;
  return is;
}

//----------------------------------  end synopsis
//------------------------------------//

//  endian_buffer class template specializations
//  --------------------------------------//

//  Specializations that represent unaligned bytes.
//  Taking an integer type as a parameter provides a nice way to pass both
//  the size and signedness of the desired integer and get the appropriate
//  corresponding integer type for the interface.

// Q: Should endian_buffer supply "value_type operator value_type() const
// noexcept"? A: No. The rationale for endian_buffers is to prevent high-cost
// hidden
//    conversions. If an implicit conversion operator is supplied, hidden
//    conversions can occur.

//  unaligned endian_buffer specialization

template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits>
class endian_buffer<Order, T, n_bits, align::no> {
private:
  BOOST_STATIC_ASSERT((n_bits / 8) * 8 == n_bits);

  unsigned char value_[n_bits / 8];

public:
  typedef T value_type;

#ifndef BOOST_ENDIAN_NO_CTORS

  endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT

      explicit endian_buffer(T val) BOOST_NOEXCEPT {
    boost::endian::endian_store<T, n_bits / 8, Order>(value_, val);
  }

#endif

  endian_buffer &operator=(T val) BOOST_NOEXCEPT {
    boost::endian::endian_store<T, n_bits / 8, Order>(value_, val);
    return *this;
  }

  value_type value() const BOOST_NOEXCEPT {
    return boost::endian::endian_load<T, n_bits / 8, Order>(value_);
  }

  unsigned char const *data() const BOOST_NOEXCEPT { return value_; }

  unsigned char *data() BOOST_NOEXCEPT { return value_; }
};

// aligned specializations; only n_bits == 16/32/64 supported

// aligned endian_buffer specialization

template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits>
class endian_buffer<Order, T, n_bits, align::yes> {
private:
  BOOST_STATIC_ASSERT((n_bits / 8) * 8 == n_bits);
  BOOST_STATIC_ASSERT(sizeof(T) == n_bits / 8);

  union {
    unsigned char value_[n_bits / 8];
    T align_;
  };

public:
  typedef T value_type;

#ifndef BOOST_ENDIAN_NO_CTORS

  endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT

      explicit endian_buffer(T val) BOOST_NOEXCEPT {
    boost::endian::endian_store<T, n_bits / 8, Order>(value_, val);
  }

#endif

  endian_buffer &operator=(T val) BOOST_NOEXCEPT {
    boost::endian::endian_store<T, n_bits / 8, Order>(value_, val);
    return *this;
  }

  value_type value() const BOOST_NOEXCEPT {
    return boost::endian::endian_load<T, n_bits / 8, Order>(value_);
  }

  unsigned char const *data() const BOOST_NOEXCEPT { return value_; }

  unsigned char *data() BOOST_NOEXCEPT { return value_; }
};

// aligned native endian_buffer specialization

template <class T, std::size_t n_bits>
class endian_buffer<order::native, T, n_bits, align::yes> {
private:
  BOOST_STATIC_ASSERT((n_bits / 8) * 8 == n_bits);
  BOOST_STATIC_ASSERT(sizeof(T) == n_bits / 8);

  T value_;

public:
  typedef T value_type;

#ifndef BOOST_ENDIAN_NO_CTORS

  endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT

      explicit endian_buffer(T val) BOOST_NOEXCEPT : value_(val) {}

#endif

  endian_buffer &operator=(T val) BOOST_NOEXCEPT {
    value_ = val;
    return *this;
  }

  value_type value() const BOOST_NOEXCEPT { return value_; }

  unsigned char const *data() const BOOST_NOEXCEPT {
    return reinterpret_cast<unsigned char const *>(&value_);
  }

  unsigned char *data() BOOST_NOEXCEPT {
    return reinterpret_cast<unsigned char *>(&value_);
  }
};

} // namespace endian
} // namespace boost

#if defined(__BORLANDC__) || defined(__CODEGEARC__)
#pragma pack(pop)
#endif

#if defined(_MSC_VER)
#pragma warning(pop)
#endif

#endif // BOOST_ENDIAN_BUFFERS_HPP

ext: hpp

max_stars_repo_name: henrywarhurst/matrix

max_issues_repo_name: henrywarhurst/matrix

max_forks_repo_name: henrywarhurst/matrix


text:
#include <gtest/gtest.h>

#include <blink/raster/utility.h>
#include <blink/raster/gdal_raster_view.h>
#include <blink/raster/edge_view.h>
#include <blink/raster/gdal_input_iterator.h>
#include <blink/raster/pad_raster.h>
#include <blink/raster/offset_raster.h>
#include <boost/filesystem.hpp>

bool test_create_temp_gdal_raster()
{
  auto r = blink::raster::create_temp_gdal_raster<int>(5, 3);
  int count = 0;
  for (auto&& i : r)
  {
    i = count++;
  }
  std::vector<int> check_vector;
  for (auto&& i : r)
  {
    check_vector.push_back(i);
  }
  return check_vector == std::vector<int>
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
}

bool test_create_gdal_raster()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 5, 3);
    int count = 0;
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist;
}

bool test_open_gdal_raster()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 5, 3);
    int count = 0;
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto r = blink::raster::open_gdal_raster<int>("temp.tif", GA_ReadOnly);
    std::vector<int> check_vector;
    for (auto&& i : r)
    {
      check_vector.push_back(i);
    }
    check_contents =  check_vector == std::vector<int>
     {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_gdal_raster_delete_on_close()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp2.tif", 5, 3);
    int count = 0;
    for (auto&& i : r)
    {
      i = count++;
    }
    r.set_delete_on_close(true);
  } // leave scope, remove temp.tif
  bool check_not_exist = !boost::filesystem::exists("temp2.tif");
  return check_not_exist;
}

bool test_gdal_raster_transpose_view()
{
  auto r = blink::raster::create_temp_gdal_raster<int>(3,5);
  int count = 0;
  for (auto&& i : r)
  {
    i = count++;
  }

  auto t = blink::raster::make_raster_view(
    &r, blink::raster::orientation::col_major{});
  std::vector<int> check_vector;
  for (auto&& i : t)
  {
    check_vector.push_back(i);
  }
  return check_vector == std::vector<int>
    {0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14};

}

bool test_gdal_raster_v_edge_view()
{
  auto r = blink::raster::create_temp_gdal_raster<int>(3, 5);
  int count = 0;
  for (auto&& i : r)
  {
    i = count++;
  }

  auto t = blink::raster::make_raster_view(
    &r, blink::raster::orientation::row_major{},
    blink::raster::element::v_edge{});

  std::vector < std::pair<boost::optional<int>, boost::optional<int> > >
    check_vector;
  for (auto&& i : t)
  {
    check_vector.push_back(i);
  }
  using o_int = boost::optional<int>;
  using o_pair = std::pair<o_int, o_int>;

  std::vector < o_pair > c2;
  c2.push_back(o_pair(o_int(  ), o_int( 0)));
  c2.push_back(o_pair(o_int( 0), o_int( 1)));
  c2.push_back(o_pair(o_int( 1), o_int( 2)));
  c2.push_back(o_pair(o_int( 2), o_int( 3)));
  c2.push_back(o_pair(o_int( 3), o_int( 4)));
  c2.push_back(o_pair(o_int( 4), o_int(  )));
  c2.push_back(o_pair(o_int(  ), o_int( 5)));
  c2.push_back(o_pair(o_int( 5), o_int( 6)));
  c2.push_back(o_pair(o_int( 6), o_int( 7)));
  c2.push_back(o_pair(o_int( 7), o_int( 8)));
  c2.push_back(o_pair(o_int( 8), o_int( 9)));
  c2.push_back(o_pair(o_int( 9), o_int(  )));
  c2.push_back(o_pair(o_int(  ), o_int(10)));
  c2.push_back(o_pair(o_int(10), o_int(11)));
  c2.push_back(o_pair(o_int(11), o_int(12)));
  c2.push_back(o_pair(o_int(12), o_int(13)));
  c2.push_back(o_pair(o_int(13), o_int(14)));
  c2.push_back(o_pair(o_int(14), o_int(  )));

  return c2==check_vector;
}

bool test_gdal_raster_transpose_v_edge_view()
{
  auto r = blink::raster::create_temp_gdal_raster<int>(3, 5);
  int count = 0;
  for (auto&& i : r)
  {
    i = count++;
  }

  auto t = blink::raster::make_raster_view(
    &r, blink::raster::orientation::col_major{},
    blink::raster::element::v_edge{});

  std::vector < std::pair<boost::optional<int>, boost::optional<int> > >
    check_vector;
  for (auto&& i : t)
  {
    check_vector.push_back(i);
  }
  using o_int = boost::optional<int>;
  using o_pair = std::pair<o_int, o_int>;

  std::vector < o_pair > c2;
  c2.push_back(o_pair(o_int(), o_int(0)));
  c2.push_back(o_pair(o_int(), o_int(5)));
  c2.push_back(o_pair(o_int(), o_int(10)));
  c2.push_back(o_pair(o_int(0), o_int(1)));
  c2.push_back(o_pair(o_int(5), o_int(6)));
  c2.push_back(o_pair(o_int(10), o_int(11)));
  c2.push_back(o_pair(o_int(1), o_int(2)));
  c2.push_back(o_pair(o_int(6), o_int(7)));
  c2.push_back(o_pair(o_int(11), o_int(12)));
  c2.push_back(o_pair(o_int(2), o_int(3)));
  c2.push_back(o_pair(o_int(7), o_int(8)));
  c2.push_back(o_pair(o_int(12), o_int(13)));
  c2.push_back(o_pair(o_int(3), o_int(4)));
  c2.push_back(o_pair(o_int(8), o_int(9)));
  c2.push_back(o_pair(o_int(13), o_int(14)));
  c2.push_back(o_pair(o_int(4), o_int()));
  c2.push_back(o_pair(o_int(9), o_int()));
  c2.push_back(o_pair(o_int(14), o_int()));

  return c2 == check_vector;
}

bool test_gdal_raster_h_edge_view()
{
  auto r = blink::raster::create_temp_gdal_raster<int>(3, 5);
  int count = 0;
  for (auto&& i : r)
  {
    i = count++;
  }

  auto t = blink::raster::make_raster_view(
    &r, blink::raster::orientation::row_major{},
    blink::raster::element::h_edge{});

  std::vector < std::pair<boost::optional<int>, boost::optional<int> > >
    check_vector;
  for (auto&& i : t)
  {
    check_vector.push_back(i);
  }
  using o_int = boost::optional<int>;
  using o_pair = std::pair<o_int, o_int>;

  std::vector < o_pair > c2;
  c2.push_back(o_pair(o_int(), o_int(0)));
  c2.push_back(o_pair(o_int(), o_int(1)));
  c2.push_back(o_pair(o_int(), o_int(2)));
  c2.push_back(o_pair(o_int(), o_int(3)));
  c2.push_back(o_pair(o_int(), o_int(4)));
  c2.push_back(o_pair(o_int(0), o_int(5)));
  c2.push_back(o_pair(o_int(1), o_int(6)));
  c2.push_back(o_pair(o_int(2), o_int(7)));
  c2.push_back(o_pair(o_int(3), o_int(8)));
  c2.push_back(o_pair(o_int(4), o_int(9)));
  c2.push_back(o_pair(o_int(5), o_int(10)));
  c2.push_back(o_pair(o_int(6), o_int(11)));
  c2.push_back(o_pair(o_int(7), o_int(12)));
  c2.push_back(o_pair(o_int(8), o_int(13)));
  c2.push_back(o_pair(o_int(9), o_int(14)));
  c2.push_back(o_pair(o_int(10), o_int()));
  c2.push_back(o_pair(o_int(11), o_int()));
  c2.push_back(o_pair(o_int(12), o_int()));
  c2.push_back(o_pair(o_int(13), o_int()));
  c2.push_back(o_pair(o_int(14), o_int()));

  return c2 == check_vector;
}

bool test_gdal_raster_transpose_h_edge_view()
{
  auto r = blink::raster::create_temp_gdal_raster<int>(3, 5);
  int count = 0;
  for (auto&& i : r)
  {
    i = count++;
  }

  auto t = blink::raster::make_raster_view(
    &r, blink::raster::orientation::col_major{},
    blink::raster::element::h_edge{});

  std::vector < std::pair<boost::optional<int>, boost::optional<int> > >
    check_vector;
  for (auto&& i : t)
  {
    check_vector.push_back(i);
  }
  using o_int = boost::optional<int>;
  using o_pair = std::pair<o_int, o_int>;

  std::vector < o_pair > c2;

  c2.push_back(o_pair(o_int(), o_int(0)));
  c2.push_back(o_pair(o_int(0), o_int(5)));
  c2.push_back(o_pair(o_int(5), o_int(10)));
  c2.push_back(o_pair(o_int(10), o_int()));

  c2.push_back(o_pair(o_int(), o_int(1)));
  c2.push_back(o_pair(o_int(1), o_int(6)));
  c2.push_back(o_pair(o_int(6), o_int(11)));
  c2.push_back(o_pair(o_int(11), o_int()));

  c2.push_back(o_pair(o_int(), o_int(2)));
  c2.push_back(o_pair(o_int(2), o_int(7)));
  c2.push_back(o_pair(o_int(7), o_int(12)));
  c2.push_back(o_pair(o_int(12), o_int()));

  c2.push_back(o_pair(o_int(), o_int(3)));
  c2.push_back(o_pair(o_int(3), o_int(8)));
  c2.push_back(o_pair(o_int(8), o_int(13)));
  c2.push_back(o_pair(o_int(13), o_int()));

  c2.push_back(o_pair(o_int(), o_int(4)));
  c2.push_back(o_pair(o_int(4), o_int(9)));
  c2.push_back(o_pair(o_int(9), o_int(14)));
  c2.push_back(o_pair(o_int(14), o_int()));

  return c2 == check_vector;
}

bool test_input_view_raster()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 5, 3);
    int count = 0;
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif", GA_ReadOnly);
    blink::raster::gdalrasterband_range_view<const int> view(band);
    std::vector<int> check_vector;

    for (auto&& i : view)
    {
      check_vector.push_back(i);
    }

    check_contents = check_vector == std::vector<int>
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_gdal_raster_large()
{
  {
    auto view = blink::raster::create_gdal_raster<int>("temp.tif", 5000, 3000);
    int count = 0;
    for (auto&& i : view)
    {
      i = count++;
    }
  }
  bool check_exist = boost::filesystem::exists("temp.tif");

  bool check_contents;
  {
    auto view = blink::raster::open_gdal_raster<int>("temp.tif", GA_ReadOnly);

    std::vector<int> check_vector;
    for (auto&& i : view)
    {
      check_vector.push_back(i);
    }
    int last = check_vector.back();
    check_vector.resize(15);
    check_contents = check_vector == std::vector<int>
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
    && last == (5000 * 3000 - 1);
  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_input_view_raster_large()
{
  int rows = 50;
  int cols = 30;
  {
    auto band = blink::raster::detail::gdal_makers::create_band("temp.tif", rows, cols,
      GDT_Int32);
    blink::raster::gdalrasterband_range_view<int> view(band);

    int count = 0;
    for (auto&& i : view)
    {
      i = count++;
    }
  }
  bool check_exist = boost::filesystem::exists("temp.tif");

  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif",
      //GA_Update,
      GA_ReadOnly,
      1);
    blink::raster::gdalrasterband_range_view<const int> view(band);

    std::vector<int> check_vector;
    for (auto&& i : view)
    {
      check_vector.push_back(i);
    }

    int last = check_vector.back();
    check_vector.resize(15);
    check_contents = check_vector == std::vector<int>
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
    && last == (rows*cols  - 1);
  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}
bool test_padded_raster()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 2, 3);
    int count = 1; // start at 1
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif", GA_ReadOnly);
    blink::raster::gdalrasterband_range_view<const int> view(band);
    auto padded = pad_raster(view, 1, 3, 2, 4);
    std::vector<int> check_vector;

    for (boost::optional<const int>&& i : padded)
    {
      if (i) {
        check_vector.push_back(i.get());
      }
      else {
        check_vector.push_back(0);
      }
    }
    check_contents = check_vector == std::vector < int >
    {0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 1, 2, 3, 0, 0, 0, 0,
      0, 0, 4, 5, 6, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0};

  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_padded_raster_2()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 2, 3);
    int count = 1; // start at 1
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif", GA_ReadOnly);
    blink::raster::gdalrasterband_range_view<const int> view(band);
    auto padded = pad_raster(view, 1, 0, 2, 0);
    std::vector<int> check_vector;

    for (boost::optional<const int>&& i : padded)
    {
      if (i) {
        check_vector.push_back(i.get());
      }
      else {
        check_vector.push_back(0);
      }
    }
    check_contents = check_vector == std::vector < int >
    {0, 0, 0, 0, 0,
      0, 0, 1, 2, 3,
      0, 0, 4, 5, 6};

  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_padded_raster_3()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 2, 3);
    int count = 1; // start at 1
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif", GA_ReadOnly);
    blink::raster::gdalrasterband_range_view<const int> view(band);
    auto padded = pad_raster(view, 0, 1, 0, 2);
    std::vector<int> check_vector;

    for (boost::optional<const int>&& i : padded)
    {
      if (i) {
        check_vector.push_back(i.get());
      }
      else {
        check_vector.push_back(0);
      }
    }
    check_contents = check_vector == std::vector < int >
    {1, 2, 3, 0, 0,
     4, 5, 6, 0, 0,
     0, 0, 0, 0, 0
    };

  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_offset_raster()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 3, 4);
    int count = 1; // start at 1
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif", GA_ReadOnly);
    blink::raster::gdalrasterband_range_view<const int> view(band);
    auto offset = offset_raster(view, 1, 2);
    std::vector<int> check_vector;

    for (boost::optional<const int>&& i : offset)
    {
      if (i) {
        check_vector.push_back(i.get());
      //  std::cout << i.get() << " ";
      }
      else {
        check_vector.push_back(0);
     //   std::cout << 0 << " ";
      }
    }
    check_contents = check_vector == std::vector < int >
    { 7, 8, 0, 0,
      11, 12, 0, 0,
      0, 0, 0, 0};

  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

bool test_offset_raster_2()
{
  {
    auto r = blink::raster::create_gdal_raster<int>("temp.tif", 3, 4);
    int count = 1; // start at 1
    for (auto&& i : r)
    {
      i = count++;
    }
  } // leave scope
  bool check_exist = boost::filesystem::exists("temp.tif");
  bool check_contents;
  {
    auto band = blink::raster::detail::gdal_makers::open_band("temp.tif", GA_ReadOnly);
    blink::raster::gdalrasterband_range_view<const int> view(band);
    auto offset = offset_raster(view, -1, -2);
    std::vector<int> check_vector;

    for (boost::optional<const int>&& i : offset)
    {
      if (i) {
        check_vector.push_back(i.get());
     //   std::cout << i.get() << " ";
      }
      else {
        check_vector.push_back(0);
    //    std::cout << 0 << " ";
      }
    }
    check_contents = check_vector == std::vector < int >
    { 0, 0, 0, 0,
      0, 0, 1, 2,
      0, 0, 5, 6};

  }
  boost::filesystem::remove("temp.tif");
  bool check_not_exist = !boost::filesystem::exists("temp.tif");
  return check_exist && check_not_exist && check_contents;
}

//#if NDEBUG // Ouch, have not build gdal libraries in debug and now get funny errors
TEST(Raster, GDALRaster) {
  EXPECT_TRUE(test_create_temp_gdal_raster());
  EXPECT_TRUE(test_create_gdal_raster());
  EXPECT_TRUE(test_open_gdal_raster());
  EXPECT_TRUE(test_gdal_raster_delete_on_close());
  EXPECT_TRUE(test_gdal_raster_transpose_view());
  EXPECT_TRUE(test_gdal_raster_v_edge_view());
  EXPECT_TRUE(test_gdal_raster_transpose_v_edge_view());
  EXPECT_TRUE(test_gdal_raster_h_edge_view());
  EXPECT_TRUE(test_gdal_raster_transpose_h_edge_view());
  EXPECT_TRUE(test_input_view_raster());
  EXPECT_TRUE(test_input_view_raster_large());
  EXPECT_TRUE(test_padded_raster());
  EXPECT_TRUE(test_padded_raster_2());
  EXPECT_TRUE(test_padded_raster_3());
  EXPECT_TRUE(test_offset_raster());
  EXPECT_TRUE(test_offset_raster_2());
  // EXPECT_TRUE(test_gdal_raster_large());

 }
//#endif


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#ifndef INCLUDED_CANVAS_CANVASCUSTOMSPRITEBASE_HXX
#define INCLUDED_CANVAS_CANVASCUSTOMSPRITEBASE_HXX

#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/rendering/XCustomSprite.hpp>
#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/range/b2drange.hxx>
#include <canvas/base/integerbitmapbase.hxx>
#include <canvas/base/sprite.hxx>

#include <boost/utility.hpp>

namespace canvas
{
    /** Helper template to handle XCustomSprite method forwarding to
        CanvasCustomSpriteHelper

    	Use this helper to handle the XCustomSprite part of your
    	implementation.

        @tpl Base
        Base class to use, most probably one of the
        WeakComponentImplHelperN templates with the appropriate
        interfaces. At least XCustomSprite and Sprite should be among
        them (why else would you use this template, then?). Base class
        must have an Base( const Mutex& ) constructor (like the
        WeakComponentImplHelperN templates have).

        @tpl SpriteHelper
        Sprite helper implementation for the backend in question

        @tpl CanvasHelper
        Canvas helper implementation for the backend in question

        @tpl Mutex
        Lock strategy to use. Defaults to using the
        OBaseMutex-provided lock.  Every time one of the methods is
        entered, an object of type Mutex is created with m_aMutex as
        the sole parameter, and destroyed again when the method scope
        is left.

        @tpl UnambiguousBase
        Optional unambiguous base class for XInterface of Base. It's
        sometimes necessary to specify this parameter, e.g. if Base
        derives from multiple UNO interface (were each provides its
        own version of XInterface, making the conversion ambiguous)

        @see CanvasCustomSpriteHelper for further contractual
        requirements towards the SpriteHelper type, and some examples.
     */
    template< class Base,
              class SpriteHelper,
              class CanvasHelper,
              class Mutex=::osl::MutexGuard,
              class UnambiguousBase=::com::sun::star::uno::XInterface > class CanvasCustomSpriteBase :
        public IntegerBitmapBase< Base, CanvasHelper, Mutex, UnambiguousBase >
    {
    public:
        typedef IntegerBitmapBase< Base, CanvasHelper, Mutex, UnambiguousBase >	BaseType;
        typedef SpriteHelper													SpriteHelperType;

        CanvasCustomSpriteBase() :
            maSpriteHelper()
        {
        }

        /** Object is being disposed.

        	Called from the cppu helper base, to notify disposal of
        	this object. Already releases all internal references.

            @derive when overriding this method in derived classes,
            always call the base class' method!
         */
        virtual void SAL_CALL disposing()
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.disposing();

            // pass on to base class
            BaseType::disposing();
        }

        // XCanvas: selectively override base's methods here, for opacity tracking
        virtual void SAL_CALL clear() throw (::com::sun::star::uno::RuntimeException)
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.clearingContent( this );

            // and forward to base class, which handles the actual rendering
            return BaseType::clear();
        }

        virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCachedPrimitive > SAL_CALL
        	drawBitmap( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmap >& xBitmap,
                        const ::com::sun::star::rendering::ViewState& 									viewState,
                        const ::com::sun::star::rendering::RenderState& 								renderState ) throw (::com::sun::star::lang::IllegalArgumentException,
                                                                                ::com::sun::star::uno::RuntimeException)
        {
            tools::verifyArgs(xBitmap, viewState, renderState,
                              BOOST_CURRENT_FUNCTION,
                              static_cast< typename BaseType::UnambiguousBaseType* >(this));

            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.checkDrawBitmap( this, xBitmap, viewState, renderState );

            // and forward to base class, which handles the actual rendering
            return BaseType::drawBitmap( xBitmap,
                                         viewState,
                                         renderState );
        }

        // TODO(F3): If somebody uses the XIntegerBitmap methods to
        // clear pixel (setting alpha != 1.0 there), or a compositing
        // mode results in similar alpha, maSpriteHelper might
        // errorneously report fully opaque sprites. Effectively, all
        // render methods must be overridden here; or better,
        // functionality provided at the baseclass.

        // XSprite
        virtual void SAL_CALL setAlpha( double alpha ) throw (::com::sun::star::lang::IllegalArgumentException,
                                                              ::com::sun::star::uno::RuntimeException)
        {
            tools::verifyRange( alpha, 0.0, 1.0 );

            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.setAlpha( this, alpha );
        }

        virtual void SAL_CALL move( const ::com::sun::star::geometry::RealPoint2D& 	aNewPos,
                                    const ::com::sun::star::rendering::ViewState& 	viewState,
                                    const ::com::sun::star::rendering::RenderState& renderState ) throw (::com::sun::star::lang::IllegalArgumentException,
                                                                                ::com::sun::star::uno::RuntimeException)
        {
            tools::verifyArgs(aNewPos, viewState, renderState,
                              BOOST_CURRENT_FUNCTION,
                              static_cast< typename BaseType::UnambiguousBaseType* >(this));

            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.move( this, aNewPos, viewState, renderState );
        }

        virtual void SAL_CALL transform( const ::com::sun::star::geometry::AffineMatrix2D& aTransformation ) throw (::com::sun::star::lang::IllegalArgumentException,
                                                                                ::com::sun::star::uno::RuntimeException)
        {
            tools::verifyArgs(aTransformation,
                              BOOST_CURRENT_FUNCTION,
                              static_cast< typename BaseType::UnambiguousBaseType* >(this));

            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.transform( this, aTransformation );
        }

        virtual void SAL_CALL clip( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >& aClip ) throw (::com::sun::star::uno::RuntimeException)
        {
            // NULL xClip explicitly allowed here (to clear clipping)

            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.clip( this, aClip );
        }

        virtual void SAL_CALL setPriority( double nPriority ) throw (::com::sun::star::uno::RuntimeException)
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.setPriority( this, nPriority );
        }

        virtual void SAL_CALL show() throw (::com::sun::star::uno::RuntimeException)
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.show( this );
        }

        virtual void SAL_CALL hide() throw (::com::sun::star::uno::RuntimeException)
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            maSpriteHelper.hide( this );
        }

        // XCustomSprite
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > SAL_CALL
        	getContentCanvas() throw (::com::sun::star::uno::RuntimeException)
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return this;
        }

        // Sprite
        virtual bool isAreaUpdateOpaque( const ::basegfx::B2DRange& rUpdateArea ) const
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return maSpriteHelper.isAreaUpdateOpaque( rUpdateArea );
        }

        virtual bool isContentChanged() const
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return BaseType::mbSurfaceDirty;
        }

        virtual ::basegfx::B2DPoint getPosPixel() const
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return maSpriteHelper.getPosPixel();
        }

        virtual ::basegfx::B2DVector getSizePixel() const
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return maSpriteHelper.getSizePixel();
        }

        virtual ::basegfx::B2DRange getUpdateArea() const
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return maSpriteHelper.getUpdateArea();
        }

        virtual double getPriority() const
        {
            typename BaseType::MutexType aGuard( BaseType::m_aMutex );

            return maSpriteHelper.getPriority();
        }

    protected:
        SpriteHelperType maSpriteHelper;
    };
}

#endif /* INCLUDED_CANVAS_CANVASCUSTOMSPRITEBASE_HXX */

ext: hxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
//
// FILE NAME:		$HeadURL: svn+ssh://sstrick@svn.cm.aol.com/advertising/adlearn/gen1/branches/dpl-ping/lib/cpp/DataProxy/Service/PingHandler.hpp $
//
// REVISION:		$Revision: 234049 $
//
// COPYRIGHT:		(c) 2007 Advertising.com All Rights Reserved.
//
// LAST UPDATED:	$Date: 2011-12-27 16:23:02 -0500 (Tue, 27 Dec 2011) $
// UPDATED BY:		$Author: sstrick $
//

#ifndef _PING_HANDLER_
#define _PING_HANDLER_

#include "AbstractHandler.hpp"
#include "MVException.hpp"
#include <boost/noncopyable.hpp>
#include <string>

class HTTPRequest;
class HTTPResponse;
class DataProxyClient;

MV_MAKEEXCEPTIONCLASS( PingHandlerException, MVException );

class PingHandler : public AbstractHandler
{
public:
	PingHandler( DataProxyClient& i_rDataProxyClient, const std::string& i_rDplConfig );
	virtual ~PingHandler();

	virtual void Handle( HTTPRequest& i_rRequest, HTTPResponse& o_rResponse );
};

#endif // _PING_HANDLER_

max_stars_repo_name: aol/DataProxyLibrary

max_issues_repo_name: aol/DataProxyLibrary

max_forks_repo_name: aol/DataProxyLibrary


text:
/*
 * KQuery.cpp
 *
 *  Created on: 2012-9-23
 *      Author: fasiondog
 */

#include <boost/algorithm/string.hpp>
#include "KQuery.h"

namespace hku {

const string KQuery::MIN("MIN");
const string KQuery::MIN5("MIN5");
const string KQuery::MIN15("MIN15");
const string KQuery::MIN30("MIN30");
const string KQuery::MIN60("MIN60");
const string KQuery::DAY("DAY");
const string KQuery::WEEK("WEEK");
const string KQuery::MONTH("MONTH");
const string KQuery::QUARTER("QUARTER");
const string KQuery::HALFYEAR("HALFYEAR");
const string KQuery::YEAR("YEAR");
const string KQuery::MIN3("MIN3");
const string KQuery::HOUR2("HOUR2");
const string KQuery::HOUR4("HOUR4");
const string KQuery::HOUR6("HOUR5");
const string KQuery::HOUR12("HOUR12");
// const string KQuery::INVALID_KTYPE("Z");

KQuery::KQuery(Datetime start, Datetime end, KType ktype, RecoverType recoverType)
: m_start(start == Null<Datetime>() ? (int64_t)start.number()
                                    : (int64_t)(start.number() * 100 + start.second())),
  m_end(end == Null<Datetime>() ? (int64_t)end.number()
                                : (int64_t)(end.number() * 100 + end.second())),
  m_queryType(KQuery::DATE),
  m_dataType(ktype),
  m_recoverType(recoverType) {
    to_upper(m_dataType);
}

Datetime KQuery::startDatetime() const {
    HKU_IF_RETURN(m_queryType != DATE || (uint64_t)m_start == Null<uint64_t>(), Null<Datetime>());
    uint64_t number = (uint64_t)(m_start / 100);
    Datetime d(number);
    return Datetime(d.year(), d.month(), d.day(), d.hour(), d.minute(), m_start - number * 100);
}

Datetime KQuery::endDatetime() const {
    HKU_IF_RETURN(m_queryType != DATE || (uint64_t)m_end == Null<uint64_t>(), Null<Datetime>());
    uint64_t number = (uint64_t)(m_end / 100);
    Datetime d(number);
    return Datetime(d.year(), d.month(), d.day(), d.hour(), d.minute(), m_end - number * 100);
}

string KQuery::getQueryTypeName(QueryType queryType) {
    switch (queryType) {
        case INDEX:
            return "INDEX";
        case DATE:
            return "DATE";
        default:
            return "INVALID";
    }
}

KQuery::QueryType KQuery::getQueryTypeEnum(const string& arg) {
    string name(arg);
    to_upper(name);
    HKU_IF_RETURN("INDEX" == name, INDEX);
    HKU_IF_RETURN("DATE" == name, DATE);
    return INVALID;
}

string KQuery::getKTypeName(KType dataType) {
    string result(dataType);
    to_upper(result);
    return result;
}

KQuery::KType KQuery::getKTypeEnum(const string& arg) {
    string name(arg);
    to_upper(name);
    return name;
}

string KQuery::getRecoverTypeName(RecoverType recoverType) {
    switch (recoverType) {
        case NO_RECOVER:
            return "NO_RECOVER";
        case FORWARD:
            return "FORWARD";
        case BACKWARD:
            return "BACKWARD";
        case EQUAL_FORWARD:
            return "EQUAL_FORWARD";
        case EQUAL_BACKWARD:
            return "EQUAL_BACKWARD";
        default:
            return "INVALID_RECOVER_TYPE";
    }
}

KQuery::RecoverType KQuery::getRecoverTypeEnum(const string& arg) {
    string name(arg);
    to_upper(name);
    HKU_IF_RETURN("NO_RECOVER" == name, NO_RECOVER);
    HKU_IF_RETURN("FORWARD" == name, FORWARD);
    HKU_IF_RETURN("BACKWARD" == name, BACKWARD);
    HKU_IF_RETURN("EQUAL_FORWARD" == name, EQUAL_FORWARD);
    HKU_IF_RETURN("EQUAL_BACKWARD" == name, EQUAL_BACKWARD);
    return INVALID_RECOVER_TYPE;
}

HKU_API std::ostream& operator<<(std::ostream& os, const KQuery& query) {
    string strip(", ");
    if (query.queryType() == KQuery::INDEX) {
        os << "KQuery(" << query.start() << strip << query.end() << strip
           << KQuery::getQueryTypeName(query.queryType()) << strip
           << KQuery::getKTypeName(query.kType()) << strip
           << KQuery::getRecoverTypeName(query.recoverType()) << ")";
    } else {
        os << "KQueryByDate(" << query.startDatetime() << strip << query.endDatetime() << strip
           << KQuery::getQueryTypeName(query.queryType()) << strip
           << KQuery::getKTypeName(query.kType()) << strip
           << KQuery::getRecoverTypeName(query.recoverType()) << ")";
    }
    return os;
}

}  // namespace hku

max_stars_repo_name: scanfyu/hikyuu

max_issues_repo_name: scanfyu/hikyuu

max_forks_repo_name: scanfyu/hikyuu


text:
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;

template <class Matrix>

// The auxiliary function Atimesx computes the function A*x in a smart way, using the particular structure of the matrix A.

void Atimesx(const Matrix & d, const Matrix & a, const Matrix & x, Matrix & Ax)
{
    int n=d.size();
    Ax=(d.array()*x.array()).matrix();
    VectorXd Axcut=Ax.head(n-1);
    VectorXd acut = a.head(n-1);
    VectorXd xcut = x.head(n-1);

    Ax << Axcut + x(n-1)*acut, Ax(n-1)+ acut.transpose()*xcut;
}

// We compute A*A*x by using the function Atimesx twice with 5 dimensional random vectors.

int main(void)
{
    VectorXd a=VectorXd::Random(5);
    VectorXd d=VectorXd::Random(5);
    VectorXd x=VectorXd::Random(5);
    VectorXd Ax(5);

    Atimesx(d,a,x,Ax);
    VectorXd AAx(5);
    Atimesx(d,a,Ax,AAx);
    std::cout << "A*A*x = " << AAx << std::endl;
}

max_stars_repo_path: Nummerical Methods for CSE/PS1/solutions_ps1/C++/arrowmatvec2.cpp

max_stars_repo_name: valentinjacot/backupETHZ

max_issues_repo_name: valentinjacot/backupETHZ

max_forks_repo_name: valentinjacot/backupETHZ


text:
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// See LICENSE file in the project root for full license information.
//
#include "Profiling.hpp"

#if ARMNN_PROFILING_ENABLED

#if ARMNN_STREAMLINE_ENABLED
#include <streamline_annotate.h>
#endif

#if ARMCOMPUTECL_ENABLED
#include <arm_compute/runtime/CL/CLFunctions.h>
#endif

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <stack>
#include <boost/algorithm/string.hpp>

namespace armnn
{

// Controls the amount of memory initially allocated to store profiling events.
// If chosen carefully, the profiling system will not make any additional allocations, thus minimizing its impact on
// measured times.
constexpr std::size_t g_ProfilingEventCountHint = 1024;

// Whether profiling reports should include the sequence of events together with their timings.
constexpr bool g_WriteProfilingEventSequence = true;

// Whether profiling reports should also report detailed information on events grouped by tag.
// This is used to group stats per inference (see usage of ARMNN_UPDATE_PROFILING_EVENT_TAG in
// Runtime::EnqueueWorkload). This can spam the output stream, so use carefully (or adapt
// the code to just output information for a tag of interest).
constexpr bool g_AggregateProfilingEventsByTag = false;

// Whether a call to Profiler::AnalyzeEventsAndWriteResults() will be made when the Profiler
// singleton is destroyed. It can be convenient for local tests.
constexpr bool g_WriteReportToStdOutOnProfilerDestruction = true;

// Whether events denoting operations running on the GPU should force a sync before/after the event.
// This is hardcoded to true for now as the profiling timings are not very useful without it.
constexpr bool g_ProfilingForceGpuSync = true;

std::map<std::string, Profiler::ProfilingEventStats> Profiler::CalculateProfilingEventStats() const
{
    std::map<std::string, ProfilingEventStats> nameToStatsMap;

    for (auto&& event : m_EventSequence)
    {
        auto mapIter = nameToStatsMap.find(event.m_Label);
        if (mapIter != nameToStatsMap.end())
        {
            ProfilingEventStats& stats = mapIter->second;
            stats.m_TotalMs += event.DurationMs();
            stats.m_MinMs = std::min(stats.m_MinMs, event.DurationMs());
            stats.m_MaxMs = std::max(stats.m_MaxMs, event.DurationMs());
            ++stats.m_Count;
        }
        else
        {
            ProfilingEventStats stats;
            stats.m_TotalMs = event.DurationMs();
            stats.m_MinMs = event.DurationMs();
            stats.m_MaxMs = event.DurationMs();
            stats.m_Count = 1;

            nameToStatsMap[event.m_Label] = stats;
        }
    }

    return nameToStatsMap;
}

void Profiler::AnalyzeEventSequenceAndWriteResults(std::vector<ProfilingEvent>::const_iterator first,
                                                   std::vector<ProfilingEvent>::const_iterator last,
                                                   std::ostream& outStream) const
{
    // Output event sequence, if needed
    if (g_WriteProfilingEventSequence)
    {
        // Make sure timestamps are output with 6 decimals, and save old settings
        std::streamsize oldPrecision = outStream.precision();
        outStream.precision(6);
        std::ios_base::fmtflags oldFlags = outStream.flags();
        outStream.setf(std::ios::fixed);
        // Output fields
        outStream << "Event Sequence - Name | Duration (ms) | Start (ms) | Stop (ms) | Device" << std::endl;
        for (auto event = first; event != last; ++event)
        {
            std::chrono::duration<double, std::milli> startTimeMs = event->m_StartTime.time_since_epoch();
            std::chrono::duration<double, std::milli> stopTimeMs = event->m_StopTime.time_since_epoch();

            outStream << std::setw(50) << event->m_Label << " "
                << std::setw(20) << event->DurationMs()
                << std::setw(20) << startTimeMs.count()
                << std::setw(20) << stopTimeMs.count()
                << std::setw(20) << Profiler::Get().GetEventComputeDevice(event->m_Device)
                << std::endl;
        }
        outStream << std::endl;
        // Restore previous precision settings
        outStream.flags(oldFlags);
        outStream.precision(oldPrecision);
    }

    // Aggregate results per event name
    std::map<std::string, ProfilingEventStats> nameToStatsMap = CalculateProfilingEventStats();

    // Output aggregated stats
    outStream << "Event Stats - Name | Avg (ms) | Min (ms) | Max (ms) | Total (ms) | Count" << std::endl;
    for (const auto& pair : nameToStatsMap)
    {
        const std::string& eventLabel = pair.first;
        const ProfilingEventStats& eventStats = pair.second;
        const double avgMs = eventStats.m_TotalMs / double(eventStats.m_Count);

        outStream << "\t" << std::setw(50) << eventLabel << " " << std::setw(9) << avgMs << " "
            << std::setw(9) << eventStats.m_MinMs << " " << std::setw(9) << eventStats.m_MaxMs << " "
            << std::setw(9) << eventStats.m_TotalMs << " " << std::setw(9) << eventStats.m_Count << std::endl;
    }
    outStream << std::endl;
}

Profiler Profiler::s_Instance;

Profiler::Profiler()
    : m_EventTag(0)
    , m_NestingLevel(0)
    , m_EventTagUpdated(false)
{
    m_EventSequence.reserve(g_ProfilingEventCountHint);

#if ARMNN_STREAMLINE_ENABLED
    // Initialise streamline annotations
    ANNOTATE_SETUP;
#endif
}

Profiler::~Profiler()
{
    if (g_WriteReportToStdOutOnProfilerDestruction)
    {
        AnalyzeEventsAndWriteResults(std::cout);
    }
}

void Profiler::BeginEvent(Compute compute, const std::string label)
{
    // We need to sync just before the begin event to not include time before the period we want to time.
    WaitForDevice(compute);

    const TimePoint timeStamp = Clock::now();
    m_ObservedMarkers.emplace(Marker{m_EventSequence.size(), label, timeStamp, compute, m_EventTag});
    m_EventSequence.emplace_back();

#if ARMNN_STREAMLINE_ENABLED
    ANNOTATE_CHANNEL_COLOR(m_NestingLevel, GetEventColor(compute), label.c_str());
#endif

    m_NestingLevel++;
}

void Profiler::EndEvent(Compute compute)
{
    // We need to sync just before the end event to include all the time of the timed period.
    WaitForDevice(compute);

    const Marker& marker = m_ObservedMarkers.top();

    const TimePoint startTime = marker.m_TimeStamp;
    const TimePoint stopTime = Clock::now();

    m_EventSequence[marker.m_Id] = {std::move(marker.m_EventName),
                                    startTime,
                                    stopTime,
                                    marker.m_ComputeDevice,
                                    marker.m_Tag};

    m_ObservedMarkers.pop();

#if ARMNN_STREAMLINE_ENABLED
    ANNOTATE_CHANNEL_END(m_NestingLevel);
#endif

    m_NestingLevel--;
}

void Profiler::AnalyzeEventsAndWriteResults(std::ostream& outStream) const
{
    // Stack should be empty now.
    const bool saneMarkerSequence = m_ObservedMarkers.empty();

    // Abort if the sequence of markers was found to have incorrect information:
    // The stats cannot be trusted.
    if (!saneMarkerSequence)
    {
        outStream << "Cannot write profiling stats. "
            "Unexpected errors were found when analyzing the sequence of logged events, which may lead to plainly "
            "wrong stats. The profiling system may contain implementation issues or could have been used in an "
            "unsafe manner." << std::endl;
        return;
    }

    // Analyze the full sequence of events
    AnalyzeEventSequenceAndWriteResults(m_EventSequence.begin(), m_EventSequence.end(), outStream);

    // Aggregate events by tag if requested (spams the output stream if done for all tags)
    if (m_EventTagUpdated && g_AggregateProfilingEventsByTag)
    {
        outStream << std::endl;
        outStream << "***" << std::endl;
        outStream << "*** Per Tag Stats" << std::endl;
        outStream << "***" << std::endl;
        outStream << std::endl;

        for (auto iter = m_EventSequence.begin(); iter != m_EventSequence.end();)
        {
            const uint32_t tag = iter->m_Tag;

            // Advance iter until we find the first non-matching tag
            auto tagEndIter = iter;
            for (; tagEndIter != m_EventSequence.end(); ++tagEndIter)
            {
                if (tagEndIter->m_Tag != tag)
                {
                    break;
                }
            }

            outStream << "> Begin Tag: " << tag << std::endl;
            outStream << std::endl;
            AnalyzeEventSequenceAndWriteResults(iter, tagEndIter, outStream);
            outStream << std::endl;
            outStream << "> End Tag: " << tag << std::endl;

            iter = tagEndIter;
        }
    }
}

void Profiler::WaitForDevice(Compute compute) const
{
#if ARMCOMPUTECL_ENABLED
    if(compute == Compute::GpuAcc && g_ProfilingForceGpuSync)
    {
        arm_compute::CLScheduler::get().sync();
    }
#endif
}

const char* Profiler::GetEventComputeDevice(Compute compute) const
{
    switch(compute)
    {
        case Compute::CpuRef:
            return "CpuRef";
        case Compute::CpuAcc:
            return "CpuAcc";
        case Compute::GpuAcc:
            return "GpuAcc";
        default:
            return "Undefined";
    }
}

std::uint32_t Profiler::GetEventColor(Compute compute) const
{
    switch(compute)
    {
        case Compute::CpuRef:
            // Cyan
            return 0xffff001b;
        case Compute::CpuAcc:
            // Green
            return 0x00ff001b;
        case Compute::GpuAcc:
            // Purple
            return 0xff007f1b;
        default:
            // Dark gray
            return 0x5555551b;
    }
}

} // namespace armnn

#endif // ARMNN_PROFILING_ENABLED


text:
// Copyright (C) 2005 Arkadiy Vertleyb, Peder Holt.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_TYPEOF_STD_map_hpp_INCLUDED
#define BOOST_TYPEOF_STD_map_hpp_INCLUDED

#include <map>
#include <boost/typeof/typeof.hpp>
#include <boost/typeof/std/memory.hpp>
#include <boost/typeof/std/functional.hpp>
#include <boost/typeof/std/utility.hpp>

#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()

BOOST_TYPEOF_REGISTER_TEMPLATE(std::map, 2)
BOOST_TYPEOF_REGISTER_TEMPLATE(std::map, 3)
BOOST_TYPEOF_REGISTER_TEMPLATE(std::map, 4)
BOOST_TYPEOF_REGISTER_TEMPLATE(std::multimap, 2)
BOOST_TYPEOF_REGISTER_TEMPLATE(std::multimap, 3)
BOOST_TYPEOF_REGISTER_TEMPLATE(std::multimap, 4)

#endif//BOOST_TYPEOF_STD_map_hpp_INCLUDED

max_stars_repo_name: randolphwong/mcsema

max_issues_repo_name: randolphwong/mcsema

max_forks_repo_name: randolphwong/mcsema


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.

// This file was modified by Oracle on 2013.
// Modifications copyright (c) 2013, Oracle and/or its affiliates.

// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.

// Use, modification and distribution is subject to 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)

#ifndef BOOST_GEOMETRY_MULTI_HPP
#define BOOST_GEOMETRY_MULTI_HPP

#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/geometry_id.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/is_areal.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/topological_dimension.hpp>

#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/area.hpp>
#include <boost/geometry/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/distance.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/for_each.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/algorithms/length.hpp>
#include <boost/geometry/algorithms/num_geometries.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/perimeter.hpp>
#include <boost/geometry/algorithms/remove_spikes.hpp>
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/algorithms/simplify.hpp>
#include <boost/geometry/algorithms/transform.hpp>
#include <boost/geometry/algorithms/unique.hpp>
#include <boost/geometry/algorithms/within.hpp>

#include <boost/geometry/algorithms/detail/point_on_border.hpp>

#include <boost/geometry/algorithms/detail/for_each_range.hpp>
#include <boost/geometry/algorithms/detail/multi_modify_with_predicate.hpp>
#include <boost/geometry/algorithms/detail/multi_sum.hpp>

#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>

#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
#include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>

#include <boost/geometry/geometries/concepts/check.hpp>

#include <boost/geometry/views/detail/range_type.hpp>
#include <boost/geometry/strategies/cartesian/centroid_average.hpp>

#include <boost/geometry/io/dsv/write.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>

#endif // BOOST_GEOMETRY_MULTI_HPP

max_stars_repo_name: multi-os-engine/cinder-natj-binding

max_issues_repo_name: multi-os-engine/cinder-natj-binding

max_forks_repo_name: multi-os-engine/cinder-natj-binding