text:
/*
 * @brief sim_loc_driver_check_thread implements a thread to check
 * sim_loc_driver messages against configured min and max values.
 *
 * This way a scene specific plausibility check of sim_loc_driver messages
 * can be performed when running automated tests against localization controllers
 * like SIM1000FXA. A warning will be logged in case of failures or values out of
 * range.
 *
 * Copyright (C) 2019 Ing.-Buero Dr. Michael Lehning, Hildesheim
 * Copyright (C) 2019 SICK AG, Waldkirch
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of SICK AG nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission
 *     * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *      Authors:
 *         Michael Lehning <michael.lehning@lehning.de>
 *
 *  Copyright 2019 SICK AG
 *  Copyright 2019 Ing.-Buero Dr. Michael Lehning
 *
 */
#include <algorithm>
#include <ros/ros.h>
#include <boost/algorithm/clamp.hpp>

#include "sick_lidar_localization/driver_check_thread.h"
#include "sick_lidar_localization/utils.h"

/*
 * Constructor, reads the configuration parameter incl. the
 * min and max allowed values in sim_loc_driver messages.
 */
sick_lidar_localization::MessageCheckThread::MessageCheckThread()
: m_message_check_thread_running(false), m_message_check_thread(0), m_message_check_frequency(100)
{
  // Read configuation
  int software_pll_fifo_length = 7, time_sync_initial_length = 10;
  double time_sync_rate = 0.1, time_sync_initial_rate = 1.0;
  ros::param::param<double>("/sick_lidar_localization/sim_loc_driver_check/message_check_frequency", m_message_check_frequency, m_message_check_frequency);
  ros::param::param<int>("/sick_lidar_localization/time_sync/software_pll_fifo_length", software_pll_fifo_length, software_pll_fifo_length);
  ros::param::param<double>("/sick_lidar_localization/time_sync/time_sync_rate", time_sync_rate, time_sync_rate);
  ros::param::param<double>("/sick_lidar_localization/time_sync/time_sync_initial_rate", time_sync_initial_rate, time_sync_initial_rate);
  ros::param::param<int>("/sick_lidar_localization/time_sync/time_sync_initial_length", time_sync_initial_length, time_sync_initial_length);
  assert(software_pll_fifo_length > 0 && time_sync_rate > FLT_EPSILON);
  m_software_pll_expected_initialization_duration = (software_pll_fifo_length / time_sync_initial_rate + 1); // expected initialization time for software pll (system time from lidar ticks not yet available)
  // Read min allowed values in a result port telegrams
  m_result_port_telegram_min_values = readYamlResultPortTelegram("/sick_lidar_localization/sim_loc_driver_check/result_telegram_min_values");
  m_result_port_telegram_min_values.vehicle_time_valid = false;
  m_result_port_telegram_min_values.vehicle_time_sec = 0;
  m_result_port_telegram_min_values.vehicle_time_nsec = 0;
  ros::param::param<double>("/sick_lidar_localization/sim_loc_driver_check/result_telegram_min_values/vehicle_time_delta", m_vehicle_time_delta_min, -1.0);
  ros::param::param<bool>("/sick_lidar_localization/sim_loc_driver_check/result_telegram_min_values/check_vehicle_time", m_vehicle_time_check_enabled, true);
  // Read max allowed values in a result port telegrams
  m_result_port_telegram_max_values = readYamlResultPortTelegram("/sick_lidar_localization/sim_loc_driver_check/result_telegram_max_values");
  m_result_port_telegram_max_values.vehicle_time_valid = true;
  m_result_port_telegram_max_values.vehicle_time_sec = UINT32_MAX;
  m_result_port_telegram_max_values.vehicle_time_nsec = UINT32_MAX;
  ros::param::param<double>("/sick_lidar_localization/sim_loc_driver_check/result_telegram_max_values/vehicle_time_delta", m_vehicle_time_delta_max, 1.0);
  ros::param::param<bool>("/sick_lidar_localization/sim_loc_driver_check/result_telegram_max_values/check_vehicle_time", m_vehicle_time_check_enabled, true);
  ROS_INFO_STREAM("MessageCheckThread: min allowed values in result port telegrams: " << sick_lidar_localization::Utils::flattenToString(m_result_port_telegram_min_values));
  ROS_INFO_STREAM("MessageCheckThread: max allowed values in result port telegrams: " << sick_lidar_localization::Utils::flattenToString(m_result_port_telegram_max_values));
}

/*
 * Destructor
 */
sick_lidar_localization::MessageCheckThread::~MessageCheckThread()
{
  stop();
}

/*
 * Starts the sim_loc_driver message check thread.
 * @return true on success, false on failure.
 */
bool sick_lidar_localization::MessageCheckThread::start(void)
{
  m_message_check_thread_running = true;
  m_message_check_thread = new boost::thread(&sick_lidar_localization::MessageCheckThread::runMessageCheckThreadCb, this);
  return true;
}

/*
 * Stops the sim_loc_driver message check thread.
 * @return true on success, false on failure.
 */
bool sick_lidar_localization::MessageCheckThread::stop(void)
{
  m_message_check_thread_running = false;
  if(m_message_check_thread)
  {
    m_message_check_thread->join();
    delete(m_message_check_thread);
    m_message_check_thread = 0;
  }
  return true;
}

/*
 * Callback for result telegram messages (SickLocResultPortTelegramMsg) from sim_loc_driver.
 * @param[in] msg result telegram message (SickLocResultPortTelegramMsg)
 */
void sick_lidar_localization::MessageCheckThread::messageCbResultPortTelegrams(const sick_lidar_localization::SickLocResultPortTelegramMsg & msg)
{
  m_result_port_telegram_fifo.push(msg);
}

/*
 * Thread callback, checks sim_loc_driver messages in m_result_port_telegram_fifo
 * against min and max values.
 */
void sick_lidar_localization::MessageCheckThread::runMessageCheckThreadCb(void)
{
  ROS_INFO_STREAM("MessageCheckThread: thread to check sim_loc_driver messages started");
  size_t total_message_check_cnt = 0, total_message_check_failed_cnt = 0;
  while(ros::ok() && m_message_check_thread_running)
  {
    while(ros::ok() && m_message_check_thread_running && m_result_port_telegram_fifo.empty())
    {
      ros::Duration(1.0 / m_message_check_frequency).sleep();
    }
    if(ros::ok() && m_message_check_thread_running && !m_result_port_telegram_fifo.empty())
    {
      // Check sim_loc_driver message
      sick_lidar_localization::SickLocResultPortTelegramMsg result_port_telegram = m_result_port_telegram_fifo.pop();
      total_message_check_cnt++;
      if (!checkTelegram(result_port_telegram))
      {
        ROS_WARN_STREAM("## ERROR MessageCheckThread: driver message check failed (" << total_message_check_cnt << ". driver message)");
        ROS_WARN_STREAM("## driver message (received): " << sick_lidar_localization::Utils::flattenToString(result_port_telegram));
        ROS_WARN_STREAM("## MessageCheckThread: min allowed values in result port telegrams: " << sick_lidar_localization::Utils::flattenToString(m_result_port_telegram_min_values));
        ROS_WARN_STREAM("## MessageCheckThread: max allowed values in result port telegrams: " << sick_lidar_localization::Utils::flattenToString(m_result_port_telegram_max_values));
        total_message_check_failed_cnt++;
      }
      else
      {
        ROS_DEBUG_STREAM("MessageCheckThread: " << total_message_check_cnt << ". driver message checked, okay");
        ROS_DEBUG_STREAM("MessageCheckThread: driver message (received): " << sick_lidar_localization::Utils::flattenToString(result_port_telegram));
      }
    }
  }
  ROS_INFO_STREAM("MessageCheckThread: thread to check sim_loc_driver messages finished");
  std::stringstream info_msg;
  info_msg << "MessageCheckThread: check messages thread summary: " << total_message_check_cnt << " messages checked, " << total_message_check_failed_cnt << " failures.";
  if(ros::ok())
    ROS_INFO_STREAM(info_msg.str());
  else
    std::cout << info_msg.str() << std::endl;
}

/*
 * Reads and returns a result port telegram from yaml configuration file.
 * @param[in] param_section section name in yaml configuration file, f.e. "/sick_lidar_localization/sim_loc_driver_check/result_telegram_min_values"
 * @return result port telegram with values initialized from yaml file.
 */
