text:
/*
 * UpdateJobBase.hpp
 *
 *  Created on: 2018年9月4日
 *      Author: peter
 */

#ifndef SRC_MASTER_UPDATEJOBBASE_HPP_
#define SRC_MASTER_UPDATEJOBBASE_HPP_

#include "JobBase.hpp"
#include "Result.hpp"
#include "db_typedef.hpp"
#include "mysql_empty_res_exception.hpp"

#include <boost/current_function.hpp>

#ifndef MYSQLPP_MYSQL_HEADERS_BURIED
#	define MYSQLPP_MYSQL_HEADERS_BURIED
#endif

#include <mysql++/connection.h>

#include <kerbal/redis/operation.hpp>
#include <redis_conn_factory.hpp>

/**
 * @brief JobBase 的子类，同时是所有类型的 update 类的基类。
 * @note 此类为虚基类，update_solution 等函数需要由子类实现，此类不可实例化
 */
class UpdateJobBase: public JobBase
{
	protected:
		ojv4::u_id_type u_id; ///< @brief user id

		std::string s_posttime; ///< @brief post time

		SolutionDetails result;

		ojv4::s_similarity_type similarity_percentage;

	protected:

		/**
		 * @brief 通用基类的构造函数，除父类 JobBase 构造函数获得的信息除外，还额外获取更新类别任务的额外信息如 u_id,
		 * cid, postTime等信息。
		 */
		UpdateJobBase(int jobType, ojv4::s_id_type s_id, kerbal::redis_v2::connection & redis_conn);

	public:
		/**
		 * @brief 执行任务
		 * @warning 本方法实现了基类中规定的 void handle() 接口, 且子类不可再覆盖
		 */
		virtual void handle() override;