sick_lidar_localization::SickLocResultPortTelegramMsg sick_lidar_localization::MessageCheckThread::readYamlResultPortTelegram(const std::string param_section)
{
  int i_value = 0;
  double d_value = 0;
  std::vector<int> i_vec;
  std::vector<uint8_t> u8_vec;
  sick_lidar_localization::SickLocResultPortTelegramMsg telegram;

  // Default values, can be overwritten by parameter settings
  telegram.vehicle_time_valid = false;
  telegram.vehicle_time_sec = 0;
  telegram.vehicle_time_nsec = 0;

  // Read ros header
  ros::param::param<double>(param_section+"/header/seq", d_value, 0);
  telegram.header.seq = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // sequence ID, consecutively increasing ID, uint32, size:= 4 byte
  ros::param::param<double>(param_section+"/header/stamp", d_value, 0);
  telegram.header.stamp = ros::Time(d_value); // time stamp
  ros::param::param<std::string>(param_section+"/header/frame_id", telegram.header.frame_id, "");

  // Read telegram header, 52 byte
  ros::param::param<int>(param_section+"/telegram_header/MagicWord", i_value, 0x5349434B);
  telegram.telegram_header.MagicWord = (uint32_t)i_value; // Magic word SICK (0x53 0x49 0x43 0x4B). uint32, size:= 4 × UInt8 = 4 byte
  ros::param::param<int>(param_section+"/telegram_header/Length", i_value, 106);
  telegram.telegram_header.Length = (uint32_t)i_value; // Length of telegram incl. header, payload, and trailer. uint32, size:= UInt32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_header/PayloadType", i_value, 0x0642);
  telegram.telegram_header.PayloadType = (uint16_t)i_value; // Payload type, 0x06c2 = Little Endian, 0x0642 = Big Endian. uint16, size:= UInt16 = 2 byte
  ros::param::param<int>(param_section+"/telegram_header/PayloadVersion", i_value, 1);
  telegram.telegram_header.PayloadVersion = (uint16_t)i_value; // Version of PayloadType structure. uint16, size:= UInt16 = 2 byte
  ros::param::param<double>(param_section+"/telegram_header/OrderNumber", d_value, 0);
  telegram.telegram_header.OrderNumber = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // Order number of the localization controller. uint32, size:= UInt32 = 4 byte
  ros::param::param<double>(param_section+"/telegram_header/SerialNumber", d_value, 0);
  telegram.telegram_header.SerialNumber = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // Serial number of the localization controller. uint32, size:= UInt32 = 4 byte
  ros::param::param<std::vector<int>>(param_section+"/telegram_header/FW_Version", i_vec, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0});
  u8_vec.reserve(i_vec.size());
  for(size_t n = 0; n < i_vec.size(); n++)
    u8_vec.push_back(i_vec[n]);
  telegram.telegram_header.FW_Version = u8_vec; // Software version of the localization controller. uint8[], size:= 20 × UInt8 = 20 byte
  ros::param::param<double>(param_section+"/telegram_header/TelegramCounter", d_value, 0);
  telegram.telegram_header.TelegramCounter = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // Telegram counter since last start-up. uint32, size:= UInt32 = 4 byte
  ros::param::param<double>(param_section+"/telegram_header/SystemTime", d_value, 0);
  telegram.telegram_header.SystemTime = ((d_value <= 0)?0:((d_value >= 0xFFFFFFFFFFFFFFFF)?0xFFFFFFFFFFFFFFFF:(uint64_t)(d_value))); // Not used. uint64, size:= NTP = 8 byte

  // Read telegram payload, 52 byte
  ros::param::param<int>(param_section+"/telegram_payload/ErrorCode", i_value, 0);
  telegram.telegram_payload.ErrorCode = (uint16_t)i_value; // ErrorCode 0:= OK, ErrorCode 1:= UNKNOWNERROR. uint16, size:= UInt16 = 2 byte
  ros::param::param<double>(param_section+"/telegram_payload/ScanCounter", d_value, 0);
  telegram.telegram_payload.ScanCounter = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // Counter of related scan data. uint32, size:= UInt32 = 4 byte
  ros::param::param<double>(param_section+"/telegram_payload/Timestamp", d_value, 0);
  telegram.telegram_payload.Timestamp = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // Time stamp of the pose [ms]. The time stamp indicates the time at which the pose is calculated. uint32, size:= UInt32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/PoseX", telegram.telegram_payload.PoseX, 0); // Position X of the vehicle on the map in cartesian global coordinates [mm]. int32, size:= Int32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/PoseY", telegram.telegram_payload.PoseY, 0); // Position Y of the vehicle on the map in cartesian global coordinates [mm]. int32, size:= Int32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/PoseYaw", telegram.telegram_payload.PoseYaw, 0); // Orientation (yaw) of the vehicle on the map [mdeg]. int32, size:= Int32 = 4 byte
  ros::param::param<double>(param_section+"/telegram_payload/Reserved1", d_value, 0);
  telegram.telegram_payload.Reserved1 = (uint32_t)boost::algorithm::clamp<double>(d_value, 0, 0xFFFFFFFF); // Reserved. uint32, size:= UInt32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/Reserved2", telegram.telegram_payload.Reserved2, 0); // Reserved. int32, size:= Int32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/Quality", i_value, 0);
  telegram.telegram_payload.Quality = (uint8_t)i_value; // Quality of pose [0 … 100], 1 = bad pose quality, 100 = good pose quality. uint8, size:= UInt8 = 1 byte
  ros::param::param<int>(param_section+"/telegram_payload/OutliersRatio", i_value, 0);
  telegram.telegram_payload.OutliersRatio = (uint8_t)i_value; // Ratio of beams that cannot be assigned to the current reference map [%]. uint8, size:= UInt8 = 1 byte
  ros::param::param<int>(param_section+"/telegram_payload/CovarianceX", telegram.telegram_payload.CovarianceX, 0); // Covariance c1 of the pose X [mm^2]. int32, size:= Int32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/CovarianceY", telegram.telegram_payload.CovarianceY, 0); // Covariance c5 of the pose X [mm^2]. int32, size:= Int32 = 4 byte
  ros::param::param<int>(param_section+"/telegram_payload/CovarianceYaw", telegram.telegram_payload.CovarianceYaw, 0); // Covariance c9 of the pose Yaw [mdeg^2]. int32, size:= Int32 = 4 byte
  ros::param::param<double>(param_section+"/telegram_payload/Reserved3", d_value, 0);
  telegram.telegram_payload.Reserved3 = ((d_value <= 0)?0:((d_value >= 0xFFFFFFFFFFFFFFFF)?0xFFFFFFFFFFFFFFFF:(uint64_t)(d_value))); // Reserved. uint64, size:= UInt64 = 8 byte

  // Read telegram trailer, 2 byte
  ros::param::param<int>(param_section+"/telegram_trailer/Checksum", i_value, 0);
  telegram.telegram_trailer.Checksum = (uint16_t)i_value; // CRC16-CCITT checksum

  return telegram;
}

/** Shortcut to check a value against min and max values, returns (telegram.key >= mintelegram.key && telegram.key <= maxtelegram.key) */
#define CHECK_TELEGRAM_VALUE(key,telegram,mintelegram,maxtelegram) ((telegram.key) >= (mintelegram.key) && (telegram.key <= maxtelegram.key))

/** Shortcut to check an array of values against min and max values, returns (telegram.key >= mintelegram.key && telegram.key <= maxtelegram.key) for each element in telegram.key */
#define CHECK_TELEGRAM_ARRAY(key,telegram,mintelegram,maxtelegram) (checkTelegramArray((telegram.key), (mintelegram.key), (maxtelegram.key)))

/** Shortcut to check an array of values against min and max values, returns (telegram.key >= mintelegram.key && telegram.key <= maxtelegram.key) for each element */
template<typename T> bool checkTelegramArray(const T & value, const T & min_value, const T & max_value)
{
  if(value.size() != min_value.size() || value.size() != max_value.size())
    return false;
  for(size_t n = 0; n < value.size(); n++)
  {
    if(!(value[n] >= min_value[n] && value[n] <= max_value[n]))
      return false;
  }
  return true;
}

/*
 * Checks a result telegram messages (SickLocResultPortTelegramMsg) against min and max values.
 * Returns true, if test passed (all values within their ranges), or false otherwise.
 * @param[in] telegram result telegram message (SickLocResultPortTelegramMsg)
 * @return true, if test passed, false otherwise.
 */