	protected:
		/**
		 * @brief 将本次提交记录更新至 solution 表
		 * @warning 仅规定 update solution 表的接口, 具体操作需由子类实现
		 */
		virtual void update_solution(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 将提交代码更新至 mysql
		 * @warning 仅规定 update source_code 表的接口, 具体操作需由子类实现
		 */
		virtual void update_source_code(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 将编译错误信息更新至 mysql
		 * @warning 仅规定 update compile_info 表的接口, 具体操作需由子类实现
		 */
		virtual void update_compile_info(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 从 redis 中取得编译错误信息
		 * @return Redis 返回集. 注意! 返回集的类型只可能为字符串类型, 否则该方法会通过抛出异常报告错误
		 * @throws RedisUnexpectedCaseException 如果取得的结果不为字符串类型 (包括空类型), 则抛出此异常
		 * @throws std::exception 该方法执行过程中还会因 redis 操作失败
		 */
		kerbal::redis_v2::reply get_compile_info() const;

		/**
		 * @brief 更新用户的提交数, 通过数
		 * @warning 仅规定 update user 表的接口, 具体操作需由子类实现
		 */
		virtual void update_user(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 更新题目的提交数, 通过数
		 * @warning 仅规定 update problem 表的接口, 具体操作需由子类实现
		 */
		virtual void update_problem(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 更新此用户此题的完成状态
		 * @detail 用户所见到的每题 AC, TO_DO, ATTEMPT 三种状态即为user problem 表所提供的服务
		 * @warning 仅规定 update user problem 表的接口, 具体操作需由子类实现
		 */
		virtual void update_user_problem(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 更新此用户此题的完成状态 [新]
		 * @detail 用户所见到的每题 AC, TO_DO, ATTEMPT 三种状态即为user problem 表所提供的服务
		 * @warning 仅规定 update user problem 表的接口, 具体操作需由子类实现
		 */
		virtual void update_user_problem_status(mysqlpp::Connection & mysql_conn) = 0;

		/**
		 * @brief 删除 redis 中本条 job 不再需要的信息
		 */
 		void clear_this_jobs_info_in_redis() noexcept;

		/**
		 * @brief 如果 update job 的过程中产生失败, 则将记录插入 core_update_failed 表中
		 * @throws 本方法承诺不抛出任何异常. 因为它本身就是对错误结果的处理函数
		 * @warning 若此方法在更新表时失败, 则说明 mysql 连接可能已失效, 接下来可能会发生一系列未定义行为 (TODO)
		 */
		void core_update_failed_table(const kerbal::redis::RedisReply & source_code, const kerbal::redis::RedisReply & compile_error_info) noexcept;

	private:
		/**
		 * @brief 删除 redis 中本条 job 向前推 600 条的 job 信息
		 */
 		void clear_previous_jobs_info_in_redis() noexcept;

	public:
		virtual ~UpdateJobBase() noexcept = default;
};

/**
 * @brief 根据传入的 jobType, sid 构造一个具体的 UpdateJob 对象, 并返回指向所构造对象的智能指针
 * @return 指向构造对象的智能指针.
 *         如果 job 为练习, 则指针实际指向的是一个 ExerciseUpdateJob 对象
 *         如果 job 为课程, 则指针实际指向的是一个 CourseUpdateJob 对象
 *         如果 job 为竞赛, 则指针实际指向的是一个 ContestUpdateJob 对象
 * @warning 返回的对象具有多态性, 请谨慎处理!
 */
std::unique_ptr<UpdateJobBase>
make_update_job(int jobType, ojv4::s_id_type s_id, kerbal::redis_v2::connection & redis_conn);

#endif /* SRC_MASTER_UPDATEJOBBASE_HPP_ */


text:
//----------------------------------------------------------------------------
/** @file SgFastLogTest.cpp
    Unit tests for SgFastLog.
*/
//----------------------------------------------------------------------------

#include "SgSystem.h"

#include <cmath>
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include "SgFastLog.h"

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

namespace {

BOOST_AUTO_TEST_CASE(SgFastLogTest_Basic)
{
    SgFastLog fastLog(10);
    const float epsilon = 0.1;
    BOOST_CHECK_CLOSE(fastLog.Log(1), 0.0f, epsilon);
    BOOST_CHECK_CLOSE(fastLog.Log(M_E), 1.0f, epsilon);
    BOOST_CHECK_CLOSE(fastLog.Log(pow(M_E, 2.0)), 2.0f, epsilon);
}

} // namespace

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

ext: cpp

max_stars_repo_name: MisterTea/HyperNEAT

max_issues_repo_name: afcarl/HyperNEAT

max_forks_repo_name: afcarl/HyperNEAT


text:
#include "sound_input_impl.hpp"

#include <AL/alc.h>
#include <AL/al.h>
#include <AL/alext.h>
#include <opus.h>

#include <algorithm>
#include <array>
#include <boost/circular_buffer.hpp>

#include "voice_exception.hpp"

kvoice::sound_input_impl::sound_input_impl(std::string_view device_name, std::int32_t        sample_rate,
                                           std::int32_t     frames_per_buffer, std::uint32_t bitrate)
    : sample_rate_(sample_rate),
      frames_per_buffer_(frames_per_buffer),
      input_device(alcCaptureOpenDevice(device_name.data(), sample_rate, AL_FORMAT_MONO_FLOAT32, frames_per_buffer)) {

    if (!input_device) throw voice_exception::create_formatted("Couldn't open capture device {}", device_name);

    sleep_time = std::chrono::milliseconds{ frames_per_buffer * 500 / sample_rate };

    int opus_err;
    encoder = opus_encoder_create(sample_rate, 1, OPUS_APPLICATION_VOIP, &opus_err);

    if (opus_err != OPUS_OK || !encoder)
        throw voice_exception::create_formatted("Couldn't create opus encoder (errc = {})", opus_err);

    if ((opus_err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(bitrate))) != OPUS_OK)
        throw voice_exception::create_formatted("Couldn't set encoder bitrate (errc = {})", opus_err);

    input_alive = true;
    input_thread = std::thread(&sound_input_impl::process_input, this);
}

kvoice::sound_input_impl::~sound_input_impl() {
    input_alive = false;
    input_thread.join();

    alcCaptureCloseDevice(input_device);
    opus_encoder_destroy(encoder);
}

bool kvoice::sound_input_impl::enable_input() {
    if (!input_active) {
        std::unique_lock lck(device_mutex);
        if (input_device) {
            input_active = true;
            alcCaptureStart(input_device);
            return true;
        }
        return false;
    }
    return false;
}

bool kvoice::sound_input_impl::disable_input() {
    if (input_active) {
        std::unique_lock lck(device_mutex);
        input_active = false;
        if (input_device)
            alcCaptureStart(input_device);
        return true;
    }
    return false;
}

void kvoice::sound_input_impl::set_mic_gain(float gain) {
    input_gain.store(gain);
}

void kvoice::sound_input_impl::change_device(std::string_view device_name) {
    std::unique_lock lck(device_mutex);

    alcCaptureCloseDevice(input_device);

    input_device = alcCaptureOpenDevice(device_name.data(), sample_rate_, AL_FORMAT_MONO_FLOAT32, frames_per_buffer_);

    if (!input_device) throw voice_exception::create_formatted("Couldn't open capture device {}", device_name);
}

void kvoice::sound_input_impl::set_input_callback(std::function<on_voice_input_t> cb) {
    on_voice_input = std::move(cb);
}

void kvoice::sound_input_impl::set_raw_input_callback(std::function<on_voice_raw_input> cb) {
    on_raw_voice_input = std::move(cb);
}

void kvoice::sound_input_impl::process_input() {
    using namespace std::chrono_literals;

    std::array<std::uint8_t, kPacketMaxSize> packet{};
    std::vector<float>                       capture_buffer(frames_per_buffer_);
    std::vector<float>                       temporary_buffer;
    temporary_buffer.reserve(kOpusFrameSize);

    std::int32_t captured_frames;
    bool         buffer_captured;

    while (input_alive) {
        buffer_captured = false;

        {
            std::unique_lock lck(device_mutex);
            if (!input_device) {
                std::this_thread::sleep_for(sleep_time);
                continue;
            }
            alcGetIntegerv(input_device, ALC_CAPTURE_SAMPLES, 1, &captured_frames);
            if (captured_frames >= frames_per_buffer_) {
                capture_buffer.resize(frames_per_buffer_);
                alcCaptureSamples(input_device, capture_buffer.data(), frames_per_buffer_);
                buffer_captured = true;
            }
        }

        if (buffer_captured) {
            float mic_level = *std::max_element(capture_buffer.begin(), capture_buffer.end());

            on_raw_voice_input(capture_buffer.data(), capture_buffer.size(), mic_level);

            std::transform(capture_buffer.begin(), capture_buffer.end(), capture_buffer.begin(),
                           [gain = input_gain.load()](const float v) { return v * gain; });

            std::ptrdiff_t needed_data = kOpusFrameSize - static_cast<std::ptrdiff_t>(temporary_buffer.size());

            // move all data to temp buffer by default
            auto end_it = capture_buffer.end();

            if (needed_data < static_cast<std::ptrdiff_t>(capture_buffer.size())) {
                // move only needed amount of data if needed data size < captured data size
                end_it = std::next(capture_buffer.begin(), needed_data);
            }

            // move
            temporary_buffer.insert(temporary_buffer.cend(), std::make_move_iterator(capture_buffer.begin()),
                                    std::make_move_iterator(end_it));
            capture_buffer.erase(capture_buffer.begin(), end_it);

            // if there enough data then pass it to the encoder
            if (temporary_buffer.size() == kOpusFrameSize) {
                // encode data and pass it to callback, then clear temporary data buffer
                int len = opus_encode_float(encoder, temporary_buffer.data(), kOpusFrameSize, packet.data(),
                                            kPacketMaxSize);
                if (len < 0 || len > kPacketMaxSize) return;
                on_voice_input(packet.data(), len);
                temporary_buffer.clear();
            }
            auto           remaining_data = capture_buffer.size();
            std::ptrdiff_t idx = 0;
            // process the remaining data if any and if its size more or equals to opus frame size
            while (remaining_data >= kOpusFrameSize) {
                int len = opus_encode_float(encoder, &capture_buffer[idx], kOpusFrameSize, packet.data(),
                                            kPacketMaxSize);
                if (len < 0 || len > kPacketMaxSize) return;
                on_voice_input(packet.data(), len);
                idx += kOpusFrameSize;
                remaining_data -= kOpusFrameSize;
            }
            // add remaining data to the temporary buffer if any
            if (remaining_data > 0) {
                temporary_buffer.insert(temporary_buffer.cend(),
                                        std::make_move_iterator(std::next(capture_buffer.begin(), idx)),
                                        std::make_move_iterator(capture_buffer.end()));
                capture_buffer.clear();
            }

        }

        std::this_thread::sleep_for(sleep_time);
    }
}


text: #include <boost/spirit/home/support/auxiliary/attr_cast.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


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

#include "JUnitReporter.h"
#include "Runnable.h"
#include "FileOutputStream.h"
#include "ConsoleOutputStream.h"
#include "SpecResult.h"
#include <iostream>
#include <algorithm>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/typeof/typeof.hpp>

namespace CppSpec {

JUnitReporter::JUnitReporter()
: createLogFiles(false), reportDirectory(), failOccured(false) {
}

JUnitReporter::JUnitReporter(const std::string& reportDirectory)
: createLogFiles(true), reportDirectory(reportDirectory), failOccured(false) {
}

JUnitReporter::~JUnitReporter() {
}

void JUnitReporter::addSpecification(const SpecResult& results) {
    const int fails(results.failCount());
    const int pass(results.passCount());
    failOccured = (fails != 0) || failOccured;
    OutputStream* output = createOutputStream(results.getSpecificationName());
    (*output) << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" << "\n";
    (*output) << "<testsuite failures=\"" << fails << "\" name=\"" << results.getSpecificationName() << "\" tests=\""
        << pass + fails << "\" time=\"" << results.getDuration() << "\" timestamp=\"" << currentTime() << "\">" << "\n";

    for (BOOST_AUTO(it, results.firstBehavior()); it != results.lastBehavior(); ++it) {
        (*output)   << "<testcase classname=\""
                    << results.getSpecificationName()
                    << "\" name=\""
                    << it->name
                    << "\" time=\""
                    << it->duration << "\"";
        if (it->passed) {
            (*output) << " />" << "\n";
        } else {
            (*output) << ">" << "\n";
			(*output) << "<error message=\"" << it->message << " at " << it->file << ":" << it->line << "\" />" << "\n";
			(*output) << "</testcase>" << "\n";
        }
    }

    (*output) << "</testsuite>" << "\n";
    delete output;
}

bool JUnitReporter::anyBehaviorFailed() const {
    return failOccured;
}

OutputStream* JUnitReporter::createOutputStream(const std::string& specificationName) {
	if(createLogFiles) {
		return new FileOutputStream(reportDirectory, specificationName);
	}

	return new ConsoleOutputStream;
}

std::string JUnitReporter::currentTime() {
    using namespace boost::posix_time;
    return to_simple_string(second_clock::local_time());
}

}

max_stars_repo_name: meshell/cppspec

max_issues_repo_name: meshell/cppspec

max_forks_repo_name: meshell/cppspec


text:
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>

int main()
{
	boost::uuids::uuid tag;

	tag = boost::uuids::random_generator()();

	std::cout << tag << std::endl;
}


text:
//
// Created by bodand on 2019-12-22.
//

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wused-but-marked-unused"
#pragma once

#pragma clang diagnostic push
#pragma ide diagnostic ignored "MemberFunctionCanBeStaticInspection"
#pragma ide diagnostic ignored "cert-err58-cpp"

#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(Trivial)

  BOOST_AUTO_TEST_CASE(FrameworkTest) {
      BOOST_CHECK_MESSAGE(true, "Your Boost is properly installed");
  }

BOOST_AUTO_TEST_SUITE_END()

#pragma clang diagnostic pop

#pragma clang diagnostic pop

max_stars_repo_name: isbodand/InfoDynamite

max_issues_repo_name: isbodand/InfoDynamite

max_forks_repo_name: isbodand/InfoDynamite


text:
#ifndef constraint_hpp
#define constraint_hpp

#include <memory>
#include <vector>
#include <Eigen/Core>

namespace elasty
{
    struct Particle;

    enum class ConstraintType { Bilateral, Unilateral };

    class Constraint
    {
    public:

        Constraint(const std::vector<std::shared_ptr<Particle>>& particles,
                   const double stiffness) :
        m_stiffness(stiffness),
        m_particles(particles)
        {
        }

        /// \brief Calculates the constraint function value C(x).
        virtual double calculateValue() = 0;

        /// \brief Calculate the derivative of the constraint function
        /// grad C(x).
        /// \details As constraints can have different vector sizes, it will
        /// store the result to the passed raw buffer that should be allocated
        /// in the caller, rather than returning a dynamically allocated
        /// variable-length vector. This method does not check whether the
        /// buffer is adequately allocated, or not.
        virtual void calculateGrad(double* grad_C) = 0;

        /// \brief Manipulate the associated particles by projecting them to the
        /// constraint manifold.
        /// \details This method should be called by the core engine. As this
        /// method directly updates the predicted positions of the associated
        /// particles, it is intended to be used in a Gauss-Seidel-style solver.
        virtual void projectParticles() = 0;

        /// \brief Return the constraint type (i.e., either unilateral or
        /// bilateral).
        virtual ConstraintType getType() = 0;

        /// \brief Stiffness of this constraint, which should be in [0, 1].
        double m_stiffness;

    protected:

        /// \brief Associated particles.
        /// \details The number of particles is (in most cases) solely
        /// determined in each constraint. For example, a distance constraint
        /// need to have exactly two particles. Some special constraints
        /// (e.g., shape-matching constraint) could have a variable number of
        /// particles.
        std::vector<std::shared_ptr<Particle>> m_particles;
    };

    class BendingConstraint final : public Constraint
    {
    public:

        BendingConstraint(const std::shared_ptr<Particle> p_0,
                          const std::shared_ptr<Particle> p_1,
                          const std::shared_ptr<Particle> p_2,
                          const std::shared_ptr<Particle> p_3,
                          const double stiffness,
                          const double dihedral_angle);

        double calculateValue() override;
        void calculateGrad(double* grad_C) override;
        void projectParticles() override;
        ConstraintType getType() override { return ConstraintType::Bilateral; }

    private:

        const Eigen::Matrix<double, 12, 1> m_inv_M;
        const double m_dihedral_angle;
    };

    class DistanceConstraint final : public Constraint
    {
    public:

        DistanceConstraint(const std::shared_ptr<Particle> p_0,
                           const std::shared_ptr<Particle> p_1,
                           const double stiffness,
                           const double d);

        double calculateValue() override;
        void calculateGrad(double* grad_C) override;
        void projectParticles() override;
        ConstraintType getType() override { return ConstraintType::Bilateral; }

    private:

        const Eigen::Matrix<double, 6, 1> m_inv_M;
        const double m_d;
    };

    class EnvironmentalCollisionConstraint final : public Constraint
    {
    public:

        EnvironmentalCollisionConstraint(const std::shared_ptr<Particle> p_0,
                                         const double stiffness,
                                         const Eigen::Vector3d& n,
                                         const double d);

        double calculateValue() override;
        void calculateGrad(double* grad_C) override;
        void projectParticles() override;
        ConstraintType getType() override { return ConstraintType::Unilateral; }

    private:

        const Eigen::Matrix<double, 3, 1> m_inv_M;
        const Eigen::Vector3d m_n;
        const double m_d;
    };

    class FixedPointConstraint final : public Constraint
    {
    public:

        FixedPointConstraint(const std::shared_ptr<Particle> p_0,
                             const double stiffness,
                             const Eigen::Vector3d& point);

        double calculateValue() override;
        void calculateGrad(double* grad_C) override;
        void projectParticles() override;
        ConstraintType getType() override { return ConstraintType::Bilateral; }

    private:

        const Eigen::Matrix<double, 3, 1> m_inv_M;
        const Eigen::Vector3d m_point;
    };

    class IsometricBendingConstraint final : public Constraint
    {
    public:

        IsometricBendingConstraint(const std::shared_ptr<Particle> p_0,
                                   const std::shared_ptr<Particle> p_1,
                                   const std::shared_ptr<Particle> p_2,
                                   const std::shared_ptr<Particle> p_3,
                                   const double stiffness);

        double calculateValue() override;
        void calculateGrad(double* grad_C) override;
        void projectParticles() override;
        ConstraintType getType() override { return ConstraintType::Bilateral; }

    private:

        const Eigen::Matrix<double, 12, 1> m_inv_M;
        Eigen::Matrix4d m_Q;
    };
}

#endif /* constraint_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_FUNCTION_DEFINITION_IF_DEC_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_DEFINITION_IF_DEC_HPP_INCLUDED

#include <boost/simd/config.hpp>
#include <boost/simd/function/definition/seldec.hpp>
#include <boost/simd/detail/dispatch.hpp>

namespace boost { namespace simd
{
  namespace tag
  {
    using if_dec_ = seldec_;
  }

  BOOST_DISPATCH_CALLABLE_DEFINITION(tag::if_dec_,if_dec);
} }

#endif


text:
#ifndef MULTIVARIATE_GAUSSIAN_HPP
#define MULTIVARIATE_GAUSSIAN_HPP

#include "gtest/gtest_prod.h"
#include "multinomial.hpp"
#include "types.hpp"

#include <Eigen/Dense>
#include <boost/log/trivial.hpp>
#include <vector>

namespace FilterModel {

/**
 * Represents a Multivariate Guassian distribution, especially when approximated from a multinomial.
 */
class MultivariateGuassian {
   public:
    MultivariateGuassian(const std::vector<double> mean,
                         const std::vector<std::vector<double>> covariance);

    /**
     * Constructs a MultivariateGuassian as an approximation of a multinomial distribution.
     */
    static MultivariateGuassian from_multinomial(int n, const std::vector<double>& p);
    static MultivariateGuassian from_multinomial(const Multinomial& m);
    /**
     * Returns the triangular covariance matrix of the guassian as a vector of vectors.
     */
    std::vector<std::vector<double>> get_covariance() const;
    /**
     * Returns the mean vector of the guassian.
     */
    std::vector<double> get_mean() const;

    void shift_hyperplanes(std::vector<std::vector<double>>& hyperplanes);
    double density(std::vector<double> point) const;

   private:
    Eigen::VectorXd mean;
    Eigen::MatrixXd covariance;
    Eigen::MatrixXd covariance_inverse;
};
}  // namespace FilterModel

#endif

max_stars_repo_name: skinnersBoxy/input-filter

max_issues_repo_name: skinnersBoxy/input-filter

max_forks_repo_name: skinnersBoxy/input-filter


text:
#include <boost/test/unit_test.hpp>

#include <common.shared/url_parser/url_parser.h>

namespace
{
    bool check(const std::string& _source, const common::tools::url_vector_t& _expected)
    {
        const auto actual = common::tools::url_parser::parse_urls(_source);

        if (actual.size() != _expected.size())
        {
            std::cout << "  size mismatch: " << actual.size() << " != " << _expected.size() << " (expected)\n";
            for (auto& s : actual)
                std::cout << "  " << s.url_ << '\n';
            return false;
        }

        bool failed = false;
        for (size_t i = 0, size = _expected.size(); i != size; ++i)
        {
            if (actual[i].url_ != _expected[i].url_)
            {
                std::cout << "  \"" << actual[i].url_ << "\" != \"" << _expected[i].url_ << "\" (expected)\n";
                failed = true;
            }

            if (actual[i].type_ != _expected[i].type_)
            {
                std::cout << "  \"" << to_string(actual[i].type_) << "\" != \"" << to_string(_expected[i].type_) << "\" (expected)\n";
                failed = true;
            }

            if (_expected[i].type_ == common::tools::url::type::email)
                continue;

            if (actual[i].protocol_ != _expected[i].protocol_)
            {
                std::cout << "  \"" << to_string(actual[i].protocol_) << "\" != \"" << to_string(_expected[i].protocol_) << "\" (expected)\n";
                failed = true;
            }

            if (actual[i].extension_ != _expected[i].extension_)
            {
                std::cout << "  \"" << to_string(actual[i].extension_) << "\" != \"" << to_string(_expected[i].extension_) << "\" (expected)\n";
                failed = true;
            }
        }

        if (failed)
        {
            return false;
        }

        return true;
    }

    struct DataWrapper
    {
        DataWrapper& clear()
        {
            data_.clear();
            return *this;
        }

        DataWrapper& replace(const std::string& _url, common::tools::url::type _type = common::tools::url::type::image)
        {
            data_.clear();
            return append(_url, _type);
        }

        DataWrapper& append(const std::string& _url, common::tools::url::type _type = common::tools::url::type::image)
        {
            data_.emplace_back(_url, _type, common::tools::url::protocol::http, common::tools::url::extension::undefined);
            return *this;
        }

        DataWrapper& replace(const std::string& _url, common::tools::url::type _type, common::tools::url::extension _extension)
        {
            data_.clear();
            return append(_url, _type, _extension);
        }

        DataWrapper& append(const std::string& _url, common::tools::url::type _type, common::tools::url::extension _extension)
        {
            data_.emplace_back(_url, _type, common::tools::url::protocol::http, _extension);
            return *this;
        }

        DataWrapper& replace(const std::string& _url, common::tools::url::type _type, common::tools::url::protocol _protocol)
        {
            data_.clear();
            return append(_url, _type, _protocol);
        }

        DataWrapper& append(const std::string& _url, common::tools::url::type _type, common::tools::url::protocol _protocol)
        {
            data_.emplace_back(_url, _type, _protocol, common::tools::url::extension::undefined);
            return *this;
        }

        DataWrapper& replace(const std::string& _url, common::tools::url::type _type, common::tools::url::protocol _protocol, common::tools::url::extension _extension)
        {
            data_.clear();
            return append(_url, _type, _protocol, _extension);
        }

        DataWrapper& append(const std::string& _url, common::tools::url::type _type, common::tools::url::protocol _protocol, common::tools::url::extension _extension)
        {
            data_.emplace_back(_url, _type, _protocol, _extension);
            return *this;
        }

        operator const common::tools::url_vector_t&() const
        {
            return data_;
        }

        common::tools::url_vector_t data_;
    };
}

BOOST_AUTO_TEST_SUITE(common)

BOOST_AUTO_TEST_SUITE(tools)

BOOST_AUTO_TEST_SUITE(test_url_parser)

BOOST_AUTO_TEST_CASE(all_tests)
{
    using namespace common::tools;

    DataWrapper data;

    BOOST_CHECK(check("«12.127.17.72/test»", data.replace("http://12.127.17.72/test", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("«12.127.17.72»", data.replace("http://12.127.17.72", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("https://jira.mail.ru/browse/SWA-3529. hello", data.replace("https://jira.mail.ru/browse/SWA-3529", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://jira.mail.ru/browse/SWA-3529\" hello", data.replace("https://jira.mail.ru/browse/SWA-3529", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://jira.mail.ru/browse/SWA-3529> hello", data.replace("https://jira.mail.ru/browse/SWA-3529", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://jira.mail.ru/browse/SWA-3529` hello", data.replace("https://jira.mail.ru/browse/SWA-3529", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("http://mail.ru]", data.replace("http://mail.ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("http://mail.ru? текст", data.replace("http://mail.ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("cleric@bk.ru?", data.replace("cleric@bk.ru", url::type::email)));
    BOOST_CHECK(check("получить https://files.icq.net/get/ ->> первая часть", data.replace("https://files.icq.net/get/", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://o.life/бука💀", data.replace("https://o.life/бука💀", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("кто-нибудь вживую? https://sys.mail.ru/users/k.kashirina/ ",
        data.replace("https://sys.mail.ru/users/k.kashirina/", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("krybachuk@bk.ru\nvsras@inbox.ru\natachenko@bk.ru",
        data.replace("krybachuk@bk.ru", url::type::email).append("vsras@inbox.ru", url::type::email).append("atachenko@bk.ru", url::type::email)));
    BOOST_CHECK(check("http://img-fotki.yandex.ru/get/6707/139667729.b/0_16e81a_4aa200b1_M.jpg",
        data.replace("http://img-fotki.yandex.ru/get/6707/139667729.b/0_16e81a_4aa200b1_M.jpg", url::type::image, url::protocol::http, url::extension::jpg)));
    BOOST_CHECK(check("https://ae01.alicdn.com/kf/HTB18EXkIFXXXXc2XpXXq6xXFXXXJ/NECA-Чужой-ПРОТИВ-хищника-Фигурки-Набор-2-В-1-ПВХ-Рис-Игрушка-Установить-Классический-Хищник-Фильм.jpg_640x640.jpg",
        data.replace("https://ae01.alicdn.com/kf/HTB18EXkIFXXXXc2XpXXq6xXFXXXJ/NECA-Чужой-ПРОТИВ-хищника-Фигурки-Набор-2-В-1-ПВХ-Рис-Игрушка-Установить-Классический-Хищник-Фильм.jpg_640x640.jpg", url::type::image, url::protocol::https, url::extension::jpg)));
    BOOST_CHECK(check("h Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("ht Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("htt Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("http Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("https Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("f Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("ft Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("ftp Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("https://mail.ru@124 ", data.replace("https://mail.ru@124", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://mail.ru@124", data.replace("https://mail.ru@124", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("chat.my.com", data.replace("http://chat.my.com", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("files.icq.net", data.replace("http://files.icq.net", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("урлы будут icq.com", data.replace("http://icq.com", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("Завтра Hi-Tech Mail.Ru приглашает", data.replace("http://Mail.Ru", url::type::site, url::protocol::http)));
    BOOST_CHECK(check("file.zip", data.clear()));
    BOOST_CHECK(check("file.host", data.clear()));
    BOOST_CHECK(check("https://medium.com/@geometrieva/tutorial-for-that-space-illustration-you-keep-seeing-around-9c97214b4d92#.bceysleoc",
        data.replace("https://medium.com/@geometrieva/tutorial-for-that-space-illustration-you-keep-seeing-around-9c97214b4d92#.bceysleoc", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("http://i.imgur.com/Ospf9qn.gifv", data.replace("http://i.imgur.com/Ospf9qn.gifv", url::type::site)));
    BOOST_CHECK(check("http://media.mnn.com/assets/images/2015/08/forest-waterfall-thailand.jpg.838x0_q80.jpg",
        data.replace("http://media.mnn.com/assets/images/2015/08/forest-waterfall-thailand.jpg.838x0_q80.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("https://pbs.twimg.com/media/CwzDLi5XcAAmX6C.jpg:large",
        data.replace("https://pbs.twimg.com/media/CwzDLi5XcAAmX6C.jpg:large", url::type::image, url::protocol::https, url::extension::jpg)));
    BOOST_CHECK(check("i.com/f.bmp", data.replace("http://i.com/f.bmp", url::type::image, url::extension::bmp)));
    BOOST_CHECK(check("i.com/f.jpg", data.replace("http://i.com/f.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("i.com/f.jpeg", data.replace("http://i.com/f.jpeg", url::type::image, url::extension::jpeg)));
    BOOST_CHECK(check("i.com/f.png", data.replace("http://i.com/f.png", url::type::image, url::extension::png)));
    BOOST_CHECK(check("i.com/f.tiff", data.replace("http://i.com/f.tiff", url::type::image, url::extension::tiff)));
    BOOST_CHECK(check("i.com/f.gif", data.replace("http://i.com/f.gif", url::type::image, url::extension::gif)));
    BOOST_CHECK(check("i.com/f.avi", data.replace("http://i.com/f.avi", url::type::video, url::extension::avi)));
    BOOST_CHECK(check("i.com/f.mkv", data.replace("http://i.com/f.mkv", url::type::video, url::extension::mkv)));
    BOOST_CHECK(check("i.com/f.wmv", data.replace("http://i.com/f.wmv", url::type::video, url::extension::wmv)));
    BOOST_CHECK(check("i.com/f.flv", data.replace("http://i.com/f.flv", url::type::video, url::extension::flv)));
    BOOST_CHECK(check("i.com/f.3gp", data.replace("http://i.com/f.3gp", url::type::video, url::extension::_3gp)));
    BOOST_CHECK(check("i.com/f.mpeg4", data.replace("http://i.com/f.mpeg4", url::type::video, url::extension::mpeg4)));
    BOOST_CHECK(check("i.com/f.webm", data.replace("http://i.com/f.webm", url::type::video, url::extension::webm)));
    BOOST_CHECK(check("i.com/f.mov", data.replace("http://i.com/f.mov", url::type::video, url::extension::mov)));
    BOOST_CHECK(check("http://vignette2.wikia.nocookie.net/himym/images/5/59/Robin_dogs.jpg/revision/latest?cb=20120219232609",
        data.replace("http://vignette2.wikia.nocookie.net/himym/images/5/59/Robin_dogs.jpg/revision/latest?cb=20120219232609", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("10.0.12134 dacl73@yahoo.com", data.replace("dacl73@yahoo.com", url::type::email)));
    BOOST_CHECK(check("http://icqsnip.go.mail.ru/snippet/?", data.replace("http://icqsnip.go.mail.ru/snippet/", url::type::site)));
    BOOST_CHECK(check("http://icqsnip.go.mail.ru/snippet/?v=1&favicon=1&force_reload=0&layer=1&url=https://www.dropbox.com/s/du9mmc4yt48juix/settings.jpg?dl=0",
        data.replace("http://icqsnip.go.mail.ru/snippet/?v=1&favicon=1&force_reload=0&layer=1&url=https://www.dropbox.com/s/du9mmc4yt48juix/settings.jpg?dl=0", url::type::site)));
    BOOST_CHECK(check("ftp://ftp.mrunix.net/ ()", data.replace("ftp://ftp.mrunix.net/", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("прекрасно). 9 минут. theblueprint.ru/culture/unusual-magazines", data.replace("http://theblueprint.ru/culture/unusual-magazines", url::type::site)));
    BOOST_CHECK(check("hTO1DY", data.clear()));
    BOOST_CHECK(check("fTO1DY", data.clear()));
    BOOST_CHECK(check("hTp1DY", data.clear()));
    BOOST_CHECK(check("fTp1DY", data.clear()));
    BOOST_CHECK(check("hTtpDY", data.clear()));
    BOOST_CHECK(check("hTtpsY", data.clear()));
    BOOST_CHECK(check("fTpsDY", data.clear()));
    BOOST_CHECK(check("ftp://user@host/", data.replace("ftp://user@host/", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("http://user@host.ru/", data.replace("http://user@host.ru/", url::type::site)));
    BOOST_CHECK(check("https://user@host.ru/", data.replace("https://user@host.ru/", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("ftp://user@host.ru/", data.replace("ftp://user@host.ru/", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("ftps://user@host.ru/", data.replace("ftps://user@host.ru/", url::type::ftp, url::protocol::ftps)));
    BOOST_CHECK(check("ftp://user:pass@host.ru/", data.replace("ftp://user:pass@host.ru/", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("example.com#fooBaR", data.replace("http://example.com#fooBaR", url::type::site)));
    BOOST_CHECK(check("example.com/foo/捦挺挎/bar", data.replace("http://example.com/foo/捦挺挎/bar", url::type::site)));
    BOOST_CHECK(check("ne. ", data.clear()));
    BOOST_CHECK(check("fd.dmp", data.clear()));
    BOOST_CHECK(check("hd.dmp", data.clear()));
    BOOST_CHECK(check("%appdata%\\ICQ\\reports\\crashdump.dmp", data.clear()));
    BOOST_CHECK(check("mpmulti-l6wd.slack-msgs.com ", data.replace("http://mpmulti-l6wd.slack-msgs.com", url::type::site)));
    BOOST_CHECK(check("http://img0.joyreactor.cc/pics/post/%20ифки-болливуд-Индийское-кино-фильм-ужасов-3460286.gif",
        data.replace("http://img0.joyreactor.cc/pics/post/%20ифки-болливуд-Индийское-кино-фильм-ужасов-3460286.gif", url::type::image, url::extension::gif)));
    BOOST_CHECK(check("http://img0.joyreactor.cc/pics/post/гифки-болливуд-Индийское-кино-фильм-ужасов-3460286.gif",
        data.replace("http://img0.joyreactor.cc/pics/post/гифки-болливуд-Индийское-кино-фильм-ужасов-3460286.gif", url::type::image, url::extension::gif)));
    BOOST_CHECK(check("1. ", data.clear()));
    BOOST_CHECK(check("1.", data.clear()));
    BOOST_CHECK(check("https://1l.mail.ru/report/view/?uidReport=58186a939b58f2.82089113&idOwner=200265&graph=countFirstLoginDaily#data",
        data.replace("https://1l.mail.ru/report/view/?uidReport=58186a939b58f2.82089113&idOwner=200265&graph=countFirstLoginDaily#data", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("media3.giphy.com/media/zZQe7wglGKCEE/200w.gif#5", data.replace("http://media3.giphy.com/media/zZQe7wglGKCEE/200w.gif#5", url::type::image, url::extension::gif)));
    BOOST_CHECK(check("ftp.ru", data.replace("http://ftp.ru", url::type::site)));
    BOOST_CHECK(check("ftps.ru", data.replace("http://ftps.ru", url::type::site)));
    BOOST_CHECK(check("http.ru", data.replace("http://http.ru", url::type::site)));
    BOOST_CHECK(check("https.ru", data.replace("http://https.ru", url::type::site)));
    BOOST_CHECK(check("http.msk", data.clear()));
    BOOST_CHECK(check("http://odri.mail.msk:8111/viewType.html?buildTypeId=ImOsx_IcqQtDevelopXcode7",
        data.replace("http://odri.mail.msk:8111/viewType.html?buildTypeId=ImOsx_IcqQtDevelopXcode7", url::type::site)));
    BOOST_CHECK(check("...", data.clear()));
    BOOST_CHECK(check("master_10.0", data.clear()));
    BOOST_CHECK(check("lenta.ru?", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru!", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru,", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru.", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru? ", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru! ", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru, ", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("lenta.ru. ", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("http://icqsnip.go.mail.ru/snippet/?v=1&force_reload=1&favicon=1&layer=1&url=rb.mail.ru",
        data.replace("http://icqsnip.go.mail.ru/snippet/?v=1&force_reload=1&favicon=1&layer=1&url=rb.mail.ru", url::type::site)));
    BOOST_CHECK(check("wwwcom.ru", data.replace("http://wwwcom.ru", url::type::site)));
    BOOST_CHECK(check("ftpcom.ru", data.replace("http://ftpcom.ru", url::type::site)));
    BOOST_CHECK(check("ftp://i.com", data.replace("ftp://i.com", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("ftp://i.com/f.zip", data.replace("ftp://i.com/f.zip", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("ftp://i.com:8080/f.zip", data.replace("ftp://i.com:8080/f.zip", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("ftp://1.2.0.100/f.zip", data.replace("ftp://1.2.0.100/f.zip", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("ftp://1.2.0.100:8080/f.zip", data.replace("ftp://1.2.0.100:8080/f.zip", url::type::ftp, url::protocol::ftp)));
    BOOST_CHECK(check("ProblemBook.NET · GitBook",  data.replace("http://ProblemBook.NET", url::type::site)));
    BOOST_CHECK(check("<http://images.com/foto.jpg>", data.replace("http://images.com/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("w", data.clear()));
    BOOST_CHECK(check("hi", data.clear()));
    BOOST_CHECK(check("wat?", data.clear()));
    BOOST_CHECK(check("123.com", data.replace("http://123.com", url::type::site)));
    BOOST_CHECK(check("123@mail.com", data.replace("123@mail.com", url::type::email)));
    BOOST_CHECK(check("my@mail.com", data.replace("my@mail.com", url::type::email)));
    BOOST_CHECK(check("my.com@mail.com", data.replace("my.com@mail.com", url::type::email)));
    BOOST_CHECK(check("my@mail.com/some", data.clear()));
    BOOST_CHECK(check("my@mail.com?some", data.replace("my@mail.com", url::type::email)));
    BOOST_CHECK(check("my@mail.com:1010", data.clear()));
    BOOST_CHECK(check("my@mail", data.clear()));
    BOOST_CHECK(check("Https://icq.com/androidbeta", data.replace("Https://icq.com/androidbeta", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("Https://ICQ.com/androidbeta", data.replace("Https://ICQ.com/androidbeta", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://ICQ.com/androidbeta", data.replace("https://ICQ.com/androidbeta", url::type::site, url::protocol::https)));
    BOOST_CHECK(check("https://wtf.jpg.wtf/e8/31/1474222035-e83114ddc66ee30550fa27f26d9e9433.jpeg",
        data.replace("https://wtf.jpg.wtf/e8/31/1474222035-e83114ddc66ee30550fa27f26d9e9433.jpeg", url::type::image, url::protocol::https, url::extension::jpeg)));
    BOOST_CHECK(check("я.", data.clear()));
    BOOST_CHECK(check("ext:119:sticker:1", data.clear()));
    BOOST_CHECK(check("sticker:10", data.clear()));
    BOOST_CHECK(check("http://images.com/foto.jpg", data.replace("http://images.com/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("https://images.com/foto.jpg", data.replace("https://images.com/foto.jpg", url::type::image, url::protocol::https, url::extension::jpg)));
    BOOST_CHECK(check("http://i.com/f.png", data.replace("http://i.com/f.png", url::type::image, url::extension::png)));
    BOOST_CHECK(check("http://i.com/f1.png http://i.com/f2.jpg ,https://i.com/f3.png",
        data.replace("http://i.com/f1.png", url::type::image, url::extension::png).
            append("http://i.com/f2.jpg", url::type::image, url::extension::jpg).
            append("https://i.com/f3.png", url::type::image, url::protocol::https, url::extension::png)));
    BOOST_CHECK(check("did you see this: http://images.com/foto.jpg?", data.replace("http://images.com/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф/foto.jpg?", data.replace("http://сайт.рф/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://САЙТ.РФ/foto.jpg", data.replace("http://САЙТ.РФ/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("http://images.com:8080/foto.jpg", data.replace("http://images.com:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg?", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg.", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg,", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg? ", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg! ", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg. ", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check(" http://сайт.рф:8080/foto.jpg, ", data.replace("http://сайт.рф:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("http://example.com/%E5%BC%95%E3%81%8D%E5%89%B2%E3%82%8A.jpg",
        data.replace("http://example.com/%E5%BC%95%E3%81%8D%E5%89%B2%E3%82%8A.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("http://127.0.0.1:8080/foto.jpg", data.replace("http://127.0.0.1:8080/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("http://127.0.0.1/foto.jpg", data.replace("http://127.0.0.1/foto.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("HTTP://I.com/f.png FTPS://I.COM/f.png ;HTTP://I.COM/F.png , FTP://I.COM/F.PNG  HTTPS://I.COM/F.JPG",
        data.replace("HTTP://I.com/f.png", url::type::image, url::extension::png).
            append("FTPS://I.COM/f.png", url::type::image, url::protocol::ftps, url::extension::png).
            append("HTTP://I.COM/F.png", url::type::image, url::extension::png).
            append("FTP://I.COM/F.PNG", url::type::image, url::protocol::ftp, url::extension::png).
            append("HTTPS://I.COM/F.JPG", url::type::image, url::protocol::https, url::extension::jpg)));
    BOOST_CHECK(check("Привет! http://floristics.info/images/stati_photo/convallaria/convallaria4_3.jpg",
        data.replace("http://floristics.info/images/stati_photo/convallaria/convallaria4_3.jpg", url::type::image, url::extension::jpg)));
    BOOST_CHECK(check("http://i.com/f.jpeg", data.replace("http://i.com/f.jpeg", url::type::image, url::extension::jpeg)));
    BOOST_CHECK(check("http://i.com/f.gif", data.replace("http://i.com/f.gif", url::type::image, url::extension::gif)));
    BOOST_CHECK(check("https://www.dropbox.com/s/sxqsy9qqevmfqku/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202016-06-27%2013.25.37.png?dl=0",
        data.replace("https://www.dropbox.com/s/sxqsy9qqevmfqku/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202016-06-27%2013.25.37.png?dl=0", url::type::image, url::protocol::https, url::extension::png)));
    BOOST_CHECK(check("https://scontent-ams3-1.xx.fbcdn.net/v/t1.0-9/13516151_1781129492105796_4673404754537260997_n.jpg?oh=9ed7eb6120966f8dc03c029e7d6f850b&oe=57FFB21D",
        data.replace("https://scontent-ams3-1.xx.fbcdn.net/v/t1.0-9/13516151_1781129492105796_4673404754537260997_n.jpg?oh=9ed7eb6120966f8dc03c029e7d6f850b&oe=57FFB21D", url::type::image, url::protocol::https, url::extension::jpg)));
    BOOST_CHECK(check("http://files.icq.net/get/0zcm41ngURshP8sQ74B4eN578502541ba",
        data.replace("http://files.icq.net/get/0zcm41ngURshP8sQ74B4eN578502541ba", url::type::filesharing)));
    BOOST_CHECK(check("http://files.icq.net/get/0zcm41ngURshP8sQ74B4eN578502541ba http://files.icq.net/get/0fu9GNuiHmI5q733TuDiUb57861ccf1ai",
        data.replace("http://files.icq.net/get/0zcm41ngURshP8sQ74B4eN578502541ba", url::type::filesharing)
        .append("http://files.icq.net/get/0fu9GNuiHmI5q733TuDiUb57861ccf1ai", url::type::filesharing)));
    BOOST_CHECK(check("https://icq.com/files/0ocg8iAzD7xbSTJ5UT42z45788a26b1bb",
        data.replace("https://icq.com/files/0ocg8iAzD7xbSTJ5UT42z45788a26b1bb", url::type::filesharing, url::protocol::https)));
    BOOST_CHECK(check("https://files.icq.net/get/1fu8IH8lD0to91d7puYGH8to91AdbsmicDBiG1NT413i2HZ48S1Ny1wSq0beD1i5UbS14VhUi1GY2f811INoH1tfFVLSnuMinScT1wV1RwxQUSBp9WO1nu63FsyRzEDGi5KFLSZbXLaGFuxGyImTVzl194bsmi",
        data.replace("https://files.icq.net/get/1fu8IH8lD0to91d7puYGH8to91AdbsmicDBiG1NT413i2HZ48S1Ny1wSq0beD1i5UbS14VhUi1GY2f811INoH1tfFVLSnuMinScT1wV1RwxQUSBp9WO1nu63FsyRzEDGi5KFLSZbXLaGFuxGyImTVzl194bsmi", url::type::filesharing, url::protocol::https)));
    BOOST_CHECK(check("https://files.icq.net/get/0kE2t0tNZvcOhm3YTn3rElwKjc7UrsbBB ",
        data.replace("https://files.icq.net/get/0kE2t0tNZvcOhm3YTn3rElwKjc7UrsbBB", url::type::filesharing, url::protocol::https)));
    BOOST_CHECK(check("www.icq.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ",
        data.replace("http://www.icq.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ", url::type::filesharing)));
    BOOST_CHECK(check("chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ",
        data.replace("http://chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ", url::type::filesharing)));
    BOOST_CHECK(check("www.chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ",
        data.replace("http://www.chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ", url::type::filesharing)));
    BOOST_CHECK(check("http://www.chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ",
        data.replace("http://www.chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ", url::type::filesharing)));
    BOOST_CHECK(check("http://chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ",
        data.replace("http://chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ", url::type::filesharing)));
    BOOST_CHECK(check(" chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ",
        data.replace("http://chat.my.com/files/0hquY5yMzTW2ePH1O2542iqfr0McfiSAJ", url::type::filesharing)));
    BOOST_CHECK(check("http://img6a.flixcart.com//image/keyboard/9/q/u/ttesports-ttesports-meka-g-unit-gaming-keyboard-meka-original-imad2658r8rqvmrz.jpeg",
        data.replace("http://img6a.flixcart.com//image/keyboard/9/q/u/ttesports-ttesports-meka-g-unit-gaming-keyboard-meka-original-imad2658r8rqvmrz.jpeg", url::type::image, url::extension::jpeg)));
    BOOST_CHECK(check("http://images.com/foto.bmp", data.replace("http://images.com/foto.bmp", url::type::image, url::extension::bmp)));
    BOOST_CHECK(check("https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/14022305_1600680923562681_6123020614678369175_n.jpg?oh=910166fdcaf14be8f1ad7e623f24b974&oe=584D970E",
        data.replace("https://scontent-arn2-1.xx.fbcdn.net/v/t1.0-9/14022305_1600680923562681_6123020614678369175_n.jpg?oh=910166fdcaf14be8f1ad7e623f24b974&oe=584D970E", url::type::image, url::protocol::https, url::extension::jpg)));
    BOOST_CHECK(check("life1", data.clear()));
    BOOST_CHECK(check("i.org", data.replace("http://i.org", url::type::site)));
    BOOST_CHECK(check("i.org/", data.replace("http://i.org/", url::type::site)));
    BOOST_CHECK(check("ico.org", data.replace("http://ico.org", url::type::site)));
    BOOST_CHECK(check("ico.test.org", data.replace("http://ico.test.org", url::type::site)));
    BOOST_CHECK(check("img2?", data.clear()));
    BOOST_CHECK(check("img2/", data.clear()));
    BOOST_CHECK(check("img2:", data.clear()));
    BOOST_CHECK(check("sqlite?", data.clear()));
    BOOST_CHECK(check("lenta.sru", data.clear()));
    BOOST_CHECK(check("lenta.ru", data.replace("http://lenta.ru", url::type::site)));
    BOOST_CHECK(check("com", data.clear()));
    BOOST_CHECK(check("Уф.ф", data.clear()));
    BOOST_CHECK(check("batenka.ru/resource/med/dementia/", data.replace("http://batenka.ru/resource/med/dementia/", url::type::site)));
    BOOST_CHECK(check("\nbatenka.ru/resource/med/dementia/", data.replace("http://batenka.ru/resource/med/dementia/", url::type::site)));
    BOOST_CHECK(check("\nbatenka.ru/resource/med/dementia/\n", data.replace("http://batenka.ru/resource/med/dementia/", url::type::site)));
    BOOST_CHECK(check("http://graphite14.mail.ru/render?width=1800&from=-14h&until=&height=900&target=movingAverage(smsapi.sum.operator_ALL_MOROCCO.{send,action},30)&hideLegend=false",
        data.replace("http://graphite14.mail.ru/render?width=1800&from=-14h&until=&height=900&target=movingAverage(smsapi.sum.operator_ALL_MOROCCO.{send,action},30)&hideLegend=false", url::type::site)));
}

BOOST_AUTO_TEST_CASE(periods)
{
    using namespace common::tools;

    DataWrapper data;

    BOOST_CHECK(check("www.images.com/.x.jpg", data.replace("http://www.images.com/.x.jpg", url::type::image, url::extension::jpg)));
}

BOOST_AUTO_TEST_CASE(mamba0)
{
    using namespace common::tools;

    DataWrapper data;

    BOOST_CHECK(
        check("http://a.org?cd=pic_256d722a1075bfb9",
        data.replace("http://a.org?cd=pic_256d722a1075bfb9", url::type::site)));
}

BOOST_AUTO_TEST_CASE(mamba1)
{
    using namespace common::tools;

    DataWrapper data;

    BOOST_CHECK(
        check("http://go.imgsmail.ru/imgpreview?mb=mamba&key=pic_256d722a1075bfb9",
        data.replace("http://go.imgsmail.ru/imgpreview?mb=mamba&key=pic_256d722a1075bfb9", url::type::site)));
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()


text:
// This file is part of snark, a generic and flexible library for robotics research
// Copyright (c) 2017 The University of Sydney
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. 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.
// 3. Neither the name of the University of Sydney nor the
//    names of its contributors may be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
// GRANTED BY THIS LICENSE.  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.

/// @author Navid Pirmarzdashti

#include <comma/application/command_line_options.h>
#include <comma/application/verbose.h>
#include <Eigen/Core>
#include <boost/date_time/posix_time/ptime.hpp>
#include "../../../math/roll_pitch_yaw.h"
#include "../../../visiting/traits.h"
#include <comma/csv/options.h>
#include <comma/csv/stream.h>
#include "../device.h"
#include "../messages.h"
#include <comma/application/signal_flag.h>
#include "../../../math/spherical_geometry/coordinates.h"
#include "../../../math/spherical_geometry/traits.h"
#include "../traits.h"
#include <comma/io/select.h>
#include <comma/io/stream.h>
#include <tbb/concurrent_queue.h>
#include <thread>
#include <chrono>
#include <comma/name_value/serialize.h>
#include <regex>

using namespace snark::navigation::advanced_navigation;

const unsigned default_baud_rate=115200;
const unsigned default_sleep=10000;
bool flush=true;

void usage(bool detail)
{
    std::cerr<<"connect to Advanced Navigation Spatial device and output GPS data" << std::endl;
    std::cerr << std::endl;
    std::cerr<< "usage: " << comma::verbose.app_name() << " <what> [<options>]" << std::endl;
    std::cerr<< "    <what>: select data packet to output, default: navigation"<< std::endl;
    std::cerr<< "    or " << comma::verbose.app_name() << "--send <command> --device <port> [<options>]"<< std::endl;
    std::cerr << std::endl;
    std::cerr<< "what: " << std::endl;
    std::cerr<< "    all: combines system-state, raw-sensors and standard deviations into one record" << std::endl;
    std::cerr << "        --wait-for-all: it won't output messages for the first time until it receives all the message types" << std::endl;
    std::cerr<< "    navigation: navigation data from system state packet" << std::endl;
    std::cerr<< "    raw-sensors" << std::endl;
    std::cerr<< "    satellites" << std::endl;
    std::cerr<< "    magnetic-calibration: magnetic calibration status packet"<<std::endl;
    std::cerr<< "    system-state: full system state packet"<< std::endl;
    std::cerr << std::endl;
    std::cerr<< "send: read commands from stdin and write command message to device; csv options apply to input stream" << std::endl;
    std::cerr<< "    output: acknowledgement result value, use -v or --verbose to see human readable message on stderr"<< std::endl;
    std::cerr<< "    commands:"<< std::endl;
    std::cerr<< "        magnetic-calibration: send magnetic calibration command"<< std::endl;
    std::cerr<< "            fields: action"<< std::endl;
    std::cerr<< "            action"<< std::endl;
    std::cerr<< "                        0 Cancel magnetic calibration"<< std::endl;
    std::cerr<< "                        2 Start 2D magnetic calibration"<< std::endl;
    std::cerr<< "                        3 Start 3D magnetic calibration"<< std::endl;
    std::cerr<< "                        4 Reset calibration to defaults"<< std::endl;
    std::cerr<< "                "<< std::endl;
    std::cerr<< "    --input-fields: print input command fields and exit"<<std::endl;
    std::cerr<< "    --input-format: print input command format and exit"<<std::endl;
    std::cerr << std::endl;
    std::cerr << "options" << std::endl;
    std::cerr << "    --baud-rate,--baud=<n>: baud rate for connection, default "<< default_baud_rate << std::endl;
    std::cerr << "    --device=<filename>; filename for serial port e.g. /dev/usb/ttyUSB0" << std::endl;
    std::cerr << "    --flush: flush output stream after each write" << std::endl;
    std::cerr << "    --help,-h:       show help" << std::endl;
    std::cerr << "    --magnetic-calibration-description: print magnetic calibration status description table and exit"<< std::endl;
    std::cerr << "    --ntrip=<stream>: read ntrip data from stream and send it to device" << std::endl;
    std::cerr << "        stream can be \"-\" for stdin; or a filename or \"tcp:<host>:<port>\" etc" << std::endl;
    std::cerr << "    --output-fields: print output fields and exit" << std::endl;
    std::cerr << "    --output-format: print output format and exit" << std::endl;
    std::cerr << "    --raw: output raw packets to stdout, " << std::endl;
    std::cerr << "    --sleep=<n>: microsecond sleep between reading, default "<< default_sleep << std::endl;
    std::cerr << "    --status=<what>; print out expanded status bit map of input values" << std::endl;
    std::cerr << "        <what>: system_status | filter_status" << std::endl;
    std::cerr << "        csv options apply to input" << std::endl;
    std::cerr << "            input fields: status" << std::endl;
    std::cerr << "        --json; format output in json"<< std::endl;
    std::cerr << "    --status-description=<what>; print bit index/value and their human readable description and then exit"<< std::endl;
    std::cerr << "        <what>: system_status | filter_status | gnss_fix" << std::endl;
    std::cerr << "    --stdin; read packets from stdin, can't be used with options that need to write to device (e.g. --ntrip)" << std::endl;
    std::cerr << "    --verbose,-v:    show detailed messages" << std::endl;
    std::cerr << std::endl;
    if(detail)
    {
        std::cerr << "csv options:" << std::endl;
        std::cerr<< comma::csv::options::usage() << std::endl;
    }
    else
    {
        std::cerr << "use -v or --verbose to see more detail" << std::endl;
    }
    std::cerr << std::endl;
    std::cerr << "examples:" << std::endl;
    std::cerr << "    sudo mknod /dev/usb/ttyUSB0 c 188 0" << std::endl;
    std::cerr << "    "<<comma::verbose.app_name()<<" all --device \"/dev/usb/ttyUSB0\" " << std::endl;
    std::cerr << "    "<<comma::verbose.app_name()<<" raw-sensors --device \"/dev/usb/ttyUSB0\" " << std::endl;
    std::cerr << std::endl;
    std::cerr << "  see description of system_status values" << std::endl;
    std::cerr << "    " << comma::verbose.app_name() << " system-state --device /dev/usb/ttyUSB0 | " << comma::verbose.app_name() << " --fields system_status --status system_status" << std::endl;
    std::cerr << "    echo 128 | " << comma::verbose.app_name() << " --status system_status --json" << std::endl;
    std::cerr << std::endl;
    std::cerr << "  see description of filter_status values" << std::endl;
    std::cerr << "    " << comma::verbose.app_name() << " system-state --device /dev/usb/ttyUSB0 | " << comma::verbose.app_name() << " --fields ,filter_status --status filter_status" << std::endl;
    std::cerr << "    echo 1029 | " << comma::verbose.app_name() << " --status filter_status" << std::endl;
    std::cerr << "    " << comma::verbose.app_name() << " --status-description filter_status" << std::endl;
    std::cerr << std::endl;
    std::cerr << "  send 2D magnetic calibration command and see status" << std::endl;
    std::cerr << "    echo 1 | " << comma::verbose.app_name() << " --send magnetic-calibration --device /dev/usb/ttyUSB0 -v"<< std::endl;
    std::cerr << "    "<< comma::verbose.app_name() << " magnetic-calibration --device /dev/usb/ttyUSB0"<< std::endl;
    std::cerr << "    "<< comma::verbose.app_name() << " --magnetic-calibration-description"<<std::endl;
    std::cerr << std::endl;
}

struct output
{
    output() : height(0), system_status(0), filter_status(0) { }
    boost::posix_time::ptime t;
    snark::spherical::coordinates coordinates;
    double height;
    snark::roll_pitch_yaw orientation;
    uint16_t system_status;
    uint16_t filter_status;
};

struct output_all
{
    messages::system_state system_state;
    messages::raw_sensors raw_sensors;
    Eigen::Vector3f velocity_stddev;
    Eigen::Vector3f orientation_stddev;
    messages::satellites satellites;
};

struct status_data
{
    uint16_t status;
};

namespace comma { namespace visiting {

template <>
struct traits< output >
{
    template < typename Key, class Visitor > static void visit( const Key&, const output& p, Visitor& v )
    {
        v.apply( "t", p.t );
        v.apply( "coordinates", p.coordinates );
        v.apply( "height", p.height );
        v.apply( "orientation", p.orientation );
        v.apply( "system_status", p.system_status );
        v.apply( "filter_status", p.filter_status );
    }

    template < typename Key, class Visitor > static void visit( const Key&, output& p, Visitor& v )
    {
        v.apply( "t", p.t );
        v.apply( "coordinates", p.coordinates );
        v.apply( "height", p.height );
        v.apply( "orientation", p.orientation );
        v.apply( "system_status", p.system_status );
        v.apply( "filter_status", p.filter_status );
    }
};

template <>
struct traits< output_all >
{
    template < typename Key, class Visitor > static void visit( const Key&, const output_all& p, Visitor& v )
    {
        v.apply( "", p.system_state );
        v.apply( "", p.raw_sensors );
        v.apply( "velocity_stddev", p.velocity_stddev );
        v.apply( "orientation_stddev", p.orientation_stddev );
        v.apply( "", p.satellites );
    }

};

template <>
struct traits< status_data >
{
    template < typename Key, class Visitor > static void visit( const Key&, const status_data& p, Visitor& v )
    {
        v.apply( "status", p.status );
    }
    template < typename Key, class Visitor > static void visit( const Key&, status_data& p, Visitor& v )
    {
        v.apply( "status", p.status );
    }
};

} } // namespace comma { namespace visiting {

struct ntrip
{
    typedef std::shared_ptr<std::vector<char>> item_t;
    //create stream from name
    comma::io::istream is;
    comma::io::select select;
    //have queue<std::vecotr<char>> (or double buffer) to put data in
    static tbb::concurrent_bounded_queue<item_t> queue;
    //app_t can check the queue and write to gps, instead of sleep
    ntrip(const std::string& name) : is(name,comma::io::mode::binary,comma::io::mode::non_blocking), buf(4096)
    {
        select.read().add( is.fd() );
    }
    std::vector<char> buf;
    bool process()
    {
        if(!is->good())
            return false;
        unsigned size=is.available_on_file_descriptor();
        if( !size ) { select.wait( boost::posix_time::microseconds( 20000 ) ); }
        if( size || select.read().ready( is.fd() ) )
        {
            //or use size=readsome...
            is->read(&buf[0],size);
            size=is->gcount();
            if(size)
            {
                //put it in queue
                queue.push(item_t(new std::vector<char>(buf.begin(),buf.begin()+size)));
            }
        }
        return true;
    }
};

struct ntrip_thread
{
    //make a thread for reading
    bool shutdown;
    std::thread thread;
    std::string filename;
    ntrip_thread(const std::string& filename,const comma::command_line_options& options) :
        shutdown(false),
        thread(&ntrip_thread::run,this),
        filename(filename)
    {

    }
    ~ntrip_thread()
    {
        shutdown=true;
        thread.join();
    }
    void run()
    {
        while(!shutdown)
        {
            try
            {
                ntrip nt(filename);
                while(!shutdown&&nt.process())
                {
                }
            }
            catch( std::exception& ex ) { std::cerr << comma::verbose.app_name() << ": " << ex.what() << std::endl; }
            catch( ... ) { std::cerr << comma::verbose.app_name() << ": " << "unknown exception" << std::endl; }
            //try to connect again in 3 seconds
            for(unsigned i=0;i<100&&!shutdown;i++)
            {
                std::this_thread::sleep_for(std::chrono::microseconds(30));
            }
        }
    }
};

struct app_i
{
    virtual ~app_i() { }
    virtual void run()=0;
    virtual void output_fields()=0;
};

struct app_base : protected device
{
    unsigned us;
    comma::io::select select;
    comma::signal_flag signaled;
public:
    app_base(const std::string& port,const comma::command_line_options& options) :
        device(port,options.value<unsigned>("--baud-rate,--baud",default_baud_rate)),
        us(options.value<unsigned>("--sleep",default_sleep))
    {
        select.read().add( fd() );
    }
    void process()
    {
        while( !signaled && std::cout.good() )
        {
            select.wait( boost::posix_time::microseconds( us ) );
            if( select.read().ready( fd() ) ) { device::process(); }
            if(!ntrip::queue.empty())
            {
                ntrip::item_t item;
                ntrip::queue.pop(item);
                if(item) { send_ntrip(*item); }
            }
        }
    }
};

template<typename T>
struct app_t : public app_base
{
    comma::csv::output_stream<T> os;
    app_t(const std::string& port,const comma::command_line_options& options) :
        app_base(port,options),
        os(std::cout,comma::csv::options(options,"",true))
    {

    }
    static void output_fields()
    {
        std::cout<<comma::join( comma::csv::names<T>(true), ',' ) << std::endl;
    }
    static void output_format()    //const std::string& fields
    {
        //std::cout<<comma::csv::format::value<output_t>(fields, true) << std::endl;
        std::cout<<comma::csv::format::value<T>() << std::endl;
    }
};

struct app_nav : public app_t<output>
{
    app_nav(const std::string& port,const comma::command_line_options& options) : app_t(port,options) { }
    //message handlers
    void handle(const messages::system_state* msg)
    {
        output o;
        o.t=msg->t();
        o.coordinates.latitude=msg->latitude();
        o.coordinates.longitude=msg->longitude();
        o.height=msg->height();
        o.orientation=snark::roll_pitch_yaw(msg->orientation[0](),msg->orientation[1](),msg->orientation[2]());
        o.system_status=msg->system_status();
        o.filter_status=msg->filter_status();
        os.write(o);
        if(flush) { os.flush(); }
    }
};

struct app_raw : public app_base
{
    std::vector<char> obuf;
    app_raw(const std::string& port,const comma::command_line_options& options) : app_base(port,options), obuf(260)
    {

    }
    static void output_fields() { std::cout<<std::endl; }
    static void output_format() { std::cout<<std::endl;  }
protected:
    void handle_raw(messages::header* msg_header, const char* msg_data,std::size_t msg_data_length)
    {
        obuf.resize(messages::header::size+msg_data_length);
        std::memcpy(&obuf[0],msg_header->data(),messages::header::size);
        std::memcpy(&obuf[messages::header::size],msg_data,msg_data_length);
        std::cout.write(&obuf[0],obuf.size());
        if(flush) { std::cout.flush(); }
    }
};

/// accumulate several packets into one big output record
struct app_all : public app_t<output_all>
{
    enum { raw_sensors_mask=1, velocity_standard_deviation_mask=2, orientation_standard_deviation_mask=4, satellites_mask=8, all_mask=15 };
    unsigned recieved_messages_mask;
    unsigned wait_for_all_counter;

    app_all(const std::string& port,const comma::command_line_options& options) : app_t(port,options), recieved_messages_mask(0), wait_for_all_counter(0)
    {
        if(!options.exists("--wait-for-all"))
            recieved_messages_mask=all_mask;
    }
    output_all output;
    void handle(const messages::system_state* msg)
    {
        //make copy
        memcpy(output.system_state.data(), msg->data(),messages::system_state::size);
//         output.system_state=msg;

        if((recieved_messages_mask&all_mask)==all_mask)
        {
            os.write(output);
            if(flush) { os.flush(); }
        }
        else if(wait_for_all_counter++==100)
        {
            std::cerr<<"(--wait-for-all specified) still waiting for messages: ";
            if(!(recieved_messages_mask&raw_sensors_mask))
                std::cerr<<"raw_sensors ";
            if(!(recieved_messages_mask&velocity_standard_deviation_mask))
                std::cerr<<"velocity_standard_deviation ";
            if(!(recieved_messages_mask&orientation_standard_deviation_mask))
                std::cerr<<"orientation_standard_deviation ";
            if(!(recieved_messages_mask&satellites_mask))
                std::cerr<<"satellites ";
            std::cerr<<std::endl;
        }
    }
    void handle(const messages::raw_sensors* msg)
    {
        recieved_messages_mask|=raw_sensors_mask;
        std::memcpy(output.raw_sensors.data(),msg->data(),messages::raw_sensors::size);
    }
    void handle(const messages::velocity_standard_deviation* msg)
    {
        recieved_messages_mask|=velocity_standard_deviation_mask;
        output.velocity_stddev=Eigen::Vector3f(msg->stddev[0](),msg->stddev[1](),msg->stddev[2]());
    }
    void handle(const messages::orientation_standard_deviation* msg)
    {
        recieved_messages_mask|=orientation_standard_deviation_mask;
        output.orientation_stddev=Eigen::Vector3f(msg->stddev[0](),msg->stddev[1](),msg->stddev[2]());
    }
    void handle(const messages::satellites* msg)
    {
        recieved_messages_mask|=satellites_mask;
        std::memcpy(output.satellites.data(),msg->data(),messages::satellites::size);
    }
};

template<typename T>
struct app_packet : public app_t<T>
{
    app_packet(const std::string& port,const comma::command_line_options& options) : app_t<T>(port,options) { }
    void handle(const T* msg)
    {
        app_t<T>::os.write(*msg);
        if(flush) { app_t<T>::os.flush(); }
    }
};

struct factory_i
{
    virtual ~factory_i() { }
    virtual void output_fields()=0;
    virtual void output_format()=0;
    virtual void run(const std::string& input,const comma::command_line_options& options)=0;
};

template<typename T>
struct factory_t : public factory_i
{
    typedef T type;
    void output_fields() { T::output_fields(); }
    void output_format() { T::output_format(); }
    void run(const std::string& input,const comma::command_line_options& options)
    {

        T app(input,options);
        app.process();
    }
};

// template< typename T >
// struct description
// {
//     comma::csv::input_stream< status_data > is;
//     description( const comma::command_line_options& options ) : is( std::cin, comma::csv::options( options ) ) { }
//     void process()
//     {
//         while( std::cin.good() )
//         {
//             const status_data* p = is.read();
//             if( !p ) { break; }
//             std::cout << T::string( p->status ) << std::endl;
//         }
//     }
// };

template<typename T>
struct full_description
{
    comma::csv::input_stream< status_data > is;
    bool json;
    full_description( const comma::command_line_options& options ) : is( std::cin, comma::csv::options( options ) ),json(options.exists("--json")) { }
    void process()
    {
        while( std::cin.good() )
        {
            const status_data* p = is.read();
            if( !p ) { break; }
            T description(p->status);
            boost::property_tree::ptree ptree;
            comma::to_ptree to_ptree( ptree, comma::xpath() );
            comma::visiting::apply( to_ptree ).to( description );
            std::cout.precision( 16 ); // quick and dirty
            if(json)
            {
//                 comma::write_json(description,std::cout);
                boost::property_tree::write_json( std::cout, ptree, false );
            }
            else
            {
//                 comma::write_path_value(description,std::cout);
                std::string s=comma::property_tree::to_path_value_string( ptree, comma::property_tree::disabled, '=', ';' );
                std::cout<<std::regex_replace(s,std::regex("\"([0-9]*)\""),"$1")<<std::endl;
            }
        }
    }
};

static void bash_completion( int argc, char** argv )
{
    std::cout << "--help --verbose" <<
        " all magnetic-calibration navigation raw-sensors system-state satellites " <<
        " --magnetic-calibration-description --output-fields --output-format --raw --send --stdin --status --status-description --json"<<
        std::endl;
}

struct send_factory_i
{
    virtual ~send_factory_i() { }
    virtual void input_fields()=0;
    virtual void input_format()=0;
    virtual unsigned run(const comma::command_line_options& options)=0;
};

template<typename T>
struct send_factory_t : public send_factory_i
{
    typedef T type;
    void input_fields() { T::input_fields(); }
    void input_format() { T::input_format(); }
    unsigned run(const comma::command_line_options& options)
    {

        T app(options);
        return app.process();
    }
};

template <typename T>
struct send_app : protected device
{
    comma::csv::input_stream<T> is;
    unsigned result;
    send_app(const comma::command_line_options& options) :
        device(options.value<std::string>("--device"),options.value<unsigned>("--baud-rate,--baud",default_baud_rate)),
        is( std::cin, comma::csv::options( options ) )
    {

    }
    virtual void handle(const messages::acknowledgement* msg)
    {
        result=msg->result();
        std::cout<<result<<std::endl;
        comma::verbose<<messages::acknowledgement::result_msg(result)<<std::endl;
    }
    unsigned process()
    {
        while(std::cin.good())
        {
            const T* pt=is.read();
            if(!pt)
                break;
            messages::command cmd=pt->get_command();
            send(cmd);
        }
        return result;
    }
    static void input_fields()
    {
        std::cout<<comma::join( comma::csv::names<T>(true), ',' ) << std::endl;
    }
    static void input_format()    //const std::string& fields
    {
        //std::cout<<comma::csv::format::value<output_t>(fields, true) << std::endl;
        std::cout<<comma::csv::format::value<T>() << std::endl;
    }
};

tbb::concurrent_bounded_queue<ntrip::item_t> ntrip::queue;

int main( int argc, char** argv )
{
    try
    {
        comma::command_line_options options( argc, argv, usage );

        if(options.exists("--bash-completion")) { bash_completion( argc, argv ); return 0; }

        std::vector<std::string> unnamed=options.unnamed( comma::csv::options::valueless_options()+ ",--verbose,-v,--output-fields,--output-format,--raw,--stdin,--flush, --json", "-.*" );
        flush=options.exists("--flush");

//         auto opt_description=options.optional<std::string>("--description");
//         if(opt_description)
//         {
//             if( *opt_description == "system_status" ) { description< messages::system_status_description >( options ).process(); }
//             else if( *opt_description == "filter_status" ) { description< messages::filter_status_description >( options ).process(); }
//             else { COMMA_THROW( comma::exception, "invalid field for description. expected 'system_status' or 'filter_status', got " << *opt_description ); }
//             return 0;
//         }
        auto opt_full_description=options.optional<std::string>("--status");
        if(opt_full_description)
        {
            if( *opt_full_description == "system_status" ) { full_description< messages::system_status_description >( options ).process(); }
            else if( *opt_full_description == "filter_status" ) { full_description< messages::filter_status_description >( options ).process(); }
            else { COMMA_THROW( comma::exception, "invalid field for --status. expected 'system_status' or 'filter_status', got " << *opt_full_description ); }
            return 0;
        }
        auto opt_status_description=options.optional<std::string>("--status-description");
        if(opt_status_description)
        {
            if( *opt_status_description == "system_status" ) { messages::system_status_description::descroption(std::cout); }
            else if( *opt_status_description == "filter_status" ) { messages::filter_status_description::descroption(std::cout); }
            else if( *opt_status_description == "gnss_fix" ) { messages::filter_status_description::gnss_fix_descroption(std::cout); }
            else { COMMA_THROW( comma::exception, "invalid field for --status-description. expected 'system_status' or 'filter_status' or 'gnss_fix', got " << *opt_status_description ); }
            return 0;
        }
        if(options.exists("--magnetic-calibration-description")) { messages::magnetic_calibration_status::status_description(std::cout); return 0; }

        auto opt_send=options.optional<std::string>("--send");
        if(opt_send)
        {
            std::unique_ptr<send_factory_i> sf;
            if(*opt_send == "magnetic-calibration") { sf.reset(new send_factory_t<send_app<messages::magnetic_calibration_configuration>>()); }
            else { COMMA_THROW(comma::exception,"invalid send command: "<<*opt_send); }

            if(options.exists("--input-fields")) { sf->input_fields(); return 0; }
            if(options.exists("--input-format")) { sf->input_format(); return 0; }

            return sf->run(options);
        }

        std::unique_ptr<factory_i> factory;
        if(options.exists("--raw"))
        {
            factory.reset(new factory_t<app_raw>());
        }
        else
        {
            if(unnamed.size()!=1) { COMMA_THROW( comma::exception, "expected one unnamed arguement, got: "<<unnamed.size()); }
            if(unnamed[0]=="navigation") { factory.reset(new factory_t<app_nav>()); }
            else if(unnamed[0]=="all") { factory.reset(new factory_t<app_all>()); }
            else if(unnamed[0]=="raw-sensors") { factory.reset(new factory_t<app_packet<messages::raw_sensors>>()); }
            else if(unnamed[0]=="system-state") { factory.reset(new factory_t<app_packet<messages::system_state>>()); }
            else if(unnamed[0]=="satellites") { factory.reset(new factory_t<app_packet<messages::satellites>>()); }
            else if(unnamed[0]=="magnetic-calibration") { factory.reset(new factory_t<app_packet<messages::magnetic_calibration_status>>()); }
            else { COMMA_THROW( comma::exception,"expected <what>: navigation | raw-sensors | system-state | all; got "<<unnamed[0]);}
        }

        if(options.exists("--output-fields")) { factory->output_fields(); return 0; }
        if(options.exists("--output-format")) { factory->output_format(); return 0; }

        std::unique_ptr<ntrip_thread> ntt;
        auto opt_ntrip=options.optional<std::string>("--ntrip");
        if(opt_ntrip) { ntt.reset(new ntrip_thread(*opt_ntrip,options)); }

        std::string input;
        if(options.exists("--stdin"))
        {
            input="-";
            if(options.exists("--device")) { COMMA_THROW( comma::exception, "--stdin conflicts with --device"); }
            if(opt_ntrip) { COMMA_THROW( comma::exception, "--stdin conflicts with --ntrip"); }
            comma::csv::detail::unsynchronize_with_stdio();
        }
        else
        {
            input=options.value<std::string>("--device");
        }

        factory->run(input,options);

        return 0;
    }
    catch(snark::navigation::advanced_navigation::eois_exception& e)
    {
        // normal exit on end of input stream
        comma::verbose<<comma::verbose.app_name() << ": " << e.what() << std::endl;
        return 0;
    }
    catch( std::exception& ex ) { std::cerr << comma::verbose.app_name() << ": " << ex.what() << std::endl; }
    catch( ... ) { std::cerr << comma::verbose.app_name() << ": " << "unknown exception" << std::endl; }
    return 1;
}


text:
// Copyright David Abrahams 2002.
// 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)

#include <boost/python/extract.hpp>
#include <boost/python/list.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/reference_existing_object.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/implicit.hpp>
#include <string>
#include <boost/lexical_cast.hpp>
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include "test_class.hpp"

using namespace boost::python;

typedef test_class<> X;

bool extract_bool(object x) { return extract<bool>(x); }

boost::python::list extract_list(object x)
{
    extract<list> get_list((x));

    // Make sure we always have the right idea about whether it's a list
    bool is_list_1 = get_list.check();
    bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type);
    if (is_list_1 != is_list_2) {
        throw std::runtime_error("is_list_1 == is_list_2 failure.");
    }
    return get_list();
}

char const* extract_cstring(object x)
{
    return extract<char const*>(x);
}

std::string extract_string(object x)
{
    std::string s = extract<std::string>(x);
    return s;
}

std::string const& extract_string_cref(object x)
{
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
# pragma warning(push)
# pragma warning(disable:4172) // msvc lies about returning a reference to temporary
#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 900
# pragma warning(push)
# pragma warning(disable:473) // intel/win32 does too
#endif

    return extract<std::string const&>(x);

#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 800
# pragma warning(pop)
#endif
}

X extract_X(object x)
{
    return extract<X>(x);
}

X* extract_X_ptr(object x) { return extract<X*>(x); }

X& extract_X_ref(object x)
{
    extract<X&> get_x(x);
    return get_x;
}

int double_X(object n)
{
    extract<X> x(n);
    return x().value() + x().value();
}

bool check_bool(object x) { return extract<bool>(x).check(); }
bool check_list(object x) { return extract<list>(x).check(); }
bool check_cstring(object x) { return extract<char const*>(x).check(); }
bool check_string(object x) { return extract<std::string>(x).check(); }
bool check_string_cref(object x) { return extract<std::string const&>(x).check(); }
bool check_X(object x) { return extract<X>(x).check(); }
bool check_X_ptr(object x) { return extract<X*>(x).check(); }
bool check_X_ref(object x) { return extract<X&>(x).check(); }

std::string x_rep(X const& x)
{
    return "X("  + boost::lexical_cast<std::string>(x.value()) + ")";
}

BOOST_PYTHON_MODULE(extract_ext)
{
    implicitly_convertible<int, X>();

    def("extract_bool", extract_bool);
    def("extract_list", extract_list);
    def("extract_cstring", extract_cstring);
    def("extract_string", extract_string);
    def("extract_string_cref", extract_string_cref, return_value_policy<reference_existing_object>());
    def("extract_X", extract_X);
    def("extract_X_ptr", extract_X_ptr, return_value_policy<reference_existing_object>());
    def("extract_X_ref", extract_X_ref, return_value_policy<reference_existing_object>());

    def("check_bool", check_bool);
    def("check_list", check_list);
    def("check_cstring", check_cstring);
    def("check_string", check_string);
    def("check_string_cref", check_string_cref);
    def("check_X", check_X);
    def("check_X_ptr", check_X_ptr);
    def("check_X_ref", check_X_ref);

    def("double_X", double_X);

    def("count_Xs", &X::count);
        ;

    object x_class(
        class_<X>("X", init<int>())
            .def( "__repr__", x_rep));

    // Instantiate an X object through the Python interface
    object x_obj = x_class(3);

    // Get the C++ object out of the Python object
    X const& x = extract<X&>(x_obj);
    if (x.value() != 3) {
        throw std::runtime_error("x.value() == 3 failure.");
    }
}

#include "module_tail.cpp"

max_stars_repo_name: zyiacas/boost-doc-zh

max_issues_repo_name: alexa-infra/negine

max_forks_repo_name: alexa-infra/negine