bool sick_lidar_localization::MessageCheckThread::checkTelegram(sick_lidar_localization::SickLocResultPortTelegramMsg & telegram)
{
  return
    // Check ros header
    CHECK_TELEGRAM_VALUE(header.seq, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(header.stamp, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_ARRAY(header.frame_id, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    // Check telegram header, 52 byte
    CHECK_TELEGRAM_VALUE(telegram_header.MagicWord, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.Length, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.PayloadType, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.PayloadVersion, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.OrderNumber, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.SerialNumber, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_ARRAY(telegram_header.FW_Version, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.TelegramCounter, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_header.SystemTime, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    // Check telegram payload, 52 byte
    CHECK_TELEGRAM_VALUE(telegram_payload.ErrorCode, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.ScanCounter, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.Timestamp, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.PoseX, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.PoseY, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.PoseYaw, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.Reserved1, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.Reserved2, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.Quality, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.OutliersRatio, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.CovarianceX, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.CovarianceY, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.CovarianceYaw, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
    CHECK_TELEGRAM_VALUE(telegram_payload.Reserved3, telegram, m_result_port_telegram_min_values, m_result_port_telegram_max_values) &&
      (!m_vehicle_time_check_enabled || checkVehicleTime(telegram)); // Check vehicle time (system time from ticks by software pll), if enabled by default
}

/*
 * Checks the vehicle time of a result telegram message (system time from ticks by software pll) against min and max
 * allowed difference to ros::Time::now(). Returns true, if test passed (vehicle time  within their range), or false otherwise.
 * @param[in] telegram result telegram message (SickLocResultPortTelegramMsg)
 * @return true, if test passed, false otherwise.
 */

bool sick_lidar_localization::MessageCheckThread::checkVehicleTime(sick_lidar_localization::SickLocResultPortTelegramMsg & telegram)
{
  if(m_timestamp_valid_telegram.sec <= 0)
    m_timestamp_valid_telegram = ros::Time::now();
  if(telegram.vehicle_time_valid)
  {
    m_timestamp_valid_telegram = ros::Time::now();
    ros::Time message_time(telegram.header.stamp.sec, telegram.header.stamp.nsec);
    ros::Time vehicle_time(telegram.vehicle_time_sec,telegram.vehicle_time_nsec);
    ros::Duration delta_time = message_time - vehicle_time;
    return delta_time.toSec() >= m_vehicle_time_delta_min && delta_time.toSec() <= m_vehicle_time_delta_max;
  }
  else if((ros::Time::now() - m_timestamp_valid_telegram).toSec() <= m_software_pll_expected_initialization_duration // software pll is initializing
  || (std::abs(m_vehicle_time_delta_min) >= FLT_MAX && std::abs(m_vehicle_time_delta_max) >= FLT_MAX)) // checkVehicleTime disabled for error simulation (unreachable controller etc.)
  {
    return true; // software pll initializing, system time from lidar ticks not yet available
  }
  return false; // vehicle time out of range
}


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 2018-2020.
// Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

// 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_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP

#include <boost/array.hpp>
#include <boost/core/ignore_unused.hpp>

#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>

#include <boost/geometry/algorithms/assign.hpp>

#include <boost/geometry/strategies/side.hpp>

#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp>

namespace boost { namespace geometry { namespace strategy
{

namespace within
{

#ifndef DOXYGEN_NO_DETAIL
namespace detail
{

struct decide_within
{
    static inline bool apply(int side, bool& result)
    {
        if (side != 1)
        {
            result = false;
            return false;
        }
        return true; // continue
    }
};

struct decide_covered_by
{
    static inline bool apply(int side, bool& result)
    {
        if (side != 1)
        {
            result = side >= 0;
            return false;
        }
        return true; // continue
    }
};

// WARNING
// This strategy is not suitable for boxes in non-cartesian CSes having edges
// longer than 180deg because e.g. the SSF formula picks the side of the closer
// longitude, so for long edges the side is the opposite.
// Actually it is not suitable for shorter edges either because the edges of
// boxes are defined by meridians and parallels, not great circles or geodesics.
template <typename Decide, typename Point, typename Box, typename Strategy>
inline bool point_in_box_by_side(Point const& point, Box const& box,
                                 Strategy const& strategy)
{
    boost::ignore_unused(strategy);

    // Create (counterclockwise) array of points, the fifth one closes it
    // Every point should be on the LEFT side (=1), or ON the border (=0),
    // So >= 1 or >= 0
    boost::array<typename point_type<Box>::type, 5> bp;
    geometry::detail::assign_box_corners_oriented<true>(box, bp);
    bp[4] = bp[0];

    bool result = true;
    for (int i = 1; i < 5; i++)
    {
        int const side = strategy.apply(point, bp[i - 1], bp[i]);
        if (! Decide::apply(side, result))
        {
            return result;
        }
    }

    return result;
}

} // namespace detail
#endif // DOXYGEN_NO_DETAIL

// There should probably be another category of geometry different than box,
// e.g. rectangle or convex_ring. This strategy should probably be an
// algorithm calling side strategy.

template <typename CalculationType = void>
struct cartesian_point_box_by_side
{
    template <typename Point, typename Box>
    static inline bool apply(Point const& point, Box const& box)
    {
        using side_strategy_type
            = typename strategy::side::services::default_strategy
                <cartesian_tag, CalculationType>::type;

        return within::detail::point_in_box_by_side
            <
                within::detail::decide_within
            >(point, box, side_strategy_type());
    }
};

template <typename CalculationType = void>
struct spherical_point_box_by_side
{
    template <typename Point, typename Box>
    static inline bool apply(Point const& point, Box const& box)
    {
        return within::detail::point_in_box_by_side
            <
                within::detail::decide_within
            >(point, box,
              strategy::side::spherical_side_formula<CalculationType>());
    }
};

template
<
    typename FormulaPolicy = strategy::andoyer,
    typename Spheroid = srs::spheroid<double>,
    typename CalculationType = void
>
struct geographic_point_box_by_side
{
    geographic_point_box_by_side() = default;

    explicit geographic_point_box_by_side(Spheroid const& spheroid)
        : m_side(spheroid)
    {}

    template <typename Point, typename Box>
    bool apply(Point const& point, Box const& box) const
    {
        return within::detail::point_in_box_by_side
            <
                within::detail::decide_within
            >(point, box, m_side);
    }

    Spheroid const& model() const
    {
        return m_side.model();
    }

private:
    strategy::side::geographic
        <
            FormulaPolicy, Spheroid, CalculationType
        > m_side;
};

} // namespace within

namespace covered_by
{

template <typename CalculationType = void>
struct cartesian_point_box_by_side
{
    template <typename Point, typename Box>
    static bool apply(Point const& point, Box const& box)
    {
        using side_strategy_type
            = typename strategy::side::services::default_strategy
                <cartesian_tag, CalculationType>::type;
        return within::detail::point_in_box_by_side
            <
                within::detail::decide_covered_by
            >(point, box, side_strategy_type());
    }
};

template <typename CalculationType = void>
struct spherical_point_box_by_side
{
    template <typename Point, typename Box>
    static bool apply(Point const& point, Box const& box)
    {
        return within::detail::point_in_box_by_side
            <
                within::detail::decide_covered_by
            >(point, box,
              strategy::side::spherical_side_formula<CalculationType>());
    }
};

template
<
    typename FormulaPolicy = strategy::andoyer,
    typename Spheroid = srs::spheroid<double>,
    typename CalculationType = void
>
struct geographic_point_box_by_side
{
    geographic_point_box_by_side() = default;

    explicit geographic_point_box_by_side(Spheroid const& spheroid)
        : m_side(spheroid)
    {}

    template <typename Point, typename Box>
    bool apply(Point const& point, Box const& box) const
    {
        return within::detail::point_in_box_by_side
            <
                within::detail::decide_covered_by
            >(point, box, m_side);
    }

    Spheroid const& model() const
    {
        return m_side.model();
    }

private:
    strategy::side::geographic
        <
            FormulaPolicy, Spheroid, CalculationType
        > m_side;
};

}

}}} // namespace boost::geometry::strategy

#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP

ext: hpp


text:
#ifndef YASMIC_COMPRESSED_ROW_MATRIX_GRAPH
#define YASMIC_COMPRESSED_ROW_MATRIX_GRAPH

#if _MSC_VER >= 1400
    // disable the warning for deprecated c++ commands
    #pragma warning( push )
	#pragma warning( disable : 4996 )
#endif // _MSC_VER >= 1400

#include <boost/iterator.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/pending/integer_range.hpp>
#include <boost/graph/detail/adj_list_edge_iterator.hpp>
#include <boost/graph/properties.hpp>
#include <boost/property_map.hpp>

#include <yasmic/compressed_row_matrix.hpp>
#include <yasmic/tuple_utility.hpp>

namespace boost
{
	struct yasmic_compressed_row_matrix_traversal_category :
		public vertex_list_graph_tag,
		public adjacency_graph_tag,
		public incidence_graph_tag,
		public edge_list_graph_tag { };

	// forward declarations (prototypes) for the detailed implementation

	namespace impl
	{
		//template <class EdgeList> struct val_out_edge_ret;
		template <class RowIter, class ColIter, class ValIter> class crm_graph_edge_iter;
		template <class RowIter, class ColIter, class ValIter> struct crm_graph_edge;

		template <class RowIter, class ColIter, class ValIter>
		struct crm_graph
		{
			typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> type;
			typedef yasmic::smatrix_traits<type> traits;
		};

		/*template <class RowIter, class ColIter, class ValIter>
		struct nonzero_to_edge_transform
		{
			typedef
				typename impl::crm_graph_edge<RowIter, ColIter, ValIter>::type result_type;

			typedef
				const typename crm_graph<RowIter, ColIter, ValIter>::traits::row_nonzero_descriptor argument_type;

			result_type operator() (argument_type arg) const
			{
				return (result_type(arg._row, arg._column, arg._nzi));
			}
		};*/

		template <class RowIter, class ColIter, class ValIter>
		struct nonzero_to_adjacency_transform
		{
			typedef
				typename crm_graph<RowIter, ColIter, ValIter>::traits::index_type result_type;
			typedef
				const typename crm_graph<RowIter, ColIter, ValIter>::traits::row_nonzero_descriptor argument_type;

			result_type operator() (argument_type arg) const
			{
				return (arg._column);
			}
		};
	}

	template <class RowIter, class ColIter, class ValIter>
	struct graph_traits< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >
	{
		typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> smatrix_type;

		typedef typename yasmic::smatrix_traits<smatrix_type>::index_type vertex_descriptor;
		typedef typename yasmic::smatrix_traits<smatrix_type>::row_nonzero_descriptor edge_descriptor;

		typedef
			boost::transform_iterator<
				impl::nonzero_to_adjacency_transform<RowIter, ColIter, ValIter>,
				typename yasmic::smatrix_traits<smatrix_type>::row_nonzero_iterator >
			adjacency_iterator;

		typedef typename yasmic::smatrix_traits<smatrix_type>::row_nonzero_iterator
			out_edge_iterator;

		typedef void in_edge_iterator;

		typedef typename yasmic::smatrix_traits<smatrix_type>::row_iterator vertex_iterator;

		typedef typename yasmic::smatrix_traits<smatrix_type>::nonzero_iterator edge_iterator;

		typedef directed_tag directed_category;
		typedef allow_parallel_edge_tag edge_parallel_category;
		typedef yasmic_compressed_row_matrix_traversal_category traversal_category;
		typedef typename yasmic::smatrix_traits<smatrix_type>::index_type vertices_size_type;
		typedef typename yasmic::smatrix_traits<smatrix_type>::size_type edges_size_type;
		typedef typename yasmic::smatrix_traits<smatrix_type>::size_type degree_size_type;

        static vertex_descriptor null_vertex()
        {
            return std::numeric_limits<vertex_descriptor>::max();
        }
	};
    template <class RowIter, class ColIter, class ValIter>
	struct graph_traits< const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >
        : graph_traits< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >
    {};

    template <class RowIter, class ColIter, class ValIter>
    struct edge_property_type< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >  {
        typedef void type;
    };

    template <class RowIter, class ColIter, class ValIter>
    struct vertex_property_type< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >  {
        typedef void type;
    };

	namespace impl
	{

		template <class V, class S>
		class crm_graph_edge_type :
	    	public std::pair<V,V>
		{
		public:
    		crm_graph_edge_type() { }
    		crm_graph_edge_type(V s, V d, S id)
    			: std::pair<V,V>(s, d), _id(id) { }

    		S id() { return (_id); }

		protected:
	    	S _id;
	    };

		template <class RowIter, class ColIter, class ValIter>
		struct crm_graph_edge
		{
			typedef typename yasmic::smatrix_traits<typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::index_type V;
			typedef typename yasmic::smatrix_traits<typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::size_type S;

			typedef crm_graph_edge_type<V,S> type;
		};

		template <class RowIter, class ColIter, class ValIter>
		class crm_graph_edge_iter
		: public boost::iterator_facade<
            crm_graph_edge_iter<RowIter, ColIter, ValIter>,
			typename crm_graph_edge<RowIter, ColIter, ValIter>::type const,
            boost::forward_traversal_tag,
            typename crm_graph_edge<RowIter, ColIter, ValIter>::type const >
		{
		public:
            crm_graph_edge_iter() {}

			crm_graph_edge_iter(
                RowIter ri, RowIter rend, ColIter ci)
            : _ri(ri), _rend(rend), _ci(ci), _id(0), _row(0)
            {
				_ri++;
            	// skip over any empty rows
            	while ( _ri != _rend && *(_ri) == _id )
                {
                   	// keep incrementing the row
                   	++_ri; ++_row;
                }
            }

			crm_graph_edge_iter(
                RowIter ri, RowIter rend, ColIter ci,
				typename std::iterator_traits<RowIter>::value_type id)
			: _ri(ri), _rend(rend), _ci(ci), _id(id), _row(0)
			{
			}

		private:
            friend class boost::iterator_core_access;

            void increment()
            {
            	// just increment everything!
            	++_ci; ++_id;

                if (_id == *_ri)
                {
                	++_ri; ++_row;

                	// while we aren't at the end and the row isn't empty
                	// (if *_ri == _id, then the row is empty because _id
                	// is the current index in the column/val array.)
                	while ( _ri != _rend && *(_ri) == _id )
                    {
                    	// keep incrementing the row
                    	++_ri; ++_row;
                    }
                }
            }

			bool equal(crm_graph_edge_iter const& other) const
            {
				return (_ri == other._ri && _ci == other._ci);
            }

            typename crm_graph_edge<RowIter, ColIter, ValIter>::type
            dereference() const
            {
            	//return boost::make_tuple(_row, *_ci, *_vi);
				return edge_type(_row, *_ci, _id);
            }

			typedef typename crm_graph_edge<RowIter, ColIter, ValIter>::type edge_type;
            typename std::iterator_traits<RowIter>::value_type _row;
            typename std::iterator_traits<RowIter>::value_type _id;
            RowIter _ri, _rend;
            ColIter _ci;
		};

		template <class RowIter, class ColIter, class ValIter>
		struct crm_graph_ret
		{
			typedef yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> smatrix_type;
			typedef yasmic::smatrix_traits<smatrix_type> smatrix_traits;

			typedef boost::graph_traits<smatrix_type> g_traits;

			typedef std::pair< typename g_traits::vertex_iterator, typename g_traits::vertex_iterator >
				vertices_ret;

			typedef std::pair< typename g_traits::adjacency_iterator, typename g_traits::adjacency_iterator >
				adjacent_ret;

			typedef std::pair < typename g_traits::out_edge_iterator, typename g_traits::out_edge_iterator >
				out_edges_ret;

			typedef std::pair < typename g_traits::edge_iterator, typename g_traits::edge_iterator >
				edges_ret;
		};
	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename boost::graph_traits< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >::vertices_size_type
		num_vertices(const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		return nrows(g);
	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename boost::graph_traits< yasmic::compressed_row_matrix<RowIter, ColIter, ValIter> >::vertices_size_type
		num_edges(const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		return nnz(g);
	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_descriptor
	source(
		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::edge_descriptor e,
		const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		return (e._row);
	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_descriptor
	target(
		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::edge_descriptor e,
		const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		return (e._column);
	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::out_edges_ret
		out_edges(typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_descriptor v,
			  const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		return (row_nonzeros(v,g));

		/*typedef typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::out_edge_iterator Iter;
		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::out_edges_ret return_type;

		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::smatrix_traits::row_nonzero_iterator rnzi, rnziend;

		tie(rnzi, rnziend) = yasmic::row_nonzeros(v, g);

		typedef typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::out_edge_iterator iter;

		return std::make_pair(iter(rnzi), iter(rnziend));*/

		/*typedef typename detail::val_out_edge_iter<EdgeList>::type Iter;
		typedef typename detail::val_out_edge_ret<EdgeList>::type return_type;
		return return_type(Iter(v, ++g[v].begin(), *(g[v].begin())),
    		Iter(v, g[v].end(), *(g[v].begin())));*/
	}

	template <class RowIter, class ColIter, class ValIter>
	typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::degree_size_type
	out_degree(
		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_descriptor v,
		const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		return (g._rstart[v+1] - g._rstart[v]);

		/*typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::smatrix_traits::row_nonzero_iterator rnzi, rnziend;

		tie(rnzi, rnziend) = yasmic::row_nonzeros(v, g);

		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::smatrix_traits::size_type rval = 0;
		while (rnzi != rnziend) { ++rnzi; ++rval; }

		return (rval);*/

	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::adjacent_ret
		adjacent_vertices(
			typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_descriptor v,
			const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::smatrix_traits::row_nonzero_iterator rnzi, rnziend;

		tie(rnzi, rnziend) = yasmic::row_nonzeros(v, g);

		typedef typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::adjacency_iterator iter;

		return std::make_pair(iter(rnzi), iter(rnziend));
	}

	// source() and target() already provided for pairs in graph_traits.hpp

	template <class RowIter, class ColIter, class ValIter>
	inline typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::vertices_ret
		vertices(const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		//typedef typename boost::integer_range<typename EdgeList::value_type>
		//::iterator Iter;
		typedef typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_iterator iter;
		return std::make_pair(iter(0), iter(nrows(g)));
	}

	template <class RowIter, class ColIter, class ValIter>
	inline typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::edges_ret
		edges(const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
		//typedef typename boost::integer_range<typename EdgeList::value_type>
		//::iterator Iter;
		//typedef typename impl::crm_graph_ret<RowIter, ColIter, ValIter>::g_traits::vertex_iterator iter;
		//return std::make_pair(iter(0), iter(nrows(g)));

		return (nonzeros(g));
	}

	template <class RowIter, class ColIter, class ValIter>
	class compressed_row_matrix_graph_id_map
		: public put_get_helper<
			typename yasmic::smatrix_traits< typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::size_type,
    		compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> >
	{
	protected:
  		typedef typename yasmic::smatrix_traits< typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::size_type S;
	public:
  		typedef readable_property_map_tag category;
  		typedef S value_type;
  		typedef S reference;
		typedef typename graph_traits< typename impl::crm_graph<RowIter, ColIter, ValIter>::type >::edge_descriptor key_type;
		//typedef typename impl::crm_graph_edge<RowIter, ColIter, ValIter>::type key_type;
  		//typedef typename detail::crm_graph_edge<RowIter, ColIter, ValIter>::type key_type;

  		compressed_row_matrix_graph_id_map() { }
  		template <class T> S operator [] (T x) const { return x._nzi; }
	};

	template <class RowIter, class ColIter, class ValIter>
	inline identity_property_map get(vertex_index_t,
		const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
  		identity_property_map pmap;
  		return (pmap);
	}

	template <class RowIter, class ColIter, class ValIter>
	inline compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> get(edge_index_t,
  		const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
  		compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> pmap;
  		//return (vector_graph_id_map<EdgeList>());
  		return (pmap);
	}

	template <class Tag>
	struct compressed_row_matrix_graph_property_map { };

	template <>
	struct compressed_row_matrix_graph_property_map<vertex_index_t> {
  		template <class RowIter, class ColIter, class ValIter>
  		struct bind_ {
  			typedef identity_property_map type;
  			typedef identity_property_map const_type;
  		};
	};

	template <>
	struct compressed_row_matrix_graph_property_map<edge_index_t> {
  		template <class RowIter, class ColIter, class ValIter>
  		struct bind_ {
  			typedef compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> type;
  			typedef compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> const_type;
  		};
	};

	template <>
	struct compressed_row_matrix_graph_property_map<edge_weight_t> {
		template <class RowIter, class ColIter, class ValIter>
		struct bind_ {
			typedef iterator_property_map<ValIter, compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> > type;
			typedef iterator_property_map<ValIter, compressed_row_matrix_graph_id_map<RowIter, ColIter, ValIter> > const_type;
		};
	};

	template <class RowIter, class ColIter, class ValIter, class Tag>
	struct property_map<yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>, Tag> {
  		typedef typename compressed_row_matrix_graph_property_map<Tag>::template
  			bind_<RowIter, ColIter, ValIter> map_gen;
  		typedef typename map_gen::type type;
  		typedef typename map_gen::const_type const_type;
	};

	template <class RowIter, class ColIter, class ValIter>
	inline typename property_map<yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>, edge_weight_t>::type
		get(edge_weight_t, const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g)
	{
  		return (make_iterator_property_map(g.begin_values(), get(edge_index, g)));
	}

    /*template <class Tag, class RowIter, class ColIter, class ValIter, class Key>
    inline typename typename property_map<yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>, Tag>::value_type
		get(Tag t, const yasmic::compressed_row_matrix<RowIter, ColIter, ValIter>& g, Key key)
	{
        return get(get(t, g), key);
  		//return (make_iterator_property_map(g.begin_values(), get(edge_index, g)));
	}*/

}

#if _MSC_VER >= 1400
	// disable the warning for deprecated c++ commands
	#pragma warning( pop )
#endif // _MSC_VER >= 1400

#endif // YASMIC_COMPRESSED_ROW_MATRIX_GRAPH


text:
#ifndef _jsc_bioinfo_fasta_hpp_included_
#define _jsc_bioinfo_fasta_hpp_included_

#include <boost/config.hpp>

#include <math.h>

#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <vector>

#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/shared_ptr.hpp>

using namespace std;
using namespace boost;
using namespace boost::lambda;

namespace jsc
{

namespace bioinfo
{

//! Defines the format of a simple fasta entry, without comments.
class fa_entry
{
public:
	//! Description of the sequence.
	string seq_desc;
	unsigned long seq_length;
	shared_ptr<char> seqp;
};

//! A shared_ptr to fa_entry
typedef shared_ptr<fa_entry> fa_ptr;
//! A vector of fa_ptrs
typedef vector<fa_ptr> vec_fap;
//! desc to fap map
typedef map<string, fa_ptr> map_desc_fap;

//! Loads a fasta_entry from an istream.
fa_ptr load_fap(istream & is)
{
	vector<string> vec_string;
	fa_ptr fap(new fa_entry());
	string line;
	char c;
	bool desc_loaded = false;
	unsigned long seq_length = 0;
	while (is.peek() != EOF)
	{
		c = is.peek();
		if (c == '>' && !desc_loaded)
		{
			// assign description
			getline(is, line);
			fap->seq_desc = line;
			desc_loaded = true;
			continue;
		}
		else if (c == '>' && desc_loaded)
		{
			break;
		}
		getline(is, line);
		seq_length += line.size();
		vec_string.push_back(line);
	}
	// assign seq_length
	fap->seq_length = seq_length;
	// allocate memory for fap->seq
	shared_ptr<char> p(new char[fap->seq_length]);
	unsigned long cur_pos = 0;
	unsigned long i;
	for (i = 0; i < vec_string.size(); ++i)
	{
		memcpy(p.get() + cur_pos, vec_string[i].c_str(), vec_string[i].size());
		cur_pos += vec_string[i].size();
	}
	fap->seqp = p;

	return fap;
}

//! Loads fa_ptrs from an istream.
vec_fap load_faps_noheader(istream & is)
{
	/* read content */
	vec_fap faps;
	while (!is.eof())
	{
		faps.push_back(load_fap(is));
	}

	return faps;
}

} /* end of bioinfo */

} /* end of jsc */

#endif

max_stars_repo_name: gersteinlab/LESSeq

max_issues_repo_name: gersteinlab/LESSeq

max_forks_repo_name: gersteinlab/LESSeq


text:
// Copyright (c) 2012 Christopher Lux <christopherlux@gmail.com>
// Distributed under the Modified BSD License, see license.txt.

#include "volume_data.h"

#include <algorithm>
#include <exception>
#include <limits>
#include <stdexcept>
#include <sstream>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/numeric/conversion/bounds.hpp>

#include <scm/log.h>
#include <scm/core/log/logger_state.h>
#include <scm/core/math.h>
#include <scm/core/memory.h>
#include <scm/core/numeric_types.h>
#include <scm/core/time/high_res_timer.h>

#include <scm/gl_util/data/analysis/transfer_function/build_lookup_table.h>

#include <scm/gl_core/math.h>
#include <scm/gl_core/render_device.h>
#include <scm/gl_core/texture_objects.h>

#include <scm/gl_util/data/imaging/texture_data_util.h>
#include <scm/gl_util/primitives/box.h>
#include <scm/gl_util/primitives/box_volume.h>
#include <scm/gl_util/viewer/camera.h>
#include <scm/gl_util/data/volume/volume_reader_raw.h>
#include <scm/gl_util/data/volume/volume_reader_segy.h>
#include <scm/gl_util/data/volume/volume_reader_vgeo.h>

namespace scm {
namespace data {

volume_data::volume_data(const gl::render_device_ptr& device,
                         const std::string&           file_name,
                         const color_map_type&        cmap,
                         const alpha_map_type&        amap)
  : _transform(math::mat4f::identity())
  , _color_map(new color_map_type(cmap))
  , _alpha_map(new alpha_map_type(amap))
  , _selected_lod(0.0f)
{
    using namespace scm::gl;
    using namespace scm::math;

    out() << log::info << "volume_data::volume_data(): loading raw volume..." << log::end;
    _volume_raw = load_volume(device, file_name);
    if (!_volume_raw) {
        throw std::runtime_error("volume_data::volume_data(): error loading volume data from file: " + file_name);
    }
    out() << log::info << "volume_data::volume_data(): loading raw volume done." << log::end;

    out() << log::info << "volume_data::volume_data(): generating color map..." << log::end;
    _color_alpha_map = create_color_alpha_map(device, 256);
    if (!_color_alpha_map) {
        throw std::runtime_error("volume_data::volume_data(): error creating color alpha map texture.");
    }
    if (!update_color_alpha_map(device->main_context())) {
        throw std::runtime_error("volume_data::volume_data(): error upating color alpha map texture.");
    }
    _color_alpha_map_dirty = false;
    out() << log::info << "volume_data::volume_data(): generating color map done." << log::end;

    _data_dimensions = _volume_raw->descriptor()._size;
    _max_lod         = static_cast<float>(gl::util::max_mip_levels(_data_dimensions)) - 1.0f;
    unsigned max_dim = max(max(_data_dimensions.x,
                               _data_dimensions.y),
                               _data_dimensions.z);
    _extends         = vec3f(_volume_raw->descriptor()._size) / max_dim;
    _bbox            = box(math::vec3f(0.0f), _extends);
    _transform       = make_translation(-_extends / 2.0f);

    out() << log::info << "volume_data::volume_data(): generating render resources..." << log::end;
    try {
        _bbox_geometry = make_shared<box_volume_geometry>(device, _bbox.min_vertex(), _bbox.max_vertex());
        _volume_block  = make_uniform_block<volume_uniform_data>(device);
    }
    catch (const std::exception& e) {
        throw std::runtime_error(std::string("volume_data::volume_data(): error creating geometry objects: ") + e.what());
    }
    out() << log::info << "volume_data::volume_data(): generating render resources done." << log::end;

    out() << log::info << "volume_data::volume_data(): successfully loaded volume file: " << file_name << log::end;

    sample_distance_factor(0.5f);
    sample_distance_ref_factor(0.5f);
}

volume_data::~volume_data()
{
    _bbox_geometry.reset();

    _volume_raw.reset();
    _color_alpha_map.reset();

    _volume_block.reset();
}

const math::vec3f&
volume_data::extends() const
{
    return _extends;
}

const math::vec3ui&
volume_data::data_dimensions() const
{
    return _data_dimensions;
}

const math::mat4f&
volume_data::transform() const
{
    return _transform;
}

void
volume_data::transform(const math::mat4f& m)
{
    _transform = m;
}

float
volume_data::sample_distance() const
{
    return _sample_distance;
}

void
volume_data::sample_distance_factor(float d)
{
    using namespace scm::math;

    unsigned max_dim = max(max(_data_dimensions.x,
                               _data_dimensions.y),
                               _data_dimensions.z);

    _sample_distance = d / max_dim;
}

float
volume_data::sample_distance_factor() const
{
    using namespace scm::math;

    unsigned max_dim = max(max(_data_dimensions.x,
                               _data_dimensions.y),
                               _data_dimensions.z);

    return _sample_distance * max_dim;
}

float
volume_data::sample_distance_ref() const
{
    return _sample_distance_ref;
}

void
volume_data::sample_distance_ref_factor(float d)
{
    using namespace scm::math;

    unsigned max_dim = max(max(_data_dimensions.x,
                               _data_dimensions.y),
                               _data_dimensions.z);

    _sample_distance_ref = d / max_dim;
}

float
volume_data::sample_distance_ref_factor() const
{
    using namespace scm::math;

    unsigned max_dim = max(max(_data_dimensions.x,
                               _data_dimensions.y),
                               _data_dimensions.z);

    return _sample_distance_ref * max_dim;
}

float
volume_data::min_value() const
{
    return _min_value;
}

float
volume_data::max_value() const
{
    return _max_value;
}

float
volume_data::selected_lod() const
{
    return _selected_lod;
}

void
volume_data::selected_lod(float l)
{
    _selected_lod = math::clamp(l, 0.0f, _max_lod);
}

const gl::box&
volume_data::bbox() const
{
    return _bbox;
}

const gl::box_volume_geometry_ptr&
volume_data::bbox_geometry() const
{
    return _bbox_geometry;
}

const gl::texture_3d_ptr&
volume_data::volume_raw() const
{
    return _volume_raw;
}

const gl::texture_2d_ptr&
volume_data::color_alpha_map() const
{
    return _color_alpha_map;
}

const volume_data::color_map_ptr&
volume_data::color_map() const
{
    return _color_map;
}

const volume_data::alpha_map_ptr&
volume_data::alpha_map() const
{
    return _alpha_map;
}

void
volume_data::update_color_alpha_maps()
{
    _color_alpha_map_dirty = true;
}

gl::texture_3d_ptr
volume_data::load_volume(const gl::render_device_ptr& in_device,
                         const std::string&           in_file_name)
{
    using namespace scm::gl;
    using namespace scm::math;
    using namespace boost::filesystem;

    path                    file_path(in_file_name);
    std::string             file_name       = file_path.filename().string();
    std::string             file_extension  = file_path.extension().string();

    boost::algorithm::to_lower(file_extension);

    vec3ui      data_dimensions = vec3ui(0u);
    data_format data_format     = FORMAT_NULL;
    scm::shared_array<unsigned char> read_buffer;
    scm::size_t                      read_buffer_size = 0;

    scoped_ptr<gl::volume_reader> vol_reader;

    out() << log::indent;
    time::high_res_timer timer;

    if (file_extension == ".raw") {
        vol_reader.reset(new volume_reader_raw(file_path.string(), false));
    }
    else if (file_extension == ".vol") {
        vol_reader.reset(new volume_reader_vgeo(file_path.string(), true));
    }
    else if (file_extension == ".segy" || file_extension == ".sgy") {
        vol_reader.reset(new volume_reader_segy(file_path.string(), true));
    }
    else {
        err() << log::error
              << "volume_data::load_volume(): unable to open file ('" << in_file_name << "')." << log::end;
        return texture_3d_ptr();
    }

    if (!(*vol_reader)) {
        err() << log::error
                << "volume_data::load_volume(): unable to open file ('" << in_file_name << "')." << log::end;
        return texture_3d_ptr();
    }
    out() << "source data dimensions: " << vol_reader->dimensions() << log::end;

    //vec3ui data_offset = vec3ui(vol_reader->dimensions().x / 2, vol_reader->dimensions().y / 2, 0u);//vol_reader->dimensions() / vec3ui(2, 2, 2);
    //data_dimensions    = vol_reader->dimensions() / vec3ui(5, 5, 1);
    vec3ui data_offset = vec3ui(0);//vol_reader->dimensions().x / 2, vol_reader->dimensions().y / 2, vol_reader->dimensions().z / 2);//vol_reader->dimensions() / vec3ui(2, 2, 2);
    data_dimensions    = vol_reader->dimensions();// / vec3ui(1, 1, 5);
    //data_dimensions.x  = 2048;
    data_format        = vol_reader->format();

    read_buffer_size =   static_cast<scm::size_t>(data_dimensions.x) * data_dimensions.y * data_dimensions.z
                        * size_of_format(data_format);

    read_buffer.reset(new unsigned char[read_buffer_size]);

    out() << "reading volume data "
          << "(dimensions: " << data_dimensions
          << ", size : " << std::fixed << std::setprecision(3) << static_cast<double>(read_buffer_size) / (1024.0*1024.0) << "MiB)..."
          << log::end;
    timer.start();
    if (!vol_reader->read(data_offset, data_dimensions, read_buffer.get())) {
        err() << log::error
                << "volume_data::load_volume(): unable to read data from file ('" << in_file_name << "')." << log::end;
        return texture_3d_ptr();
    }
    timer.stop();
    out() << "reading volume data done"
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s, "
          << (static_cast<double>(read_buffer_size) / (1024.0*1024.0)) / time::to_seconds(timer.get_time()) << "MiB/s)" << log::end;

    _min_value = 0.0f;
    _max_value = 1.0f;
    if (is_float_type(data_format)) {
        out() << "determining floating point value range..." << log::end;
        timer.start();

        float* fp_data = reinterpret_cast<float*>(read_buffer.get());
        size_t dcount  = static_cast<scm::size_t>(data_dimensions.x) * data_dimensions.y * data_dimensions.z * channel_count(data_format);
        _min_value = boost::numeric::bounds<float>::highest();//(std::numeric_limits<float>::max)();
        _max_value = boost::numeric::bounds<float>::lowest();//(std::numeric_limits<float>::min)();

        for (size_t i = 0; i < dcount; ++i) {
            _min_value = min(_min_value, fp_data[i]);
            _max_value = max(_max_value, fp_data[i]);
        }

        if (abs(_min_value) > abs(_max_value)) {
            _max_value = abs(_min_value);
        }
        else {
            _min_value = -abs(_max_value);
        }

        timer.stop();
        out() << "etermining floating point value range"
              << " (elapsed time: " << std::fixed << std::setprecision(3)
              << time::to_seconds(timer.get_time()) << "s)" << log::end;

    }
    out() << "min_value: " << _min_value << ", max_value: " << _max_value << log::end;

    std::vector<uint8*> mip_data;
    std::vector<void*>  mip_init_data;

    out() << "generating mip map hierarchy..." << log::end;
    timer.start();
    gl::util::generate_mipmaps(data_dimensions, data_format, read_buffer.get(), mip_data);
    timer.stop();
    out() << "generating mip map hierarchy done"
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    std::for_each(mip_data.begin(), mip_data.end(), [&mip_init_data](uint8* v) {mip_init_data.push_back(v);});
    //for (std::vector<uint8*>::iterator v = mip_data.begin(); v != mip_data.end(); ++v) {
    //    mip_init_data.push_back(*v);
    //}

    unsigned mip_count = gl::util::max_mip_levels(data_dimensions);

    assert(mip_count == mip_init_data.size());

    out() << "allocating texture storage ("
          << "dimensions: " << data_dimensions << ", format: " << format_string(data_format)
          << ", mip-level: " << mip_count
          << ", size : " << std::fixed << std::setprecision(3) << static_cast<double>(read_buffer_size) / (1024.0*1024.0) << "MiB)..."
          << log::end;
    timer.start();
    texture_3d_ptr new_volume_tex = in_device->create_texture_3d(data_dimensions, data_format, mip_count, data_format, mip_init_data);
    timer.stop();
    out() << "allocating texture storage done."
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    std::for_each(mip_data.begin() + 1, mip_data.end(), [&mip_init_data](uint8* v) {delete [] v; });

    out() << log::outdent;

    return new_volume_tex;
}

gl::texture_2d_ptr
volume_data::create_color_alpha_map(const gl::render_device_ptr& in_device,
                                          unsigned               in_size) const
{
    using namespace scm::gl;
    using namespace scm::math;

    log::logger_format_saver out_save(out().associated_logger());

    out() << log::indent;
    time::high_res_timer timer;

    out() << "allocating texture storage ("
          << "dimensions: " << in_size << ", format: " << format_string(FORMAT_RGBA_8)
          << ", mip-level: " << 1
          << ", size : " << std::fixed << std::setprecision(3) << static_cast<double>(in_size * size_of_format(FORMAT_RGBA_8)) / (1024.0) << "KiB)..."
          << log::end;
    timer.start();
    texture_2d_ptr new_tex = in_device->create_texture_2d(vec2ui(in_size, 1), FORMAT_RGBA_8, 1, 1);
    timer.stop();
    out() << "allocating texture storage done."
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    if (!new_tex) {
        err() << log::error
              << "volume_data::create_color_map(): error during color map texture generation." << log::end;
        return texture_2d_ptr();
    }

    return new_tex;
}

bool
volume_data::update_color_alpha_map(const gl::render_context_ptr& context) const
{
    using namespace scm::gl;
    using namespace scm::math;

    scm::scoped_array<scm::math::vec3f>  color_lut;
    scm::scoped_array<float>             alpha_lut;

    log::logger_format_saver out_save(out().associated_logger());

    out() << log::indent;
    time::high_res_timer timer;

    out() << "generating color map texture data..." << log::end;
    timer.start();

    unsigned in_size = _color_alpha_map->descriptor()._size.x;

    color_lut.reset(new vec3f[in_size]);
    alpha_lut.reset(new float[in_size]);

    if (   !scm::data::build_lookup_table(color_lut, *_color_map, in_size)
        || !scm::data::build_lookup_table(alpha_lut, *_alpha_map, in_size)) {
        err() << log::error
              << "volume_data::update_color_alpha_map(): error during lookuptable generation" << log::end;
        return false;
    }
    scm::scoped_array<float> combined_lut;

    combined_lut.reset(new float[in_size * 4]);

    for (unsigned i = 0; i < in_size; ++i) {
        combined_lut[i*4   ] = color_lut[i].x;
        combined_lut[i*4 +1] = color_lut[i].y;
        combined_lut[i*4 +2] = color_lut[i].z;
        combined_lut[i*4 +3] = alpha_lut[i];
    }
    timer.stop();
    out() << "generating color map texture data done."
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    out() << "uploading texture data ("
          << "dimensions: " << in_size << ", format: " << format_string(FORMAT_RGBA_8)
          << ", mip-level: " << 1
          << ", size : " << std::fixed << std::setprecision(3) << static_cast<double>(in_size * size_of_format(FORMAT_RGBA_8)) / (1024.0) << "KiB)..."
          << log::end;
    timer.start();

    texture_region ur(vec3ui(0u), vec3ui(in_size, 1, 1));
    bool res = context->update_sub_texture(_color_alpha_map, ur, 0u, FORMAT_RGBA_32F, combined_lut.get());
    timer.stop();
    out() << "uploading texture data done."
          << " (elapsed time: " << std::fixed << std::setprecision(3)
          << time::to_seconds(timer.get_time()) << "s)" << log::end;

    if (!res) {
        err() << log::error
              << "volume_data::update_color_alpha_map(): error during color map texture generation." << log::end;
        return false;
    }

    return true;
}

void
volume_data::update(const gl::render_context_ptr& context,
                    const gl::camera&             cam)
{
    using namespace scm::gl;
    using namespace scm::math;

    float max_dim = static_cast<float>(max(max(_data_dimensions.x,
                                               _data_dimensions.y),
                                               _data_dimensions.z));

    mat4f mv_matrix     = cam.view_matrix() * transform();
    mat4f mv_matrix_inv = inverse(mv_matrix);

    _volume_block.begin_manipulation(context); {
        _volume_block->_volume_extends              = vec4f(extends(), 0.0);
        _volume_block->_scale_obj_to_tex            = vec4f(1.0f) / vec4f(extends(), 1.0);
        _volume_block->_sampling_distance           = vec4f(sample_distance(), sample_distance() / sample_distance_ref(), 0.0, 0.0);
        _volume_block->_os_camera_position          = mv_matrix_inv.column(3) / mv_matrix_inv.column(3).w;
        _volume_block->_value_range                 = vec4f(min_value(), max_value(), max_value() - min_value(), 1.0f / (max_value() - min_value()));

        _volume_block->_m_matrix                     = transform();
        _volume_block->_m_matrix_inverse             = inverse(transform());
        _volume_block->_m_matrix_inverse_transpose   = transpose(_volume_block->_m_matrix_inverse);
        _volume_block->_mv_matrix                    = mv_matrix;
        _volume_block->_mv_matrix_inverse            = mv_matrix_inv;
        _volume_block->_mv_matrix_inverse_transpose  = transpose(mv_matrix_inv);
        _volume_block->_mvp_matrix                   = cam.projection_matrix() * mv_matrix;
        _volume_block->_mvp_matrix_inverse           = inverse(_volume_block->_mvp_matrix);
    } _volume_block.end_manipulation();

    if (_color_alpha_map_dirty) {
        update_color_alpha_map(context);
        _color_alpha_map_dirty = false;
    }
}

const volume_data::volume_uniform_block&
volume_data::volume_block() const
{
    return _volume_block;
}
} // namespace data
} // namespace scm

ext: cpp

max_stars_repo_name: Nyran/schism

max_issues_repo_name: Nyran/schism

max_forks_repo_name: Nyran/schism


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

#ifndef BOOST_URL_IMPL_FRAGMENT_RULE_IPP
#define BOOST_URL_IMPL_FRAGMENT_RULE_IPP

#include <boost/url/rfc/fragment_rule.hpp>
#include <boost/url/rfc/charsets.hpp>
#include <boost/url/rfc/pct_encoded_rule.hpp>
#include <boost/url/grammar/parse.hpp>

namespace boost {
namespace urls {

void
fragment_rule::
parse(
    char const*& it,
    char const* const end,
    error_code& ec,
    fragment_rule& t) noexcept
{
    pct_encoded_rule<
        fragment_chars_t> t0;
    grammar::parse(it, end, ec, t0);
    t.s = t0.s;
}

void
fragment_part_rule::
parse(
    char const*& it,
    char const* const end,
    error_code& ec,
    fragment_part_rule& t) noexcept
{
    if(it == end)
    {
        t.has_fragment = false;
        return;
    }
    if(*it != '#')
    {
        t.has_fragment = false;
        return;
    }
    ++it;
    fragment_rule t0;
    if(! grammar::parse(it, end, ec, t0))
        return;
    t.has_fragment = true;
    t.fragment = t0.s;
}

} // urls
} // boost

#endif

ext: ipp

max_stars_repo_name: vgrigoriu/url

max_issues_repo_name: vgrigoriu/url

max_forks_repo_name: vgrigoriu/url


text:
//  Copyright (c) 2001-2011 Hartmut Kaiser
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//#define KARMA_FAIL_COMPILATION

#define SPIRIT_ARGUMENTS_LIMIT 10

#include <boost/config/warning_disable.hpp>
#include <boost/detail/lightweight_test.hpp>

#include <boost/spirit/include/karma_char.hpp>
#include <boost/spirit/include/karma_numeric.hpp>
#include <boost/spirit/include/karma_directive.hpp>
#include <boost/spirit/include/karma_operator.hpp>
#include <boost/spirit/include/karma_action.hpp>
#include <boost/spirit/include/karma_stream.hpp>
#include <boost/spirit/include/karma_format_attr.hpp>

#include "test_manip_attr.hpp"

using spirit_test::test;
using spirit_test::test_delimited;
using spirit_test::test_predelimited;

///////////////////////////////////////////////////////////////////////////////
int
main()
{
    using namespace boost::spirit;

    {
        using namespace boost::spirit::ascii;

        BOOST_TEST(test("1", char_, '1'));
        BOOST_TEST(test("12", char_ << char_, '1', '2'));
        BOOST_TEST(test("123", char_ << char_ << char_, '1', '2', '3'));
        BOOST_TEST(test("1234"
          , char_ << char_ << char_ << char_
          , '1', '2', '3', '4'));
        BOOST_TEST(test("12345"
          , char_ << char_ << char_ << char_ << char_
          , '1', '2', '3', '4', '5'));
        BOOST_TEST(test("123456"
          , char_ << char_ << char_ << char_ << char_ << char_
          , '1', '2', '3', '4', '5', '6'));
        BOOST_TEST(test("1234567"
          , char_ << char_ << char_ << char_ << char_ << char_ << char_
          , '1', '2', '3', '4', '5', '6', '7'));
        BOOST_TEST(test("12345678"
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , '1', '2', '3', '4', '5', '6', '7', '8'));
        BOOST_TEST(test("123456789"
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , '1', '2', '3', '4', '5', '6', '7', '8', '9'));
        BOOST_TEST(test("1234567890"
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'));
    }

    {
        using namespace boost::spirit::ascii;

        BOOST_TEST(test_delimited("1 ", char_, space, '1'));
        BOOST_TEST(test_delimited("1 2 "
          , char_ << char_, space, '1', '2'));
        BOOST_TEST(test_delimited("1 2 3 "
          , char_ << char_ << char_, space, '1', '2', '3'));
        BOOST_TEST(test_delimited("1 2 3 4 "
          , char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4'));
        BOOST_TEST(test_delimited("1 2 3 4 5 "
          , char_ << char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4', '5'));
        BOOST_TEST(test_delimited("1 2 3 4 5 6 "
          , char_ << char_ << char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4', '5', '6'));
        BOOST_TEST(test_delimited("1 2 3 4 5 6 7 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4', '5', '6', '7'));
        BOOST_TEST(test_delimited("1 2 3 4 5 6 7 8 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4', '5', '6', '7', '8'));
        BOOST_TEST(test_delimited("1 2 3 4 5 6 7 8 9 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4', '5', '6', '7', '8', '9'));
        BOOST_TEST(test_delimited("1 2 3 4 5 6 7 8 9 0 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'));
    }

    {
        using namespace boost::spirit::ascii;
        using boost::spirit::karma::delimit_flag;

        BOOST_TEST(test_predelimited(" 1 ", char_, space
          , delimit_flag::predelimit, '1'));
        BOOST_TEST(test_predelimited(" 1 2 "
          , char_ << char_, space, delimit_flag::predelimit
          , '1', '2'));
        BOOST_TEST(test_predelimited(" 1 2 3 "
          , char_ << char_ << char_, space
          , delimit_flag::predelimit, '1', '2', '3'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 "
          , char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit, '1', '2', '3', '4'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 5 "
          , char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit, '1', '2', '3', '4', '5'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 "
          , char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit
          , '1', '2', '3', '4', '5', '6'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit
          , '1', '2', '3', '4', '5', '6', '7'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit
          , '1', '2', '3', '4', '5', '6', '7', '8'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 9 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit
          , '1', '2', '3', '4', '5', '6', '7', '8', '9'));
        BOOST_TEST(test_predelimited(" 1 2 3 4 5 6 7 8 9 0 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::predelimit
          , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'));
    }

    {
        using namespace boost::spirit::ascii;
        using boost::spirit::karma::delimit_flag;

        BOOST_TEST(test_predelimited("1 ", char_, space
          , delimit_flag::dont_predelimit, '1'));
        BOOST_TEST(test_predelimited("1 2 "
          , char_ << char_, space, delimit_flag::dont_predelimit
          , '1', '2'));
        BOOST_TEST(test_predelimited("1 2 3 "
          , char_ << char_ << char_, space
          , delimit_flag::dont_predelimit, '1', '2', '3'));
        BOOST_TEST(test_predelimited("1 2 3 4 "
          , char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit, '1', '2', '3', '4'));
        BOOST_TEST(test_predelimited("1 2 3 4 5 "
          , char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit, '1', '2', '3', '4', '5'));
        BOOST_TEST(test_predelimited("1 2 3 4 5 6 "
          , char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit
          , '1', '2', '3', '4', '5', '6'));
        BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit
          , '1', '2', '3', '4', '5', '6', '7'));
        BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit
          , '1', '2', '3', '4', '5', '6', '7', '8'));
        BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 9 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit
          , '1', '2', '3', '4', '5', '6', '7', '8', '9'));
        BOOST_TEST(test_predelimited("1 2 3 4 5 6 7 8 9 0 "
          , char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_ << char_
          , space, delimit_flag::dont_predelimit
          , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'));
    }

    return boost::report_errors();
}


text:
// The Reactive C++ Toolbox.
// Copyright (C) 2021 Reactive Markets Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef TOOLBOX_NET_RATELIMIT_HPP
#define TOOLBOX_NET_RATELIMIT_HPP

#include <toolbox/sys/Time.hpp>

#include <boost/container/small_vector.hpp>

namespace toolbox {
inline namespace net {

/// RateLimit represents a rate limit spanning an interval of one or more seconds.
/// Rate limiters control the rate of requests sent or received over the network.
class TOOLBOX_API RateLimit {
  public:
    template <typename intervalT = Seconds>
    constexpr RateLimit(std::size_t limit, intervalT interval) noexcept
    : limit_{limit}
    , interval_{std::chrono::duration_cast<Decis>(interval)}
    {
        assert(interval_.count());
    }
    ~RateLimit() = default;

    // Copy.
    constexpr RateLimit(const RateLimit&) noexcept = default;
    constexpr RateLimit& operator=(const RateLimit&) noexcept = default;

    // Move.
    constexpr RateLimit(RateLimit&&) noexcept = default;
    constexpr RateLimit& operator=(RateLimit&&) noexcept = default;

    constexpr auto limit() const noexcept { return limit_; }
    constexpr auto interval() const noexcept { return interval_; }

  private:
    std::size_t limit_;
    Decis interval_;
};

TOOLBOX_API RateLimit parse_rate_limit(const std::string& s);
TOOLBOX_API std::istream& operator>>(std::istream& is, RateLimit& rl);
TOOLBOX_API std::ostream& operator<<(std::ostream& os, RateLimit rl);

/// RateWindow maintains a sliding window of second time buckets for the specified interval.
class TOOLBOX_API RateWindow {
  public:
    template <typename intervalT = Seconds>
    explicit RateWindow(intervalT interval)
    : buckets_(std::chrono::duration_cast<Decis>(interval).count())
    {
        assert(buckets_.size());
    }
    ~RateWindow();

    // Copy.
    RateWindow(const RateWindow&);
    RateWindow& operator=(const RateWindow&);

    // Move.
    RateWindow(RateWindow&&) noexcept;
    RateWindow& operator=(RateWindow&&) noexcept;

    std::size_t count() const noexcept { return count_; }
    /// Add count to time bucket.
    /// This function assumes a monotonically increasing clock.
    void add(MonoTime time, std::size_t count = 1) noexcept;

  private:
    std::size_t& at(std::time_t t) noexcept { return buckets_[t % buckets_.size()]; }
    std::size_t count_{};
    Decis last_time_{};
    boost::container::small_vector<std::size_t, 10> buckets_;
};
} // namespace net

inline namespace util {
template <>
struct TypeTraits<net::RateLimit> {
    static auto from_string(std::string_view sv) { return net::parse_rate_limit(std::string{sv}); }
    static auto from_string(const std::string& s) { return net::parse_rate_limit(s); }
};
} // namespace util
} // namespace toolbox

#endif // TOOLBOX_NET_RATELIMIT_HPP


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T. Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_ARCH_COMMON_SIMD_FUNCTION_REM_HPP_INCLUDED
#define BOOST_SIMD_ARCH_COMMON_SIMD_FUNCTION_REM_HPP_INCLUDED
#include <boost/simd/detail/overload.hpp>

#include <boost/simd/meta/hierarchy/simd.hpp>
#include <boost/simd/function/simd/divfix.hpp>
#include <boost/simd/function/simd/idivfix.hpp>
#include <boost/simd/function/simd/is_invalid.hpp>
#include <boost/simd/function/simd/is_nez.hpp>
#include <boost/simd/function/simd/multiplies.hpp>
#include <boost/simd/function/simd/selsub.hpp>

namespace boost { namespace simd { namespace ext
{
   namespace bd = boost::dispatch;
   namespace bs = boost::simd;
   BOOST_DISPATCH_OVERLOAD(rem_
                          , (typename A0, typename X)
                          , bd::cpu_
                          , bs::pack_<bd::arithmetic_<A0>, X>
                          , bs::pack_<bd::arithmetic_<A0>, X>
                          )
   {
      BOOST_FORCEINLINE A0 operator()( const A0& a0, const A0& a1) const BOOST_NOEXCEPT
      {
        return selsub(is_nez(a1), a0, idivfix(a0,a1)*a1);
      }
   };

   BOOST_DISPATCH_OVERLOAD(rem_
                          , (typename A0, typename X)
                          , bd::cpu_
                          , bs::pack_<bd::floating_<A0>, X>
                          , bs::pack_<bd::floating_<A0>, X>
                          )
   {
      BOOST_FORCEINLINE A0 operator()( const A0& a0, const A0& a1) const BOOST_NOEXCEPT
      {
        return if_nan_else(is_invalid(a1),
                        selsub(is_nez(a1), a0, divfix(a0,a1)*a1));
      }
   };

} } }

#endif


text:
#include <boost/filesystem.hpp>
#include <glog/logging.h>
#include <ros/ros.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/static_transform_broadcaster.h>
#include <vector>
#include <yaml-cpp/yaml.h>

#include "maloc/common/calibration.h"
#include "maloc/common/util.h"

int main(int argc, char **argv) {
    ros::init(argc, argv, "static_transform");
    ros::NodeHandle nh;

    std::string log_dir = "./log";
    if (!nh.getParam("log_dir", log_dir)) {
        LOG(WARNING) << "getParam log_dir failed, using default " << log_dir;
    }
    int stderr_log_level = 0;
    if (!nh.getParam("stderr_log_level", stderr_log_level)) {
        LOG(WARNING) << "getParam stderr_log_level failed, using default " << stderr_log_level;
    }
    int min_log_level = 0;
    if (!nh.getParam("min_log_level", min_log_level)) {
        LOG(WARNING) << "getParam min_log_level failed, using default " << min_log_level;
    }

    std::string calibration;
    if (!nh.getParam("calibration_file", calibration)) {
        LOG(ERROR) << "getParam calibration_file failed";
        return -1;
    }

    maloc::InitGlog(argv[0], log_dir.c_str(), stderr_log_level, min_log_level);

    if (maloc::CalibInit(calibration) < 0) {
        LOG(ERROR) << "calibration init failed";
        return -1;
    }

    std::vector<std::shared_ptr<tf2_ros::StaticTransformBroadcaster>> all_broads;
    std::vector<geometry_msgs::TransformStamped> all_tfs;

    std::vector<maloc::TransformInfo> all_tfi;
    maloc::CalibGetAllTransform(all_tfi);
    for (auto tfi : all_tfi) {
        geometry_msgs::TransformStamped tf;
        tf.header.stamp = ros::Time::now();
        tf.header.frame_id = tfi.from;
        tf.child_frame_id = tfi.to;
        tf.transform.translation.x = tfi.transform.translation[0];
        tf.transform.translation.y = tfi.transform.translation[1];
        tf.transform.translation.z = tfi.transform.translation[2];
        Eigen::Quaterniond q(tfi.transform.rotation);
        tf.transform.rotation.x = q.x();
        tf.transform.rotation.y = q.y();
        tf.transform.rotation.z = q.z();
        tf.transform.rotation.w = q.w();

        all_tfs.push_back(tf);

        auto tb = std::make_shared<tf2_ros::StaticTransformBroadcaster>();
        all_broads.push_back(tb);
    }

    for (size_t i = 0; i < all_tfs.size(); ++i) {
        all_broads[i]->sendTransform(all_tfs[i]);
    }

    ros::spin();

    return 0;
}

max_stars_repo_name: tsyxyz/maloc

max_issues_repo_name: tsyxyz/maloc

max_forks_repo_name: tsyxyz/maloc


text:
#include "PowerSpectrum.h"
#include "../GreensTensor/GreensTensorFactory.h"

// json parser
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
namespace pt = boost::property_tree;

// Constructor using a json-file
PowerSpectrum::PowerSpectrum(const std::string &input_file) {
  // Create a root
  pt::ptree root;

  // Load the json file in this ptree
  pt::read_json(input_file, root);

  // initialize polarizability by an input file
  this->polarizability = std::make_shared<Polarizability>(input_file);
  // initialize Green's tensor by an input file
  this->greens_tensor = polarizability->get_greens_tensor();
}

// Constructor with initialization list
PowerSpectrum::PowerSpectrum(std::shared_ptr<GreensTensor> greens_tensor,
                             std::shared_ptr<Polarizability> polarizability)
    : greens_tensor(std::move(greens_tensor)), polarizability(std::move(polarizability)) {}

// Compute the power spectrum for a given frequency \omega
void PowerSpectrum::calculate(double omega, cx_mat::fixed<3, 3> &powerspectrum,
                              Spectrum_Options spectrum) const {
  // imaginary unit
  std::complex<double> I(0.0, 1.0);
  // Compute the full spectrum
  if (spectrum == FULL) {
    // Initialize tensor storing the Green's tensor and setting the integration
    // options for the Green's tensor
    cx_mat::fixed<3, 3> green(fill::zeros);
    greens_tensor->integrate_k(omega, green, IM, NON_LTE);

    // Initialize tensor storing the polarizability and seting the integration
    // options for the polarizability
    cx_mat::fixed<3, 3> alpha(fill::zeros);
    polarizability->calculate_tensor(omega, alpha, COMPLEX);

    cx_mat::fixed<3, 3> alphaI(fill::zeros);
    alphaI = (alpha - trans(alpha)) / (2. * I);

    // First setting the LTE part
    powerspectrum =
        (alphaI / M_PI) / (1. - exp(-this->greens_tensor->get_beta() * omega));

    // Adding the NON-LTE part
    powerspectrum += 1. / M_PI * alpha * green * trans(alpha);
  }

  // Compute only the non-LTE contributions to the power spectrum
  if (spectrum == NON_LTE_ONLY) {
    // Initialize tensor storing the Green's tensor and setting the integration
    // options for the Green's tensor
    cx_mat::fixed<3, 3> green(fill::zeros);

    // Compute the Green's tensor
    this->greens_tensor->integrate_k(omega, green, IM, NON_LTE);

    // Initialize tensor storing the polarizability and seting the integration
    // options for the polarizability
    cx_mat::fixed<3, 3> alpha(fill::zeros);
    // Compute the polarizability
    this->polarizability->calculate_tensor(omega, alpha, COMPLEX);

    // Combine the Green's tensor and the polarizability, see eq. [3.9] in
    // Marty's PhD thesis
    powerspectrum = 1. / M_PI * alpha * green * trans(alpha);
  }
}

void PowerSpectrum::print_info(std::ostream &stream) const {
  stream << "# PowerSpectrum\n#\n";
  greens_tensor->print_info(stream);
  polarizability->print_info(stream);
}

max_stars_repo_name: QuaCaTeam/quaca

max_issues_repo_name: myoelmy/quaca

max_forks_repo_name: myoelmy/quaca


text:
/*
 *          Copyright Andrey Semashev 2007 - 2013.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   formatters/format.hpp
 * \author Andrey Semashev
 * \date   15.11.2012
 *
 * The header contains a generic log record formatter function.
 */

#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_FORMAT_HPP_INCLUDED_
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_FORMAT_HPP_INCLUDED_

#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/phoenix/core/actor.hpp>
#include <boost/phoenix/core/terminal_fwd.hpp>
#include <boost/phoenix/core/is_nullary.hpp>
#include <boost/phoenix/core/environment.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/format.hpp>
#include <boost/log/detail/custom_terminal_spec.hpp>
#include <boost/log/detail/header.hpp>

#ifdef BOOST_LOG_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace expressions {

/*!
 * \brief Template expressions terminal node with Boost.Format-like formatter
 */
template< typename CharT >
class format_terminal
{
public:
    //! Internal typedef for type categorization
    typedef void _is_boost_log_terminal;

    //! Character type
    typedef CharT char_type;
    //! Boost.Format formatter type
    typedef boost::log::aux::basic_format< char_type > format_type;
    //! String type
    typedef std::basic_string< char_type > string_type;

    //! Terminal result type
    typedef typename format_type::pump result_type;

private:
    //! Formatter object
    mutable format_type m_format;

public:
    //! Initializing constructor
    explicit format_terminal(const char_type* format) : m_format(format) {}

    //! Invokation operator
    template< typename ContextT >
    result_type operator() (ContextT const& ctx) const
    {
        return m_format.make_pump(fusion::at_c< 1 >(phoenix::env(ctx).args()));
    }

    BOOST_LOG_DELETED_FUNCTION(format_terminal())
};

/*!
 * The function generates a terminal node in a template expression. The node will perform log record formatting
 * according to the provided format string.
 */
template< typename CharT >
BOOST_LOG_FORCEINLINE phoenix::actor< format_terminal< CharT > > format(const CharT* fmt)
{
    typedef format_terminal< CharT > terminal_type;
    phoenix::actor< terminal_type > act = {{ terminal_type(fmt) }};
    return act;
}

/*!
 * The function generates a terminal node in a template expression. The node will perform log record formatting
 * according to the provided format string.
 */
template< typename CharT, typename TraitsT, typename AllocatorT >
BOOST_LOG_FORCEINLINE phoenix::actor< format_terminal< CharT > > format(std::basic_string< CharT, TraitsT, AllocatorT > const& fmt)
{
    typedef format_terminal< CharT > terminal_type;
    phoenix::actor< terminal_type > act = {{ terminal_type(fmt.c_str()) }};
    return act;
}

} // namespace expressions

BOOST_LOG_CLOSE_NAMESPACE // namespace log

#ifndef BOOST_LOG_DOXYGEN_PASS

namespace phoenix {

namespace result_of {

template< typename CharT >
struct is_nullary< custom_terminal< boost::log::expressions::format_terminal< CharT > > > :
    public mpl::false_
{
};

} // namespace result_of

} // namespace phoenix

#endif

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_FORMAT_HPP_INCLUDED_

max_issues_repo_name: graehl/boost

max_forks_repo_name: graehl/boost


text:
#include "settings.hpp"
#include <SDL2/SDL.h>
#ifdef _WIN32
#undef main
#include <boost/filesystem.hpp>
#include <iostream>
#elif __APPLE__
#include "CoreFoundation/CoreFoundation.h"
#else
#include <boost/filesystem.hpp>
#include <iostream>
#endif
#include <assimp/Exporter.hpp>
#include <assimp/Importer.hpp>
#include <assimp/importerdesc.h>
#include <boost/algorithm/string.hpp>
#include <memory>
#include <stdarg.h>

Settings* Settings::m_pInstance = NULL;

Settings* Settings::Instance() {
  if (!m_pInstance) {
    m_pInstance = new Settings;
    //m_pInstance->initSettings();
  }
  return m_pInstance;
}

void Settings::initSettings(const std::string& iniFolder) {
#ifdef Def_Bofrak_OpenGL_4x
  m_pInstance->OpenGL_MajorVersion = 4;
  m_pInstance->OpenGL_MinorVersion = 1;
#else
  m_pInstance->OpenGL_MajorVersion = 2;
  m_pInstance->OpenGL_MinorVersion = 1;
#endif

  m_pInstance->cfgUtils = std::make_unique<ConfigUtils>();
  m_pInstance->cfgUtils->init(iniFolder);

  m_pInstance->UIFontSize = 14.0f;

  m_pInstance->appVersion = m_pInstance->cfgUtils->readString("appVersion");
  m_pInstance->shouldRecompileShaders = m_pInstance->cfgUtils->readBool("shouldRecompileShaders");
  m_pInstance->showGLErrors = m_pInstance->cfgUtils->readBool("showGLErrors");
  m_pInstance->showFrameRenderTime = m_pInstance->cfgUtils->readBool("showFrameRenderTime");
  m_pInstance->SDL_Window_Width = m_pInstance->cfgUtils->readInt("SDL_Window_Width");
  m_pInstance->SDL_Window_Height = m_pInstance->cfgUtils->readInt("SDL_Window_Height");
  m_pInstance->SDL_DrawableSize_Width = m_pInstance->cfgUtils->readInt("SDL_DrawableSize_Width");
  m_pInstance->SDL_DrawableSize_Height = m_pInstance->cfgUtils->readInt("SDL_DrawableSize_Height");
  m_pInstance->guiClearColor = {70.0f / 255.0f, 70.0f / 255.0f, 70.0f / 255.0f, 255.0f / 255.0f};
  m_pInstance->SDL_Window_Flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
  m_pInstance->SelectedFractalID = 0;

#ifdef _WIN32
  m_pInstance->newLineDelimiter = "\r\n";
#elif defined macintosh // OS 9
  m_pInstance->newLineDelimiter = "\r";
#else
  m_pInstance->newLineDelimiter = "\n";
#endif

  m_pInstance->glUtils = std::make_unique<GLUtils>(std::bind(&Settings::reuseLogFunc, this, std::placeholders::_1));

  m_pInstance->ApplicationConfigurationFolder = iniFolder;
}

void Settings::reuseLogFunc(const std::string& msg) {
  m_pInstance->funcDoLog(msg);
}

std::string Settings::appFolder() {
#ifdef __APPLE__
  CFBundleRef mainBundle = CFBundleGetMainBundle();
  CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
  char folder[PATH_MAX];
  if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8*)folder, PATH_MAX))
    printf("Can't open bundle folder!\n");
  CFRelease(resourcesURL);
  return std::string(folder);
#elif _WIN32
  return boost::filesystem::current_path().string() + "/resources";
#else
  return boost::filesystem::current_path().string() + "/resources";
#endif
}

void Settings::saveSettings() {
  this->cfgUtils->writeString("appVersion", this->appVersion);
  this->cfgUtils->writeBool("shouldRecompileShaders", this->shouldRecompileShaders);
  this->cfgUtils->writeBool("showGLErrors", this->showGLErrors);
  this->cfgUtils->writeBool("showFrameRenderTime", this->showFrameRenderTime);
  this->cfgUtils->writeInt("SDL_Window_Width", this->SDL_Window_Width);
  this->cfgUtils->writeInt("SDL_Window_Height", this->SDL_Window_Height);
  this->cfgUtils->writeInt("SDL_DrawableSize_Width", this->SDL_DrawableSize_Width);
  this->cfgUtils->writeInt("SDL_DrawableSize_Height", this->SDL_DrawableSize_Height);
  this->cfgUtils->saveSettings();
}

#ifdef __APPLE__
std::string Settings::string_format(const std::string& fmt_str, ...) {
  int n = static_cast<int>(fmt_str.size()) * 2; /* Reserve two times as much as the length of the fmt_str */
  std::unique_ptr<char[]> formatted;
  va_list ap;
  while (1) {
    formatted.reset(new char[n]); /* Wrap the plain char array into the unique_ptr */
    strcpy(&formatted[0], fmt_str.c_str());
    va_start(ap, fmt_str);
    int final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap);
    va_end(ap);
    if (final_n < 0 || final_n >= n)
      n += abs(final_n - n + 1);
    else
      break;
  }
  return std::string(formatted.get());
}
#endif

bool Settings::isAllowedFileExtension(std::string fileExtension, const std::vector<std::string>& allowedExtensions) const {
  if (allowedExtensions.size() > 0) {
    std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower);
    return std::find(std::begin(allowedExtensions), std::end(allowedExtensions), fileExtension) != std::end(allowedExtensions);
  }
  else
    return true;
}

void Settings::setLogFunc(const std::function<void(std::string)>& doLog) {
  this->funcDoLog = doLog;
}

void Settings::timerStart(const std::string& msg) {
  this->funcDoLog(this->string_format("[Timer START] %s - %s", msg.c_str(), this->getTimeNow().c_str()));
}

void Settings::timerEnd(const std::string& msg) {
  this->funcDoLog(this->string_format("[Timer END] %s - %s", msg.c_str(), this->getTimeNow().c_str()));
}

const std::string Settings::getTimeNow() const {
  time_t t = time(0);
  const struct tm* now = localtime(&t);
  const int t_hour = static_cast<int>(now->tm_hour);
  const int t_min = static_cast<int>(now->tm_min);
  const int t_sec = static_cast<int>(now->tm_sec);
  std::string tn("");
  if (t_hour < 10)
    tn += "0";
  tn += std::to_string(t_hour) + ":";
  if (t_min < 10)
    tn += "0";
  tn += std::to_string(t_min) + ":";
  if (t_sec < 10)
    tn += "0";
  tn += std::to_string(t_sec);
  return tn;
}

const bool Settings::hasEnding(std::string const& fullString, std::string const& ending) const {
  if (fullString.length() >= ending.length())
    return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
  return false;
}

void Settings::logTimings(const std::string& file, const std::string& method) {
#ifdef Bofrak_Debug_Timings
  Settings::Instance()->funcDoLog(Settings::Instance()->string_format("[TIMINGS] [%s - %s] : %f seconds.", file.c_str(), method.c_str(), (1.0 * std::clock() / CLOCKS_PER_SEC)));
#endif
}

max_stars_repo_name: supudo/bofrak

max_issues_repo_name: supudo/bofrak

max_forks_repo_name: supudo/bofrak


text:
#include "helpFunctions.h"
#include <boost/thread/thread_time.hpp>
#include <boost/thread.hpp>
#include <fstream>
#include <boost/date_time/c_time.hpp>

std::string util::HelpFunctions::tighten(const std::string& str)
{
	bool in_string = false;
	std::string tmp;
	for (std::string::const_iterator iter = str.begin(); iter != str.end(); iter++)
	{
		char ch = *iter;
		int a = (unsigned)(ch + 1);
		if (Between(a, 0, 256) && isspace(ch) && in_string == false)
		{
			continue;
		}

		tmp.insert(tmp.end(), ch);
		if (ch == '\"')
		{
			in_string = !in_string;
		}
	}
	return tmp;
}

void util::HelpFunctions::threadSleep(int offset)
{
	boost::system_time time = boost::get_system_time();
	time += boost::posix_time::microsec(offset);
	boost::thread::sleep(time);
}

void util::HelpFunctions::threadSleepSecond(int offset)
{
	boost::system_time time = boost::get_system_time();
	time += boost::posix_time::seconds(offset);
	boost::thread::sleep(time);
}

tm* util::HelpFunctions::getCurrentTM(tm* pdate)
{
	time_t now = time(NULL);
	return boost::date_time::c_time::localtime(&now, pdate);
}

max_stars_repo_name: elenno/MyServer

max_issues_repo_name: elenno/MyServer

max_forks_repo_name: elenno/MyServer