text:
/**
 * @file basic_monomial.hh
 * @author  李昊坤 (ker@pm.me)
 * @brief 定义类：basic_monomial
 *
 */

#ifndef CLPOLY_BASIC_MONOMIAL_HH
#define CLPOLY_BASIC_MONOMIAL_HH
#include <clpoly/variable.hh>
#include <clpoly/basic.hh>
#include <vector>
#include <functional>
#include <list>
#include <iostream>
#include <sstream>
#include <string>
#include <cassert>
#include <boost/container_hash/hash.hpp>

namespace clpoly{
    template <class compare>
    class basic_monomial
    {
        private:
            std::vector<std::pair<variable,int64_t>> __data;
            int64_t __deg=0;
            const compare* __comp= &compare::init;
        public:
            typedef compare compare_type;
            typedef variable first_type;
            typedef int64_t second_type;
            typedef typename std::vector<std::pair<variable,int64_t>>::iterator iterator;
            typedef typename std::vector<std::pair<variable,int64_t>>::const_iterator  const_iterator ;
            // static compare init_comp;

            constexpr int64_t deg() const {return this->__deg;}
            constexpr int64_t & deg() {return this->__deg;}
            inline int64_t re_deg()
            {
                this->__deg=0;
                for(auto &&i:this->__data)
                    this->__deg+=i.second;
                return this->__deg;
            }
            inline bool is_normal()  const
            {
                int64_t tmp_deg=0;
                for(auto &&i:this->__data)
                    tmp_deg+=i.second;
                return tmp_deg==this->__deg && pair_vec_normal_check(this->__data,this->comp());
            }
            inline void normalization()
            {
                auto tmp_size=pair_vec_normalization(this->__data,pair_compare<variable,int64_t,compare>(this->__comp));
                this->__data.resize(tmp_size);
                if (this->__data.size()*1.0/this->__data.capacity()<CLPOLY_shrink_bound && this->__data.capacity()>CLPOLY_shrink_bound_abs)
                {
                    //std::cout<<"shrink_to_fit";
                    this->__data.shrink_to_fit();
                }
                this->re_deg();
            }
            basic_monomial():__data(),__deg(0){}
            basic_monomial(const compare * c):__data(),__deg(0),__comp(c){}
            basic_monomial(const basic_monomial<compare> &m)
            :__data(m.__data),__deg(m.__deg),__comp(m.__comp)
            {}
            // explicit
            basic_monomial(const variable & v)
            :__data({{v,1}}),__deg(1)
            {}
            basic_monomial(basic_monomial<compare> &&m)
            :__data(std::move(m.__data)),__deg(std::move(m.__deg)),__comp(m.__comp)
            {
                m.clear();
            }
            basic_monomial( std::initializer_list<std::pair<variable,int64_t>> init)
            :__data(init)
            {
                this->normalization();
            }
            basic_monomial(const std::vector<std::pair<variable,int64_t>> & v)
            :__data(v)
            {
                this->normalization();
            }
            basic_monomial(std::vector<std::pair<variable,int64_t>> && v)
            :__data(std::move(v))
            {
                this->normalization();
            }

            basic_monomial<compare> & operator=(const variable &v)
            {
                this->__data={{v,1}};
                this->__deg=1;
                return *this;
            }
            basic_monomial<compare> & operator=(const basic_monomial<compare> & m)
            {
                if (&m==this)
                    return *this;
                this->__data=m.__data;
                this->__deg=m.__deg;
                this->__comp=m.__comp;
                return *this;
            }
            basic_monomial<compare> & operator=(basic_monomial<compare> && m)
            {
                if (&m==this)
                    return *this;
                this->__data=std::move(m.__data);
                this->__deg=std::move(m.__deg);
                this->__comp=m.__comp;
                m.clear();
                return *this;
            }
            basic_monomial<compare> & operator=( std::initializer_list<std::pair<variable,int64_t>> init)
            {
                this->__data=init;
                this->normalization();
                return *this;
            }
            basic_monomial<compare> & operator=(const std::vector<std::pair<variable,int64_t>> & init)
            {
                this->__data=init;
                this->normalization();
                return *this;
            }
            basic_monomial<compare> & operator=(std::vector<std::pair<variable,int64_t>> && init)
            {
                this->__data=std::move(init);
                this->normalization();
                return *this;
            }

            constexpr auto size() const {return this->__data.size();}
            constexpr iterator begin() {return this->__data.begin();}
            constexpr const_iterator begin() const {return this->__data.begin();}

            constexpr iterator end() {return this->__data.end();}
            constexpr const_iterator end() const {return this->__data.end();}

            constexpr std::pair<variable,int64_t>& front() {return this->__data.front();}
            constexpr const std::pair<variable,int64_t>& front() const {return this->__data.front();}
            constexpr std::pair<variable,int64_t>& back() {return this->__data.back();}
            constexpr const std::pair<variable,int64_t>& back() const {return this->__data.back();}
            constexpr void resize(std::size_t size){this->__data.resize(size);}
            constexpr void reserve(std::size_t size){this->__data.reserve(size);}
            inline void pop_back(){this->__deg-=this->back().second;this->__data.pop_back();}
            inline void push_back(const std::pair<variable,int64_t>&  value ){
                this->__deg+=value.second;
                this->__data.push_back(value);
            }
            inline void push_back(std::pair<variable,int64_t>&&  value){
                this->__deg+=value.second;
                this->__data.push_back(std::move(value));
            }
            constexpr std::pair<variable,int64_t>& operator[](std::size_t pos){return this->__data[pos];}
            constexpr const std::pair<variable,int64_t>& operator[](std::size_t pos) const {return this->__data[pos];}
            constexpr std::pair<variable,int64_t>& at(std::size_t pos){return this->__data.at(pos);}
            constexpr const std::pair<variable,int64_t>& at(std::size_t pos) const {return this->__data.at(pos);}
            constexpr bool empty()const{return this->__data.empty();}
            constexpr std::vector<std::pair<variable,int64_t>> & data() {return this->__data;}
            constexpr const std::vector<std::pair<variable,int64_t>> & data() const {return this->__data;}
            constexpr const compare & comp() const {return *(this->__comp);}
            //constexpr compare & comp() {return *(this->__comp);}
            inline bool comp(const variable & a,const variable &b)const {return (*this->__comp)(a,b);}
            constexpr void comp( const compare * c){this->__comp=c;}
            constexpr const compare * comp_ptr() const {return this->__comp;}
            inline void clear()
            {
                this->__data.clear();
                this->__deg=0;
            }
            inline void swap(basic_monomial<compare> &m)
            {
                this->__data.swap(m.__data);
                std::swap(this->__deg,m.__deg);
                std::swap(this->__comp,m.__comp);
            }
            friend inline basic_monomial operator*  (const basic_monomial &p1,const basic_monomial &p)
            {
                assert(p1.__comp==p.__comp || p1.comp()==p.comp());
                // #ifdef DEBUG
                //     if (!pair_vec_normal_check(p1.begin(),p1.end(),p1.comp()))
                //         throw std::invalid_argument("Left basic_monomial is not normal.");
                //     if (!pair_vec_normal_check(p.begin(),p.end(),p1.comp()))
                //         throw std::invalid_argument("Right basic_monomial is not normal.(In left comparation.)");
                //     std::asser
                // #endif
                basic_monomial new_p(p1.__comp);
                pair_vec_add(new_p.__data,p1.__data,p.__data,p1.comp());
                __auto_shrink(new_p.__data);
                new_p.__deg=p1.__deg+p.__deg;
                return new_p;
            }
            friend inline basic_monomial operator/  (const basic_monomial &p1,const basic_monomial &p)
            {
                assert(p1.__comp==p.__comp || p1.comp()==p.comp());
                // #ifdef DEBUG
                //     if (!pair_vec_normal_check(p1.begin(),p1.end(),p1.comp))
                //         throw std::invalid_argument("Left basic_monomial is not normal.");
                //     if (!pair_vec_normal_check(p.begin(),p.end(),p1.comp))
                //         throw std::invalid_argument("Right basic_monomial is not normal.(In left comparation.)");
                // #endif
                basic_monomial new_p(p1.__comp);
                pair_vec_sub(new_p.__data,p1.__data,p.__data,p1.comp());
                __auto_shrink(new_p.__data);
                new_p.__deg=p1.__deg-p.__deg;
                return new_p;
            }

            // inline basic_monomial  power(unsigned i) const
            // {
            //     basic_monomial newp;
            //     newp.comp(this->__comp);
            //     if (this->empty() || i==0)
            //         return newp;
            //     basic_monomial p(*this);
            //     while (i!=0)
            //     {
            //         if (i%2!=0)
            //             newp=newp*p;
            //         i>>=1;
            //         if (i!=0)
            //             p=p*p;
            //     }
            //     return newp;
            // }

            inline bool operator> (const basic_monomial<compare> &p) const
            {
                assert(this->__comp==p.__comp || this->comp()==p.comp());
                // #ifdef DEBUG
                //     if (!pair_vec_normal_check(this->begin(),this->end(),this->comp))
                //         throw std::invalid_argument("Left basic_monomial is not normal.");
                //     if (!pair_vec_normal_check(p.begin(),p.end(),this->comp))
                //         throw std::invalid_argument("Right basic_monomial is not normal.(In left comparation.)");
                // #endif
                // if (this->deg()==p.deg())
                //     return pair_vec_comp(this->__data,p.__data,this->comp);
                return (this->deg()>p.deg()) || ( this->deg()==p.deg() && pair_vec_comp(this->__data,p.__data,this->comp()));
            }
            inline bool operator== (const basic_monomial<compare> &p) const
            {
                assert(this->__comp==p.__comp || this->comp()==p.comp());
                // #ifdef DEBUG
                //     if (!pair_vec_normal_check(this->begin(),this->end(),this->comp))
                //         throw std::invalid_argument("Left basic_monomial is not normal.");
                //     if (!pair_vec_normal_check(p.begin(),p.end(),this->comp))
                //         throw std::invalid_argument("Right basic_monomial is not normal.(In left comparation.)");
                // #endif
                // if (this->deg()==p.deg())
                //     return pair_vec_equal_to(p.__data,this->__data);
                return (this->deg()==p.deg() && pair_vec_equal_to(p.__data,this->__data));
            }
            constexpr bool operator< (const basic_monomial<compare> &p) const
            {
                return (p>*this);
            }
            constexpr bool operator<=(const basic_monomial<compare> &p) const
            {
                return !(*this>p);
            }
            constexpr bool operator>=(const basic_monomial<compare> &p) const
            {
                return !(p>*this);
            }
            constexpr bool operator!=(const basic_monomial<compare> &p) const
            {
                return !(*this==p);
            }

            // inline basic_monomial operator-   () const
            // {
            //     return *this;
            // }
            // inline basic_monomial operator+ () const
            // {
            //     basic_monomial new_m;
            //     new_m.reserve(this->size());
            //     for (auto &&i:*this)
            //     {
            //         new_m.push_back({i.first,negate(i.second)});
            //     }
            //     new_m.comp=this->comp;
            //     return new_m;
            // }
            inline const_iterator find(const variable & m) const
            {
                // std::function<bool(const std::pair<variable,int16_t> &,const std::pair<variable,int16_t> &)> tmp_comp=
                //     [&](std::pair<variable,int16_t> a,std::pair<variable,int16_t> b){return (this->comp(a.first,b.first));};
                // return pair_vec_find_first(this->begin(),this->end(),
                //     std::pair<variable,int16_t>(m,0),pair_compare<variable,int64_t,compare>(this->__comp));
                const_iterator i=this->begin();
                while (i!=this->end() && i->first!=m)
                    ++i;
                return i;
            }
            inline iterator find(const variable & m)
            {
                // std::function<bool(const std::pair<variable,int16_t> &,const std::pair<variable,int16_t> &)> tmp_comp=
                //     [&](std::pair<variable,int16_t> a,std::pair<variable,int16_t> b){return (this->comp(a.first,b.first));};
                // return pair_vec_find_first(this->begin(),this->end(),
                //     std::pair<variable,int16_t>(m,0),pair_compare<variable,int64_t,compare>(this->__comp));
                iterator i=this->begin();
                while (i!=this->end() && i->first!=m)
                    ++i;
                return i;
            }
            inline int64_t deg(const variable & m) const
            {
                auto l=this->find(m);
                if (l!=this->end())
                    return l->second;
                else
                    return 0;
            }
            // inline int64_t & deg(const variable & m)
            // {
            //     auto l=this->find(m);
            //     if (l!=this->end())
            //         return l->second;
            //     else
            //         return 0;
            // }
            friend std::ostream& operator<<  (std::ostream& stream, const basic_monomial<compare>& v) {
                if (v.empty())
                    return stream<<'1';
                bool is_print=false;
                for (const auto &i:v.data())
                {
                    // if (i.second!=0)
                    // {
                        if (is_print)
                            stream<<"*";
                        stream<<i.first;
                        is_print=true;
                        if (i.second!=1)
                            stream<<"^"<<i.second;
                    // }
                }
                return stream;
            }
            std::string  str() const{
                if (this->empty())
                    return "1";
                std::ostringstream ss;
                // bool is_print=false;
                // for (auto&&i:this->__data)
                // {
                //     if (i.second!=0)
                //     {
                //         if (is_print)
                //             ss<<"*";
                //         ss<<i.first;
                //         is_print=true;
                //         if (i.second!=1)
                //             ss<<"^"<<i.second;
                //     }
                // }
                ss<<(*this);
                return ss.str();
            }

    };
    // template<class compare>  compare basic_monomial<compare>::init_comp=compare();
    // template<class compare>
    // void swap(basic_monomial<compare> & v1,basic_monomial<compare> & v2)
    // {
    //     v1.swap(v2);
    // }
    template<class compare>
    std::size_t hash_value(const basic_monomial<compare>& b)
    {
        boost::hash<std::vector<std::pair<variable,int64_t>>> hasher;
        return hasher(b.data());
    }

}
namespace std{
    template<class compare>
    struct hash<clpoly::basic_monomial<compare>>: public std::unary_function<clpoly::basic_monomial<compare>, std::size_t>
    {
        std::size_t operator()(const clpoly::basic_monomial<compare> & m) const
        {
            return clpoly::hash_value(m);
        }
    };
}
#endif

ext: hh

max_stars_repo_name: Ntimesp/CLPoly

max_issues_repo_name: Ntimesp/CLPoly

max_forks_repo_name: Ntimesp/CLPoly


text:
/**
Copyright (c)
Audi Autonomous Driving Cup. 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.  All advertising materials mentioning features or use of this software must
display the following acknowledgement: “This product includes software developed
by the Audi AG and its contributors for Audi Autonomous Driving Cup.”
4.  Neither the name of Audi 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 AUDI AG 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 AUDI AG 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:: kuckal  $  $Date:: 2017-05-22 10:14:17#$ $Rev:: 63667   $
**********************************************************************/

#include "stdafx.h"
#include <boost/thread.hpp>
#include <unistd.h>   // usleep, wait for thread to finish
#include "opencv_tools.h"  // AdtfMediaSampleToCvMat
#include "cMarkerDetector.h"
#include "aadc_roadSign_enums.h"

using namespace cv;

ADTF_FILTER_PLUGIN("frAiburg Marker Detector Plugin", OID_FRAIBURG_MARKERDETECTFILTER,
                   cMarkerDetector)

cMarkerDetector::cMarkerDetector(const tChar* __info) : cFilter(__info) {
    SetPropertyBool("Debug Output to Console", tFalse);
    SetPropertyStr("Debug Output to Console" NSSUBPROP_DESCRIPTION,
                   "If enabled additional debug information is printed to the "
                   "console (Warning: decreases performance).");

    SetPropertyStr("Calibration File for used Camera", "");
    SetPropertyBool("Calibration File for used Camera" NSSUBPROP_FILENAME,
                    tTrue);
    SetPropertyStr("Calibration File for used Camera" NSSUBPROP_FILENAME
                       NSSUBSUBPROP_EXTENSIONFILTER,
                   "YML Files (*.yml)");
    SetPropertyStr("Calibration File for used Camera" NSSUBPROP_DESCRIPTION,
                   "Here you have to set the file with calibration paraemters "
                   "of the used camera");

    SetPropertyStr("Detector Paramater File", "");
    SetPropertyBool("Detector Paramater File" NSSUBPROP_FILENAME, tTrue);
    SetPropertyStr("Detector Paramater File" NSSUBPROP_FILENAME
                       NSSUBSUBPROP_EXTENSIONFILTER,
                   "YML Files (*.yml)");
    SetPropertyStr("Detector Paramater File" NSSUBPROP_DESCRIPTION,
                   "Here you have to set the file with the parameters with the "
                   "detector params");

    SetPropertyFloat("Size of Markers", 0.117f);
    SetPropertyStr("Size of Markers" NSSUBPROP_DESCRIPTION,
                   "Size (length of one side) of markers in m");

    SetPropertyFloat("FPS max", 10.0);
    SetPropertyStr("FPS max" NSSUBPROP_DESCRIPTION, "Max. fps");

    UCOM_REGISTER_TIMING_SPOT(cString(OIGetInstanceName()) + "::Process::Start",
                              m_oProcessStart);
    UCOM_REGISTER_TIMING_SPOT(cString(OIGetInstanceName()) + "::Process::End",
                              m_oProcessEnd);
    UCOM_REGISTER_TIMING_SPOT(
        cString(OIGetInstanceName()) + "::MarkerDetection::Start",
        m_oPreMarkerDetect);
    UCOM_REGISTER_TIMING_SPOT(
        cString(OIGetInstanceName()) + "::MarkerDetection::End",
        m_oPostMarkerDetect);
    UCOM_REGISTER_TIMING_SPOT(
        cString(OIGetInstanceName()) + "::PoseEstimation::Start",
        m_oPrePoseEstimation);
    UCOM_REGISTER_TIMING_SPOT(
        cString(OIGetInstanceName()) + "::PoseEstimation::End",
        m_oPostPoseEstimation);

    thread_is_active_ = false;
    timestamp_last_update_ = 0;
}

cMarkerDetector::~cMarkerDetector() {}

tResult cMarkerDetector::Init(tInitStage eStage, __exception) {
    RETURN_IF_FAILED(cFilter::Init(eStage, __exception_ptr));
    if (eStage == StageFirst) {
        // create the video rgb input pin
        RETURN_IF_FAILED(
            m_oPinInputVideo.Create("Video_RGB_input", IPin::PD_Input,
                                    static_cast<IPinEventSink*>(this)));
        RETURN_IF_FAILED(RegisterPin(&m_oPinInputVideo));

        // create the video rgb output pin
        RETURN_IF_FAILED(
            m_oPinOutputVideo.Create("Video_RGB_output", IPin::PD_Output,
                                     static_cast<IPinEventSink*>(this)));
        RETURN_IF_FAILED(RegisterPin(&m_oPinOutputVideo));

        // create the description manager
        cObjectPtr<IMediaDescriptionManager> pDescManager;
        RETURN_IF_FAILED(_runtime->GetObject(OID_ADTF_MEDIA_DESCRIPTION_MANAGER,
                                             IID_ADTF_MEDIA_DESCRIPTION_MANAGER,
                                             (tVoid**)&pDescManager,
                                             __exception_ptr));

        // create the description for the road sign pin
        tChar const* strDesc = pDescManager->GetMediaDescription("tRoadSign");
        RETURN_IF_POINTER_NULL(strDesc);
        cObjectPtr<IMediaType> pType =
            new cMediaType(0, 0, 0, "tRoadSign", strDesc,
                           IMediaDescription::MDF_DDL_DEFAULT_VERSION);

        // create the road sign OutputPin
        RETURN_IF_FAILED(m_oPinRoadSign.Create("RoadSign", pType, this));
        RETURN_IF_FAILED(RegisterPin(&m_oPinRoadSign));
        // set the description for the road sign pin
        RETURN_IF_FAILED(pType->GetInterface(IID_ADTF_MEDIA_TYPE_DESCRIPTION,
                                             (tVoid**)&m_pDescriptionRoadSign));

        // create the description for the road sign pin
        tChar const* strDescExt =
            pDescManager->GetMediaDescription("tRoadSignExt");
        RETURN_IF_POINTER_NULL(strDescExt);
        cObjectPtr<IMediaType> pTypeExt =
            new cMediaType(0, 0, 0, "tRoadSignExt", strDescExt,
                           IMediaDescription::MDF_DDL_DEFAULT_VERSION);

        // create the extended road sign OutputPin
        RETURN_IF_FAILED(
            m_oPinRoadSignExt.Create("RoadSign_ext", pTypeExt, this));
        RETURN_IF_FAILED(RegisterPin(&m_oPinRoadSignExt));
        // set the description for the extended road sign pin
        RETURN_IF_FAILED(
            pTypeExt->GetInterface(IID_ADTF_MEDIA_TYPE_DESCRIPTION,
                                   (tVoid**)&m_pDescriptionRoadSignExt));

        //*** create and register the output pin 1***//
        cObjectPtr<IMediaType> pTypeOut_GCL;
        RETURN_IF_FAILED(AllocMediaType(
            (tVoid**)&pTypeOut_GCL, MEDIA_TYPE_COMMAND,
            MEDIA_SUBTYPE_COMMAND_GCL, NULL, NULL, __exception_ptr));
        RETURN_IF_FAILED(m_outputPinGCL.Create(
            "GCL_Markers", pTypeOut_GCL, static_cast<IPinEventSink*>(this)));
        RETURN_IF_FAILED(RegisterPin(&m_outputPinGCL));

    } else if (eStage == StageNormal) {
        // get the propeerties
        m_f32MarkerSize =
            static_cast<tFloat32>(GetPropertyFloat("Size of Markers"));
        m_bDebugModeEnabled = GetPropertyBool("Debug Output to Console");
        m_bCamaraParamsLoaded = tFalse;

        // Get path of detector parameter file
        cFilename fileDetectorParameter =
            GetPropertyStr("Detector Paramater File");
        if (fileDetectorParameter.IsEmpty()) {
            THROW_ERROR_DESC(ERR_INVALID_FILE,
                             "Detector Parameter File for Markers not set");
        }
        // create absolute path for marker configuration file
        ADTF_GET_CONFIG_FILENAME(fileDetectorParameter);
        fileDetectorParameter = fileDetectorParameter.CreateAbsolutePath(".");
        // check if marker configuration file exits
        if (!(cFileSystem::Exists(fileDetectorParameter))) {
            THROW_ERROR_DESC(ERR_INVALID_FILE,
                             "Detector Parameter file for Markers not found");
        }
        // create the detector params
        m_detectorParams = aruco::DetectorParameters::create();
        if (!(readDetectorParameters(fileDetectorParameter.GetPtr(),
                                     m_detectorParams))) {
            THROW_ERROR_DESC(ERR_INVALID_FILE,
                             "Detector Parameter file not valid");
        }

        m_Dictionary = aruco::getPredefinedDictionary(aruco::DICT_5X5_50);

        // Get path of calibration file with camera paramters
        cFilename fileCalibration =
            GetPropertyStr("Calibration File for used Camera");

        if (fileCalibration.IsEmpty()) {
            THROW_ERROR_DESC(ERR_INVALID_FILE,
                             "Calibration File for camera not set");
        }

        // Get path of calibration file with camera paramters
        ADTF_GET_CONFIG_FILENAME(fileCalibration);
        fileCalibration = fileCalibration.CreateAbsolutePath(".");
        // check if calibration file with camera paramters exits
        if (!(cFileSystem::Exists(fileCalibration))) {
            THROW_ERROR_DESC(ERR_INVALID_FILE,
                             "Calibration File for camera not found");
        }

        // read the calibration file with camera paramters exits and save to
        // member variable
        readCameraParameters(fileCalibration.GetPtr(), m_Intrinsics,
                             m_Distorsion);
        m_bCamaraParamsLoaded = tTrue;

        max_fps_ = GetPropertyFloat("FPS max");

    } else if (eStage == StageGraphReady) {
        // get the image format of the input video pin
        cObjectPtr<IMediaType> pType;
        RETURN_IF_FAILED(m_oPinInputVideo.GetMediaType(&pType));

        cObjectPtr<IMediaTypeVideo> pTypeVideo;
        RETURN_IF_FAILED(pType->GetInterface(IID_ADTF_MEDIA_TYPE_VIDEO,
                                             (tVoid**)&pTypeVideo));

        // set the image format of the input video pin
        UpdateInputImageFormat(pTypeVideo->GetFormat());

        // set the image format of the output video pin
        UpdateOutputImageFormat(pTypeVideo->GetFormat());

        // IDs were not set yet
        m_bIDsRoadSignExtSet = tFalse;
        m_bIDsRoadSignSet = tFalse;
    }
    RETURN_NOERROR;
}

tResult cMarkerDetector::Shutdown(tInitStage eStage, __exception) {
    while (thread_is_active_) {
        usleep(100000);
    }
    return cFilter::Shutdown(eStage, __exception_ptr);
}

tResult cMarkerDetector::OnPinEvent(IPin* pSource, tInt nEventCode,
                                    tInt nParam1, tInt nParam2,
                                    IMediaSample* pMediaSample) {
    switch (nEventCode) {
        case IPinEventSink::PE_MediaSampleReceived:
            // a new image was received so the processing is started
            if (pSource == &m_oPinInputVideo) {
                float span = (_clock->GetStreamTime() - timestamp_last_update_);
                float fps_span = ((1.0 / max_fps_) * 1e6);
                if (thread_is_active_ | (span < fps_span)) {
                    RETURN_NOERROR;
                }
                timestamp_last_update_ = _clock->GetStreamTime();
                UCOM_TIMING_SPOT(m_oProcessStart);
                cv::Mat img = slim::cvtools::AdtfMediaSampleToCvMat(pMediaSample, m_sInputFormat);
                thread_is_active_ = true;
                boost::thread(&cMarkerDetector::ProcessVideo, this,
                              img, pMediaSample->GetTime());
                UCOM_TIMING_SPOT(m_oProcessEnd);
            }
            break;
        case IPinEventSink::PE_MediaTypeChanged:
            if (pSource == &m_oPinInputVideo) {
                // the input format was changed, so the imageformat has to
                // changed in this filter also
                cObjectPtr<IMediaType> pType;
                RETURN_IF_FAILED(m_oPinInputVideo.GetMediaType(&pType));

                cObjectPtr<IMediaTypeVideo> pTypeVideo;
                RETURN_IF_FAILED(pType->GetInterface(IID_ADTF_MEDIA_TYPE_VIDEO,
                                                     (tVoid**)&pTypeVideo));

                UpdateInputImageFormat(m_oPinInputVideo.GetFormat());
                UpdateOutputImageFormat(m_oPinInputVideo.GetFormat());
            }
            break;
        default:
            break;
    }
    RETURN_NOERROR;
}

tResult cMarkerDetector::ProcessVideo(cv::Mat img, tTimeStamp timestamp) {
    // the results from aruco detection
    vector<int> ids;
    vector<vector<Point2f> > corners, rejected;
    vector<Vec3d> rvecs, tvecs;
    // receiving data from input sample, and saving to inputImage
    UCOM_TIMING_SPOT(m_oPreMarkerDetect);
    // cv::Rect roi(300, 300, 400, 400);
    // cv::Mat roiImage(inputImage, roi);

    // doing the detection of markers in image
    aruco::detectMarkers(img, m_Dictionary, corners, ids,
                         m_detectorParams, rejected);
    // aruco::detectMarkers(roiImage, m_Dictionary, corners, ids,
    // m_detectorParams, rejected);

    UCOM_TIMING_SPOT(m_oPostMarkerDetect);
    UCOM_TIMING_SPOT(m_oPrePoseEstimation);

    // if we have the camera pararmeter available we calculate the pose
    if (m_bCamaraParamsLoaded && ids.size() > 0) {
        aruco::estimatePoseSingleMarkers(corners, m_f32MarkerSize, m_Intrinsics,
                                         m_Distorsion, rvecs, tvecs);
    }

    UCOM_TIMING_SPOT(m_oPostPoseEstimation);

    transmitGCL(ids, corners);

    if (m_oPinOutputVideo.IsConnected()) {
        // draw the marker on the image
        aruco::drawDetectedMarkers(img, corners, ids);
        if (m_bCamaraParamsLoaded && ids.size() > 0) {
            for (unsigned int i = 0; i < ids.size(); i++) {
                aruco::drawAxis(img, m_Intrinsics, m_Distorsion,
                                rvecs[i], tvecs[i], m_f32MarkerSize * 0.5f);
            }
        }
        // creating new media sample for output
        cObjectPtr<IMediaSample> pNewSample;
        if (IS_FAILED(AllocMediaSample((tVoid**)&pNewSample))) {
            thread_is_active_ = false;
            RETURN_NOERROR;
        }
        pNewSample->Update(timestamp, img.data,
                           m_sOutputFormat.nSize, 0);
        m_oPinOutputVideo.Transmit(pNewSample);
    }

    // print marker info and draw the markers in image
    for (unsigned int i = 0; i < ids.size(); i++) {
        // call the function to transmit a road sign sample with the detected
        // marker
        // call the function to transmit a extended road sign sample with the
        // detected marker if the Tvec in the marker was correctly set
        if (m_bCamaraParamsLoaded) {
            sendRoadSignStructExt(static_cast<tInt16>(ids[i]),
                                  getMarkerArea(corners[i]),
                                  timestamp, tvecs[i], rvecs[i]);
        } else {
            sendRoadSignStruct(static_cast<tInt16>(ids[i]),
                               getMarkerArea(corners[i]), timestamp);
        }
    }
    thread_is_active_ = false;
    RETURN_NOERROR;
}

tResult cMarkerDetector::UpdateInputImageFormat(const tBitmapFormat* pFormat) {
    if (pFormat != NULL) {
        m_sInputFormat = (*pFormat);

        // LOG_INFO(adtf_util::cString::Format(
        //     "Marker Detection Filter: Input: Size %d x %d ; BPL %d ; Size %d , "
        //     "PixelFormat; %d",
        //     m_sInputFormat.nWidth, m_sInputFormat.nHeight,
        //     m_sInputFormat.nBytesPerLine, m_sInputFormat.nSize,
        //     m_sInputFormat.nPixelFormat));
    }

    RETURN_NOERROR;
}

tResult cMarkerDetector::UpdateOutputImageFormat(const tBitmapFormat* pFormat) {
    if (pFormat != NULL) {
        m_sOutputFormat = (*pFormat);

        // LOG_INFO(adtf_util::cString::Format(
        //     "Marker Detection Filter: Output: Size %d x %d ; BPL %d ; Size %d, "
        //     "PixelFormat; %d",
        //     m_sOutputFormat.nWidth, m_sOutputFormat.nHeight,
        //     m_sOutputFormat.nBytesPerLine, m_sOutputFormat.nSize,
        //     m_sOutputFormat.nPixelFormat));

        m_oPinOutputVideo.SetFormat(&m_sOutputFormat, NULL);
    }

    RETURN_NOERROR;
}

tResult cMarkerDetector::sendRoadSignStruct(const tInt16& i16ID,
                                            const tFloat32& f32MarkerSize,
                                            const tTimeStamp& timeOfFrame) {
    // create new media sample
    cObjectPtr<IMediaSample> pMediaSample;
    RETURN_IF_FAILED(AllocMediaSample((tVoid**)&pMediaSample));

    // get the serializer
    cObjectPtr<IMediaSerializer> pSerializer;
    m_pDescriptionRoadSign->GetMediaSampleSerializer(&pSerializer);
    tInt nSize = pSerializer->GetDeserializedSize();

    // alloc the buffer memory
    RETURN_IF_FAILED(pMediaSample->AllocBuffer(nSize));

    {
        // focus for sample write lock
        // write date to the media sample with the coder of the descriptor
        __adtf_sample_write_lock_mediadescription(m_pDescriptionRoadSign,
                                                  pMediaSample, pCoder);

        // get IDs
        if (!m_bIDsRoadSignSet) {
            pCoder->GetID("i16Identifier", m_szIDRoadSignI16Identifier);
            pCoder->GetID("f32Imagesize", m_szIDRoadSignF32Imagesize);
            m_bIDsRoadSignSet = tTrue;
        }

        pCoder->Set(m_szIDRoadSignI16Identifier, (tVoid*)&i16ID);
        pCoder->Set(m_szIDRoadSignF32Imagesize, (tVoid*)&f32MarkerSize);

        pMediaSample->SetTime(timeOfFrame);
    }

    // doing the transmit
    RETURN_IF_FAILED(m_oPinRoadSign.Transmit(pMediaSample));

    // print debug info if activated
    if (m_bDebugModeEnabled)
        LOG_INFO(cString::Format("Sign ID %d detected. Area is: %f", i16ID,
                                 f32MarkerSize));

    RETURN_NOERROR;
}

tResult cMarkerDetector::sendRoadSignStructExt(const tInt16& i16ID,
                                               const tFloat32& f32MarkerSize,
                                               const tTimeStamp& timeOfFrame,
                                               const Vec3d& Tvec,
                                               const Vec3d& Rvec) {
    // create new media sample
    cObjectPtr<IMediaSample> pMediaSample;
    RETURN_IF_FAILED(AllocMediaSample((tVoid**)&pMediaSample));

    // get the serializer
    cObjectPtr<IMediaSerializer> pSerializer;
    m_pDescriptionRoadSignExt->GetMediaSampleSerializer(&pSerializer);
    tInt nSize = pSerializer->GetDeserializedSize();

    // alloc the buffer memory
    RETURN_IF_FAILED(pMediaSample->AllocBuffer(nSize));

    {
        // focus for sample write lock
        // write date to the media sample with the coder of the descriptor
        __adtf_sample_write_lock_mediadescription(m_pDescriptionRoadSignExt,
                                                  pMediaSample, pCoder);

        // get IDs
        if (!m_bIDsRoadSignExtSet) {
            pCoder->GetID("i16Identifier", m_szIDRoadSignExtI16Identifier);
            pCoder->GetID("f32Imagesize", m_szIDRoadSignExtF32Imagesize);
            pCoder->GetID("af32RVec[0]", m_szIDRoadSignExtAf32RVec);
            pCoder->GetID("af32TVec[0]", m_szIDRoadSignExtAf32TVec);
            m_bIDsRoadSignExtSet = tTrue;
        }

        pCoder->Set(m_szIDRoadSignExtI16Identifier, (tVoid*)&i16ID);
        pCoder->Set(m_szIDRoadSignExtF32Imagesize, (tVoid*)&f32MarkerSize);
        // convert from cv::Vec3D to array
        tFloat32 rvecFl32array[3] = {tFloat32(Rvec[0]), tFloat32(Rvec[1]),
                                     tFloat32(Rvec[2])};
        tFloat32 tvecFl32array[3] = {tFloat32(Tvec[0]), tFloat32(Tvec[1]),
                                     tFloat32(Tvec[2])};
        pCoder->Set("af32TVec", (tVoid*)&tvecFl32array[0]);
        pCoder->Set("af32RVec", (tVoid*)&rvecFl32array[0]);

        pMediaSample->SetTime(timeOfFrame);
    }
    // doing the transmit
    RETURN_IF_FAILED(m_oPinRoadSignExt.Transmit(pMediaSample));

    // print debug info if activated
    if (m_bDebugModeEnabled)
        LOG_INFO(
            cString::Format("Sign ID %d detected, translation is: %f, %f, %f",
                            i16ID, Tvec[0], Tvec[1], Tvec[2]));
    RETURN_NOERROR;
}

tResult cMarkerDetector::transmitGCL(const vector<int>& ids,
                                     const vector<vector<Point2f> >& corners) {
    IDynamicMemoryBlock* pGCLCmdDebugInfo;

    if ((ids.size() != corners.size()) || ids.size() == 0 ||
        corners.size() == 0) {
        cGCLWriter::GetDynamicMemoryBlock(pGCLCmdDebugInfo);
        cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_CLEAR);
        cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_END);
    } else {
        cGCLWriter::GetDynamicMemoryBlock(pGCLCmdDebugInfo);

        // set color
        cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_FGCOL,
                                 cColor::Red.GetRGBA());

        // iterate through all corners
        vector<int>::const_iterator itIds = ids.begin();
        for (vector<vector<Point2f> >::const_iterator it = corners.begin();
             it != corners.end(); it++, itIds++) {
            // add the ID as text to middle of marker
            tInt centerMarkerX = 0;
            tInt centerMarkerY = 0;
            for (int p = 0; p < 4; p++) {
                centerMarkerX += tInt(it->at(p).x);
                centerMarkerY += tInt(it->at(p).y);
            }
            centerMarkerX = centerMarkerX / 4;
            centerMarkerY = centerMarkerY / 4;
            cString idTest = cString::FromInt(*itIds);
            cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_TEXT_SIZE_HUGE);
            cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_TEXT,
                                     centerMarkerX, centerMarkerY,
                                     idTest.GetLength());
            cGCLWriter::StoreData(pGCLCmdDebugInfo, idTest.GetLength(),
                                  idTest.GetPtr());

            // draw marker sides as lines
            for (int j = 0; j < 4; j++) {
                Point2i p0, p1;
                p0 = it->at(j);
                p1 = it->at((j + 1) % 4);
                cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_DRAWLINE,
                                         p0.x, p0.y, p1.x, p1.y);
            }
            //// draw first corner as big circle to check rotation
            Point2i pFirst;
            pFirst = it->at(0);
            cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_FILLCIRCLE,
                                     pFirst.x, pFirst.y, 10, 10);
        }

        cGCLWriter::StoreCommand(pGCLCmdDebugInfo, GCL_CMD_END);
    }

    // alloc media sample and transmit it over output pin
    cObjectPtr<IMediaSample> pSample;
    RETURN_IF_FAILED(AllocMediaSample((tVoid**)&pSample));
    RETURN_IF_FAILED(pSample->Update(
        _clock->GetStreamTime(), pGCLCmdDebugInfo->GetPtr(),
        (tInt)pGCLCmdDebugInfo->GetSize(), IMediaSample::MSF_None));
    RETURN_IF_FAILED(m_outputPinGCL.Transmit(pSample));

    cGCLWriter::FreeDynamicMemoryBlock(pGCLCmdDebugInfo);

    RETURN_NOERROR;
}

ext: cpp

max_stars_repo_name: PhilJd/frAIburg

max_issues_repo_name: PhilJd/frAIburg

max_forks_repo_name: PhilJd/frAIburg


text:
//  Copyright (c) 2007-2013 Hartmut Kaiser
//  Copyright (c) 2011      Bryce Lelbach
//
//  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 <hpx/hpx_fwd.hpp>
#include <hpx/runtime/naming/name.hpp>
#include <hpx/exception.hpp>
#include <hpx/state.hpp>
#include <hpx/util/portable_binary_iarchive.hpp>
#include <hpx/util/portable_binary_oarchive.hpp>
#include <hpx/util/base_object.hpp>
#include <hpx/runtime/applier/applier.hpp>
#include <hpx/runtime/components/stubs/runtime_support.hpp>
#include <hpx/runtime/actions/continuation.hpp>
#include <hpx/runtime/agas/addressing_service.hpp>

#include <boost/serialization/version.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/serialization/array.hpp>

#include <boost/mpl/bool.hpp>

namespace hpx { namespace naming { namespace detail
{
    struct gid_serialization_data;
}}}

namespace boost { namespace serialization
{
    template <>
    struct is_bitwise_serializable<
            hpx::naming::detail::gid_serialization_data>
       : boost::mpl::true_
    {};
}}

namespace hpx { namespace naming
{
    namespace detail
    {
        void decrement_refcnt(detail::id_type_impl* p)
        {
            // Talk to AGAS only if this gid was split at some time in the past,
            // i.e. if a reference actually left the original locality.
            // Alternatively we need to go this way if the id has never been
            // resolved, which means we don't know anything about the component
            // type.
            naming::address addr;

            if (gid_was_split(*p) ||
                !naming::get_agas_client().resolve_cached(*p, addr))
            {
                // guard for wait_abort and other shutdown issues
                try {
                    // decrement global reference count for the given gid,
                    boost::uint32_t credits = detail::get_credit_from_gid(*p);
                    BOOST_ASSERT(0 != credits);

                    if (get_runtime_ptr())
                    {
                        error_code ec(lightweight);
                        // Fire-and-forget semantics.
                        naming::get_agas_client().decref(*p, credits, ec);
                    }
                }
                catch (hpx::exception const& e) {
                    if (e.get_error() != thread_interrupted) {
                        LTM_(error)
                            << "Unhandled exception while executing decrement_refcnt:"
                            << e.what();
                    }
                }
            }
            else {
                // If the gid was not split at any point in time we can assume
                // that the referenced object is fully local.
                components::component_type t = addr.type_;

                BOOST_ASSERT(t != components::component_invalid);

                // Third parameter is the count of how many components to destroy.
                // FIXME: The address should still be in the cache, but it could
                // be evicted. It would be nice to have a way to pass the address
                // directly to free_component_sync.
                try {
                    using components::stubs::runtime_support;
                    runtime_support::free_component_sync(t, *p, 1);
                }
                catch (hpx::exception const& e) {
                    // This request might come in too late and the thread manager
                    // was already stopped. We ignore the request if that's the
                    // case.
                    if (e.get_error() != invalid_status) {
                        throw;      // rethrow if not invalid_status
                    }
                    else if (!threads::threadmanager_is(hpx::stopping)) {
                        throw;      // rethrow if not stopping
                    }
                }
            }
            delete p;   // delete local gid representation in any case
        }

        // custom deleter for managed gid_types, will be called when the last
        // copy of the corresponding naming::id_type goes out of scope
        void gid_managed_deleter (id_type_impl* p)
        {
            // a credit of zero means the component is not (globally) reference
            // counted
            boost::uint32_t credits = detail::get_credit_from_gid(*p);
            if (0 != credits)
            {
                // We take over the ownership of the gid_type object here
                // as the shared_ptr is assuming it has been properly deleted
                // already. The actual deletion happens in the decrement_refcnt
                // once it is executed.
                //error_code ec;
                //applier::register_work(boost::bind(decrement_refcnt, p),
                //    "decrement global gid reference count",
                //    threads::thread_state(threads::pending),
                //    threads::thread_priority_normal, std::size_t(-1), ec);
                //if (ec)
                //{
                    // if we are not able to spawn a new thread, we need to execute
                    // the deleter directly
                    decrement_refcnt(p);
                //}
            }
            else {
                delete p;   // delete local gid representation if needed
            }
        }

        // custom deleter for unmanaged gid_types, will be called when the last
        // copy of the corresponding naming::id_type goes out of scope
        void gid_unmanaged_deleter (id_type_impl* p)
        {
            delete p;   // delete local gid representation only
        }

        ///////////////////////////////////////////////////////////////////////
        id_type_impl::deleter_type id_type_impl::get_deleter(id_type_management t)
        {
            switch (t) {
            case unmanaged:
                return &detail::gid_unmanaged_deleter;
            case managed:
                return &detail::gid_managed_deleter;
            default:
                BOOST_ASSERT(false);          // invalid management type
                return &detail::gid_unmanaged_deleter;
            }
            return 0;
        }

        ///////////////////////////////////////////////////////////////////////
        // prepare the given id, note: this function modifies the passed id
        naming::gid_type id_type_impl::prepare_gid() const
        {
            gid_type::mutex_type::scoped_lock l(this);

            // If the initial credit is zero the gid is 'unmanaged' and no
            // additional action needs to be performed.
            boost::uint16_t oldcredits = detail::get_credit_from_gid(*this);
            if (0 != oldcredits)
            {
                // Request new credits from AGAS if needed (i.e. the initial
                // gid's credit is equal to one and the new gid has no credits
                // after splitting).
                naming::gid_type newid =
                    detail::split_credits_for_gid(const_cast<id_type_impl&>(*this));
                if (0 == detail::get_credit_from_gid(newid))
                {
                    // We add the new credits to the gids first to avoid
                    // duplicate splitting during concurrent serialization
                    // operations.
                    BOOST_ASSERT(1 == detail::get_credit_from_gid(*this));
                    detail::add_credit_to_gid(const_cast<id_type_impl&>(*this),
                        HPX_INITIAL_GLOBALCREDIT);
                    detail::add_credit_to_gid(newid, HPX_INITIAL_GLOBALCREDIT);

                    // We unlock the lock as all operations on the local credit
                    // have been performed and we don't want the lock to be
                    // pending during the (possibly remote) AGAS operation.
                    l.unlock();

                    // If something goes wrong during the reference count
                    // increment below we will have already added credits to
                    // the split gid. In the worst case this will cause a
                    // memory leak. I'm not sure if it is possible to reliably
                    // handle this problem.
                    naming::resolver_client& resolver = naming::get_agas_client();
                    resolver.incref_apply(*this, *this, HPX_INITIAL_GLOBALCREDIT * 2);
                }
                return newid;
            }

            BOOST_ASSERT(unmanaged == type_);
            return *this;
        }

        struct gid_serialization_data
        {
            gid_type gid_;
            boost::uint16_t type_;
        };

        // serialization
        template <typename Archive>
        void id_type_impl::save(Archive& ar) const
        {
            if(ar.flags() & util::disable_array_optimization) {
                naming::gid_type split_id(prepare_gid());
                ar << split_id << type_;
            }
            else {
                gid_serialization_data data;
                data.gid_ = prepare_gid();
                data.type_ = type_;

                ar.save(data);
            }
        }

        template <typename Archive>
        void id_type_impl::load(Archive& ar)
        {
            if(ar.flags() & util::disable_array_optimization) {
                // serialize base class and management type
                ar >> static_cast<gid_type&>(*this);
                ar >> type_;
            }
            else {
                gid_serialization_data data;
                ar.load(data);

                static_cast<gid_type&>(*this) = data.gid_;
                type_ = static_cast<id_type_management>(data.type_);
            }

            if (detail::unmanaged != type_ && detail::managed != type_) {
                HPX_THROW_EXCEPTION(version_too_new, "id_type::load",
                    "trying to load id_type with unknown deleter");
            }
        }

        // explicit instantiation for the correct archive types
        template HPX_EXPORT void id_type_impl::save(
            util::portable_binary_oarchive&) const;

        template HPX_EXPORT void id_type_impl::load(
            util::portable_binary_iarchive&);
    }   // detail

    ///////////////////////////////////////////////////////////////////////////
    template <class Archive>
    void id_type::save(Archive& ar, const unsigned int version) const
    {
        bool isvalid = gid_ ? true : false;
        ar.save(isvalid);
        if (isvalid)
            gid_->save(ar);
    }

    template <class Archive>
    void id_type::load(Archive& ar, const unsigned int version)
    {
        if (version > HPX_IDTYPE_VERSION) {
            HPX_THROW_EXCEPTION(version_too_new, "id_type::load",
                "trying to load id_type of unknown version");
        }

        bool isvalid;
        ar.load(isvalid);
        if (isvalid) {
            boost::intrusive_ptr<detail::id_type_impl> gid(
                new detail::id_type_impl);
            gid->load(ar);
            std::swap(gid_, gid);
        }
    }

    // explicit instantiation for the correct archive types
    template HPX_EXPORT void id_type::save(
        util::portable_binary_oarchive&, const unsigned int version) const;

    template HPX_EXPORT void id_type::load(
        util::portable_binary_iarchive&, const unsigned int version);

    ///////////////////////////////////////////////////////////////////////////
    char const* const management_type_names[] =
    {
        "unknown_deleter",    // -1
        "unmanaged",          // 0
        "managed"             // 1
    };

    char const* get_management_type_name(id_type::management_type m)
    {
        if (m < id_type::unknown_deleter || m > id_type::managed)
            return "invalid";
        return management_type_names[m + 1];
    }

    ///////////////////////////////////////////////////////////////////////////
    inline naming::id_type get_colocation_id_sync(naming::id_type const& id, error_code& ec)
    {
        // FIXME: Resolve the locality instead of deducing it from the target
        //        GID, otherwise this will break once we start moving objects.
        boost::uint32_t locality_id = get_locality_id_from_gid(id.get_gid());
        return get_id_from_locality_id(locality_id);
    }

    inline lcos::future<naming::id_type> get_colocation_id(naming::id_type const& id)
    {
        return lcos::make_ready_future(naming::get_colocation_id_sync(id, throws));
    }
}}

namespace hpx
{
    naming::id_type get_colocation_id_sync(naming::id_type const& id, error_code& ec)
    {
        return naming::get_colocation_id(id).get(ec);
    }

    lcos::future<naming::id_type> get_colocation_id(naming::id_type const& id)
    {
        return naming::get_colocation_id(id);
    }
}

max_stars_repo_name: andreasbuhr/hpx

max_issues_repo_name: andreasbuhr/hpx

max_forks_repo_name: andreasbuhr/hpx


text:
#include <iostream>
#include <boost/type_index.hpp>

using namespace std;

namespace _nmsp1
{
	class A
	{
	public:
		A(int i) //构造函数
		{
			printf("A::A()函数执行了,this=%p\n", this);
		}

		double myfunc() //普通成员函数
		{
			printf("A::myfunc()函数执行了,this=%p\n", this);
			return 12.1;
		}

	private:
		~A() {}
	};

}

int main()
{
	//利用boost输出类型名比typeid(...).name()用法输出类型名更准确。
	using boost::typeindex::type_id_with_cvr;

	//这里注意不要把std::declval<_nmsp1::A>后面的圆括号对丢掉,
	//否则代码含义就发生变化了。想象函数调用时即便没有参数也要把圆括号带着。
	using YT = decltype(std::declval<_nmsp1::A>());
	cout << "YT=" << type_id_with_cvr<YT>().pretty_name() << endl; //显示YT的类型

    //必须为构造函数提供参数
	//_nmsp1::A myaobj(1);
	//cout << "myaobj.myfunc()的返回类型=" << type_id_with_cvr<decltype(myaobj.myfunc())>().pretty_name() << endl;

	//无需构造函数
	cout << "A::myfunc()的返回类型=" << type_id_with_cvr<decltype(std::declval<_nmsp1::A>().myfunc())>().pretty_name() << endl;

    //看起来是一个函数声明的语法，该函数返回的类型是A&&，可以看成是返回了一个A&&类型的对象，这种对象就可以看成是类A对象。
	_nmsp1::A&& refobj();
    //refobj();           //error,看起来是调用refobj这个函数
    //refobj().myfunc();  //error
	decltype(refobj().myfunc()) dvar = 1.2; //定义了一个double类型的变量dvar;
	cout << dvar << endl;

	return 0;
}

max_stars_repo_name: mallius/CppPrimer

max_issues_repo_name: mallius/CppPrimer

max_forks_repo_name: mallius/CppPrimer


text:
/*
 * Copyright (C) 2016-2017, Egor Pugin
 *
 * 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 "package_store.h"

#include "access_table.h"
#include "config.h"
#include "database.h"
#include "directories.h"
#include "exceptions.h"
#include "hash.h"
#include "lock.h"
#include "project.h"
#include "resolver.h"
#include "settings.h"
#include "sqlite_database.h"

#include <boost/algorithm/string.hpp>

#include <primitives/executor.h>
#include <primitives/hasher.h>
#include <primitives/http.h>
#include <primitives/templates.h>
#include <primitives/win32helpers.h>

#include <primitives/log.h>
//DECLARE_STATIC_LOGGER(logger, "package_store");

// legacy varname rd - was: response data
PackageStore rd;

Strings extract_comments(const String &s);

void download_file(path &fn)
{
    // this function checks if fn is url,
    // tries to download it to current dir and run cppan on it
    auto s = fn.string();
    if (!isUrl(s))
        return;
    fn = fn.filename();
    download_file(s, fn, 1_GB);
}

void PackageStore::process(const path &p, Config &root)
{
    if (processing)
        return;
    processing = true;

    SCOPE_EXIT
    {
        processing = false;
    };

    // main access table holder
    AccessTable access_table;

    // insert root config
    packages[root.pkg].config = &root;

    // resolve deps
    for (auto &c : packages)
    {
        if (!c.second.config)
            throw std::runtime_error("Config was not created for target: " + c.first.target_name);

        resolve_dependencies(*c.second.config);
    }

    // set correct local package flags to rd[d].dependencies
    for (auto &c : packages)
    {
        if (!c.first.flags[pfLocalProject])
            continue;
        // only for local packages!!!
        for (auto &d : c.second.dependencies)
        {
            // i->first equals to d.second but have correct flags!!!
            // so we assign them to d.second
            auto i = packages.find(d.second);
            if (i == packages.end())
            {
                // for pretty error message
                auto dep = d.second;
                dep.createNames();

                // we try to resolve again
                ::resolve_dependencies({ d });

                auto irp = resolved_packages.find(d.second);
                if (irp == resolved_packages.end())
                    throw std::runtime_error(c.first.target_name + ": cannot find match for " + dep.target_name);

                i = packages.find(irp->second);
                if (i == packages.end())
                {
                    throw std::logic_error("resolved package does not exist in packages var! " +
                        c.first.target_name + ": cannot find match for " + dep.target_name);
                }
            }
            if (!d.second.ppath.is_loc())
                continue;
            bool ido = d.second.flags[pfIncludeDirectoriesOnly] | i->first.flags[pfIncludeDirectoriesOnly];
            bool pvt = d.second.flags[pfPrivateDependency] | i->first.flags[pfPrivateDependency];
            d.second.flags = i->first.flags;
            d.second.flags.set(pfIncludeDirectoriesOnly, ido);
            d.second.flags.set(pfPrivateDependency, pvt);
        }
    }

    // set correct deps conditions
    for (auto &c : packages)
    {
        for (auto &d : c.second.dependencies)
        {
            d.second.conditions = c.second.config->getDefaultProject().dependencies[d.first].conditions;
        }
    }

    // TODO: if we got a download we might need to refresh configs
    // but we do not know what projects we should clear
    // so clear the whole AT
    if (rebuild_configs())
        access_table.clear();

    // gather (merge) checks, options etc.
    // add more necessary actions here
    for (auto &cc : *this)
    {
        if (cc.first == Package())
            continue;
        root.getDefaultProject().checks += cc.second.config->getDefaultProject().checks;
    }

    // make sure we have new printer every time

    // print deps
    // do not multithread this! causes livelocks
    for (auto &cc : *this)
    {
        if (cc.first == Package())
            continue;
        auto &d = cc.first;

        auto printer = Printer::create(Settings::get_local_settings().printerType);
        printer->access_table = &access_table;
        printer->d = d;
        printer->cwd = d.getDirObj();
        printer->print();
        printer->print_meta();
    }

    // have some influence on printer->print_meta();
    // do not remove
    ScopedCurrentPath cp(p, CurrentPathScope::All);

    // print root config
    auto printer = Printer::create(Settings::get_local_settings().printerType);
    printer->access_table = &access_table;
    printer->d = root.pkg;
    printer->cwd = cp.get_cwd();
    printer->print_meta();
}

void PackageStore::resolve_dependencies(const Config &c)
{
    if (c.getProjects().size() > 1)
        throw std::runtime_error("Make sure your config has only one project (call split())");

    if (!packages[c.pkg].dependencies.empty())
        return;

    Packages deps;

    // remove some packages
    for (auto &d : c.getFileDependencies())
    {
        // remove local packages
        if (d.second.ppath.is_loc())
        {
            // but still insert as a dependency
            packages[c.pkg].dependencies.insert(d);
            continue;
        }

        // remove already downloaded packages
        auto i = resolved_packages.find(d.second);
        if (i != resolved_packages.end())
        {
            // but still insert as a dependency
            packages[c.pkg].dependencies.insert({ i->second.ppath.toString(), i->second });
            continue;
        }

        deps.insert(d);
    }

    if (deps.empty())
        return;

    Resolver r;
    r.resolve_dependencies(deps);
    r.assign_dependencies(c.pkg, deps);

    write_index();
    check_deps_changed(); // goes after write_index()
}

void PackageStore::check_deps_changed()
{
    // already executed
    if (deps_changed)
        return;

    // deps are now resolved
    // now refresh dependencies database only for remote packages
    // this file (local,current,root) packages will be refreshed anyway
    auto &sdb = getServiceDatabase();
    std::unordered_map<Package, String> clean_pkgs;
    for (auto &cc : *this)
    {
        if (cc.first == Package())
            continue;
        // make sure we have ordered deps
        Hasher h;
        StringSet deps;
        for (auto &d : cc.second.dependencies)
            deps.insert(d.second.target_name);
        for (auto &d : deps)
            h |= d;

        if (!sdb.hasPackageDependenciesHash(cc.first, h.hash))
        {
            deps_changed = true;

            // clear exports for this project, so it will be regenerated
            auto p = Printer::create(Settings::get_local_settings().printerType);
            p->clear_export(cc.first.getDirObj());
            clean_pkgs.emplace(cc.first, h.hash);
        }
    }

    auto &e = getExecutor();
    std::vector<Future<void>> fs;
    for (auto &kv : clean_pkgs)
    {
        fs.push_back(e.push([&kv, &sdb]
        {
            cleanPackages(kv.first.target_name, CleanTarget::Lib | CleanTarget::Bin | CleanTarget::Obj | CleanTarget::Exp);
            // set dep hash only after clean
            sdb.setPackageDependenciesHash(kv.first, kv.second);
        }));
    }
    for (auto &f : fs)
        f.wait();
    for (auto &f : fs)
        f.get();
}

PackageStore::iterator PackageStore::begin()
{
    return packages.begin();
}

PackageStore::iterator PackageStore::end()
{
    return packages.end();
}

PackageStore::const_iterator PackageStore::begin() const
{
    return packages.begin();
}

PackageStore::const_iterator PackageStore::end() const
{
    return packages.end();
}

PackageStore::PackageConfig &PackageStore::operator[](const Package &p)
{
    return packages[p];
}

const PackageStore::PackageConfig &PackageStore::operator[](const Package &p) const
{
    auto i = packages.find(p);
    if (i == packages.end())
        throw std::runtime_error("Package not found: " + p.getTargetName());
    return i->second;
}

void PackageStore::write_index() const
{
#ifdef _WIN32
    auto create_link = [](const auto &p, const auto &ln)
    {
        if (!fs::exists(ln))
            ::create_link(p, ln, "CPPAN link");
    };
#endif

    auto &sdb = getServiceDatabase();
    for (auto &cc : *this)
    {
        if (cc.first == Package())
            continue;
        sdb.addInstalledPackage(cc.first);
#ifdef _WIN32
        create_link(cc.first.getDirSrc(), directories.storage_dir_lnk / "src" / (cc.first.target_name + ".lnk"));
        create_link(cc.first.getDirObj(), directories.storage_dir_lnk / "obj" / (cc.first.target_name + ".lnk"));
#endif
    }
}

Config *PackageStore::add_config(std::unique_ptr<Config> &&config, bool created)
{
    auto cfg = config.get();
    auto i = config_store.insert(std::move(config));
    packages[cfg->pkg].config = i.first->get();
    packages[cfg->pkg].config->created = created;
    return packages[cfg->pkg].config;
}

Config *PackageStore::add_config(const Package &p, bool local)
{
    auto c = std::make_unique<Config>(p.getDirSrc(), local);
    c->setPackage(p);
    return add_config(std::move(c), true);
}

Config *PackageStore::add_local_config(const Config &co)
{
    auto cu = std::make_unique<Config>(co);
    auto cp = add_config(std::move(cu), true);
    resolve_dependencies(*cp);
    return cp;
}

std::tuple<PackagesSet, Config, String>
PackageStore::read_packages_from_file(path p, const String &config_name, bool direct_dependency)
{
    download_file(p);
    p = fs::canonical(fs::absolute(p));

    Config conf;
    conf.defaults_allowed = true; // was false
    conf.allow_local_dependencies = true;
    // allow relative project names
    conf.allow_relative_project_names = true;

    if (!fs::exists(p))
        throw std::runtime_error("File or directory does not exist: " + p.string());

    auto read_from_cpp = [&conf, &config_name](const path &fn)
    {
        auto s = read_file_without_bom(fn);
        auto comments = extract_comments(s);

        std::vector<size_t> load_ok;
        bool found = false;
        for (size_t i = 0; i < comments.size(); i++)
        {
            bool probably_this = false;
            try
            {
                boost::trim(comments[i]);
                auto root = load_yaml_config(comments[i]);

                auto sz = root.size();
                if (sz == 0)
                    continue;

                probably_this = root.IsMap() && (
                    root["local_settings"].IsDefined() ||
                    root["files"].IsDefined() ||
                    root["dependencies"].IsDefined()
                    );

                if (!config_name.empty())
                    root["local_settings"]["current_build"] = config_name;
                conf.load(root);

                if (probably_this)
                {
                    found = true;
                    break;
                }
                load_ok.push_back(i);
            }
            catch (...)
            {
                if (probably_this)
                    throw;
            }
        }

        // fallback to the first comment w/out error
        if (!found && !load_ok.empty())
        {
            auto root = load_yaml_config(comments[load_ok.front()]);
            conf.load(root);
        }
    };

    auto build_spec_file = [](const path &p)
    {
        Config c;

        // allow defaults for spec file
        c.defaults_allowed = true;

        // allow relative project names
        c.allow_relative_project_names = true;

        // allow loading local deps from subdirs
        c.allow_local_dependencies = true;

        c.reload(p);
        return c;
    };

    auto set_config = [&config_name](const auto &fn)
    {
        auto root = load_yaml_config(fn);
        root["local_settings"]["current_build"] = config_name;
        Settings::get_local_settings().load(root["local_settings"], SettingsType::Local);
    };

    String sname;
    path cpp_fn;
    if (fs::is_regular_file(p))
    {
        if (p.filename() == CPPAN_FILENAME)
        {
            conf = build_spec_file(p.parent_path());
            sname = p.parent_path().filename().string();
            set_config(p);
        }
        else
        {
            read_from_cpp(p);
            sname = p.filename().stem().string();
            cpp_fn = p;
        }
    }
    else if (fs::is_directory(p))
    {
        // config.load() will use proper defaults
        ScopedCurrentPath cp(p, CurrentPathScope::All);

        auto cppan_fn = p / CPPAN_FILENAME;
        auto main_fn = p / "main.cpp";
        if (fs::exists(cppan_fn))
        {
            conf = build_spec_file(cppan_fn.parent_path());
            sname = cppan_fn.parent_path().filename().string();
            set_config(cppan_fn);
            p = cppan_fn;
        }
        else
        {
            if (!fs::exists(main_fn) && fs::exists("main.c"))
                main_fn = "main.c";

            if (fs::exists(main_fn))
            {
                read_from_cpp(main_fn);
                p = main_fn;
                sname = p.filename().stem().string();
                cpp_fn = p;
            }
            else
            {
                LOG_DEBUG(logger, "No candidates {cppan.yml|main.c[pp]} for reading in directory " + p.string() +
                    ". Assuming default config.");

                conf = build_spec_file(p);
                sname = p.filename().string();
            }
        }
    }
    else
        throw std::runtime_error("Unknown file type " + p.string());

    // prepare names
    auto pname = normalize_path(p);
#ifdef _WIN32 // || macos/ios?
    // prevent different project names for lower/upper case folders
    boost::to_lower(pname);
#endif

    for (auto &c : sname)
    {
        if (c < 0 || c > 127 || !isalnum(c))
            c = '_';
    }

    ProjectPath ppath;
    ppath.push_back("loc");
    ppath.push_back(sha256_short(pname));
    ppath.push_back(sname);

    // set package for root config
    {
        Package pkg;
        pkg.ppath = ppath;
        pkg.version = Version(LOCAL_VERSION_NAME);
        pkg.flags.set(pfLocalProject);
        pkg.flags.set(pfDirectDependency, direct_dependency);
        pkg.createNames();
        conf.setPackage(pkg);
    }

    PackagesSet packages;
    auto configs = conf.split();

    // batch resolve of deps first; merge flags?

    // seq
    for (auto &c : configs)
    {
        auto &project = c.getDefaultProject();
        auto root_directory = (fs::is_regular_file(p) ? p.parent_path() : p) / project.root_directory;

        // to prevent possible errors
        // pkg must have small scope
        Package pkg;
        pkg.ppath = ppath;
        if (!project.name.empty())
        {
            //pkg.ppath.push_back(project.name);
            pkg.ppath /= ProjectPath(project.name);
        }
        pkg.version = Version(LOCAL_VERSION_NAME);
        pkg.flags.set(pfLocalProject);
        pkg.flags.set(pfDirectDependency, direct_dependency);
        pkg.createNames();
        project.applyFlags(pkg.flags);
        c.setPackage(pkg);
        local_packages[pkg.ppath] = root_directory;
    }

    Executor e(std::thread::hardware_concurrency() * 2);
    std::vector<Future<void>> fs;
    for (auto &c : configs)
    {
        auto f = e.push([&c, &p, &cpp_fn, &ppath]()
        {
            auto &project = c.getDefaultProject();
            auto root_directory = fs::is_regular_file(p) ? p.parent_path() : p;
            if (project.root_directory.is_absolute())
                root_directory = project.root_directory;
            else
                root_directory /= project.root_directory;

            // sources
            if (!cpp_fn.empty() && !project.files_loaded)
            {
                // clear default sources first
                project.sources.clear();
                project.sources.insert(cpp_fn.filename().string());
            }
            project.root_directory = root_directory;
            LOG_INFO(logger, "Finding sources for " + project.pkg.ppath.slice(2).toString());
            project.findSources(root_directory);
            // maybe remove? let user see cppan.yml in local project
            project.files.erase(current_thread_path() / CPPAN_FILENAME);
            project.files.erase(CPPAN_FILENAME);
            // patch if any
            project.patchSources();

            // update flags and pkg again after findSources()
            // project type may be different
            // at this time we take project.pkg, not just local variable (pkg)
            project.applyFlags(project.pkg.flags);
            c.setPackage(project.pkg);

            if (Settings::get_local_settings().install_local_packages)
            {
                // copy files to project's dir
                decltype(project.files) files;
                for (auto &f : project.files)
                {
                    auto r = project.pkg.getDirSrc() / f.lexically_relative(root_directory);
                    create_directories(r.parent_path());
                    fs::copy_file(f, r, fs::copy_options::overwrite_existing);
                    files.insert(r);
                }
                project.files = files;

                // set non local
                //project.pkg.flags.set(pfLocalProject, false);
            }

            // check if project's deps are relative
            // this means that there's a local dependency
            auto deps = project.dependencies;
            for (auto &d : deps)
            {
                if (!d.second.ppath.is_relative())
                    continue;

                project.dependencies.erase(d.second.ppath.toString());

                d.second.ppath = ppath / d.second.ppath;
                d.second.version = Version(LOCAL_VERSION_NAME);
                d.second.createNames();
                project.dependencies.insert({ d.second.ppath.toString(), d.second });
            }
        });
        fs.push_back(f);
    }
    for (auto &f : fs)
        f.wait();
    for (auto &f : fs)
        f.get();

    // seq
    for (auto &c : configs)
    {
        auto &project = c.getDefaultProject();

        // add package for result
        packages.insert(project.pkg);

        // add config to storage
        rd.add_local_config(c);
    }

    // write local packages to index
    // do not remove
    rd.write_index();

    return std::tuple<PackagesSet, Config, String>{ packages, conf, sname };
}

bool PackageStore::has_local_package(const ProjectPath &ppath) const
{
    return local_packages.find(ppath) != local_packages.end();
}

path PackageStore::get_local_package_dir(const ProjectPath &ppath) const
{
    auto i = local_packages.find(ppath);
    if (i != local_packages.end())
        return i->second;
    return path();
}

max_stars_repo_name: fuyanbin/cppan

max_issues_repo_name: fuyanbin/cppan

max_forks_repo_name: fuyanbin/cppan


text:
#include "ctpmarkerdata.h"

#include <future>
#include <chrono>

#include <boost/algorithm/string.hpp>

#include "utils/logger.h"
#include "utils/global.h"
#include "utils/scopeguard.h"

int32 CtpMarketData::init(const CtpConfig& ctp_config) {
    using namespace std::chrono_literals;
    is_inited_ = false;

    // 1. Create Ctp Api Instance.
    {
        auto mdapi = CThostFtdcMdApi::CreateFtdcMdApi(ctp_config.flow_path.c_str());
        //ELOG("flow_path:{}", ctp_config.flow_path.c_str());
        if (mdapi == nullptr) {
            ELOG("Ctp create api instance failed!");
            return -1;
        }
        ctpmdapi_ = {mdapi, [](CThostFtdcMdApi* mdapi) {
                         if (mdapi != nullptr) {
                             mdapi->Release();
                         }
                         ELOG("Release Mdapi");
                     }};
        ctpmdapi_->RegisterSpi(&ctpmdspi_);
        ILOG("Ctp create api instance success!");
    }
    // 2. Connect to Ctp Front.
    {
        // Prepare.
        ctpmdspi_.clearCallback();
        auto guard = utils::make_guard([this] { ctpmdspi_.clearCallback(); });

        ctpmdapi_->RegisterFront(const_cast<char*>(ctp_config.md_address.c_str()));

        std::promise<bool> connect_result;
        std::future<bool>  is_connected = connect_result.get_future();
        ctpmdspi_.setOnFrontConnected([&connect_result] { connect_result.set_value(true); });
        // Try connect.
        ctpmdapi_->Init();
        auto wait_result = is_connected.wait_for(5s);
        if (wait_result != std::future_status::ready || is_connected.get() != true) {
            return -2;
        }
    }
    // 3. Login to Ctp.
    {
        // Prepare
        ctpmdspi_.clearCallback();
        auto guard = utils::make_guard([this] { ctpmdspi_.clearCallback(); });

        std::promise<bool> login_result;
        std::future<bool>  is_logined = login_result.get_future();
        ctpmdspi_.setOnLoginFun([&login_result](CThostFtdcRspUserLoginField* login, CThostFtdcRspInfoField* info) {
            if (info->ErrorID == 0) {
                login_result.set_value(true);
            } else {
                login_result.set_value(false);
            }
        });

        CThostFtdcReqUserLoginField req;
        memset(&req, 0, sizeof(req));
        ctp_config.broker_id.copy(req.BrokerID, sizeof(req.BrokerID));
        req.BrokerID[sizeof(req.BrokerID) - 1] = '\n';
        ctp_config.user_id.copy(req.UserID, sizeof(req.UserID));
        req.UserID[sizeof(req.UserID) - 1] = '\n';
        ctp_config.password.copy(req.Password, sizeof(req.Password));
        req.Password[sizeof(req.Password) - 1] = '\n';
        //DLOG("BrokerId: {},UserId:{},PassWord:{},address:{}",
        //     req.BrokerID,
        //     req.UserID,
        //     req.Password,
        //     const_cast<char*>(ctp_config.md_address.c_str()));
        // Try Login
        auto call_result = ctpmdapi_->ReqUserLogin(&req, ++request_id_);
        if (call_result != 0) {
            ELOG("Ctp reqquest Login error:{}", call_result);
            return -3;
        };
        auto wait_result = is_logined.wait_for(5s);
        if (wait_result != std::future_status::ready || is_logined.get() != true) {
            return -3;
        }
    }
    // 4. Set Spi callback.
    {
        ctpmdspi_.clearCallback();
        ctpmdspi_.setOnDataFun([this](CThostFtdcDepthMarketDataField* data) {
            if (data != nullptr) {
                buffer_.push(MarketData(*data));
            }
        });
        ctpmdspi_.setOnSubFun([this](CThostFtdcSpecificInstrumentField* instrument, CThostFtdcRspInfoField* rsp) {
            if (instrument != nullptr && rsp != nullptr && rsp->ErrorID == 0) {
                inst_ids_.insert(instrument->InstrumentID);
            }
        });
        ctpmdspi_.setOnUnSubFun([this](CThostFtdcSpecificInstrumentField* instrument, CThostFtdcRspInfoField* rsp) {
            if (instrument != nullptr && rsp != nullptr && rsp->ErrorID == 0) {
                inst_ids_.erase(instrument->InstrumentID);
            }
        });
        global::need_reconnect.store(false, std::memory_order_release);
        ctpmdspi_.setOnFrontDisConnected([](int32) {
            WLOG("Ctp disconnet, try reconnect!");
            global::need_reconnect.store(true, std::memory_order_release);
        });
    }

    is_inited_ = true;
    return 0;
}

int32 CtpMarketData::subscribeMarketData(const string& instrument_ids) {
    if (!is_inited_) {
        ELOG("CtpMarketData is not inited");
        return -1;
    }
    std::vector<string> splited;
    boost::split(splited, instrument_ids, boost::is_any_of(","), boost::token_compress_on);
    if (!splited.empty()) {
        std::vector<char*> char_instrument_ids;
        char_instrument_ids.reserve(splited.size());
        for (auto& instrument_id : splited) {
            char_instrument_ids.emplace_back(const_cast<char*>(instrument_id.c_str()));
        }
        return ctpmdapi_->SubscribeMarketData(&(char_instrument_ids[0]),
                                              static_cast<int32>(char_instrument_ids.size()));
    }
    return 0;
}

int32 CtpMarketData::subscribeMarketData(const std::vector<string>& instrument_ids) {
    if (!is_inited_) {
        ELOG("CtpMarketData is not inited");
        return -1;
    }
    std::vector<char*> char_instrument_ids;
    for (const auto& instrument_id : instrument_ids) {
        char_instrument_ids.emplace_back(const_cast<char*>(instrument_id.c_str()));
    }
    auto result =
        ctpmdapi_->SubscribeMarketData(&(char_instrument_ids[0]), static_cast<int32>(char_instrument_ids.size()));
    //auto result =
    //    ctpmdapi_->SubscribeMarketData(nullptr,0);

    ELOG("subScribe MarketData  result:{},size:{}", result, static_cast<int32>(char_instrument_ids.size()));
    return result;
}

bool CtpMarketData::getData(MarketData& data) {
    if (!is_inited_) {
        ELOG("CtpMarketData is not inited");
        return false;
    }
    return buffer_.pop(data);
}

bool CtpMarketData::empty() {
    return buffer_.empty();
}

int32 CtpMarketData::stop() {
    if (ctpmdapi_) {
        ctpmdapi_.reset(nullptr);
    }
    inst_ids_.clear();
    is_inited_ = false;
    return 0;
}

int32 CtpMarketData::reConnect(const CtpConfig& ctp_config) {
    auto result = stop();

    if (result != 0) {
        ELOG("Ctp reconnect failed while stoping pre instance! Result:{}", result);
        return -1;
    }
    result = init(ctp_config);
    if (result != 0) {
        ELOG("Ctp reconnect init failed! Result:{}", result);
        return -2;
    }
    return 0;
}

max_forks_repo_name: drinkmystery/ctpmarketdatacollector


text:
#include <boost/test/unit_test.hpp>
#include "algorithms/search/find_single_item.hpp"

BOOST_AUTO_TEST_SUITE(TestFindSingleItem)

BOOST_AUTO_TEST_CASE(vector_empty)
{
    FindSingleItem::Solution solution;
    BOOST_CHECK(-1 == solution.singleNumberHash(std::vector<int>()));
    BOOST_CHECK(0 == solution.singleNumberMath(std::vector<int>()));
    BOOST_CHECK(0 == solution.singleNumberBitManipulation(std::vector<int>()));
}

BOOST_AUTO_TEST_CASE(one_elem)
{
    FindSingleItem::Solution solution;
    BOOST_CHECK(1 == solution.singleNumberHash({1}));
    BOOST_CHECK(1 == solution.singleNumberMath({1}));
    BOOST_CHECK(1 == solution.singleNumberBitManipulation({1}));
}

BOOST_AUTO_TEST_CASE(two_elements)
{
    FindSingleItem::Solution solution;
    BOOST_CHECK(-1 == solution.singleNumberHash({1, 1}));
    BOOST_CHECK(0 == solution.singleNumberMath({1, 1}));
    BOOST_CHECK(0 == solution.singleNumberBitManipulation({1, 1}));
}

BOOST_AUTO_TEST_CASE(several_elements)
{
    FindSingleItem::Solution solution;
    BOOST_CHECK(3 == solution.singleNumberHash({1, 2, 2, 3, 1, 4, 4}));
    BOOST_CHECK(3 == solution.singleNumberMath({1, 2, 2, 3, 1, 4, 4}));
    BOOST_CHECK(3 == solution.singleNumberBitManipulation({1, 2, 2, 3, 1, 4, 4}));
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: iamantony/CppNotes

max_issues_repo_name: iamantony/CppNotes

max_forks_repo_name: iamantony/CppNotes


text:
// 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)
// (C) Copyright 2013 Vicente J. Botet Escriba

#ifndef BOOST_THREAD_COUNTER_HPP
#define BOOST_THREAD_COUNTER_HPP

#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>

//#include <boost/thread/mutex.hpp>
//#include <boost/thread/lock_types.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/assert.hpp>

#include <boost/config/abi_prefix.hpp>

namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost
{
  namespace detail {
    struct counter
    {
      condition_variable cond_;
      std::size_t value_;

      counter(std::size_t value)
      : value_(value)
      {

      }
      counter& operator=(counter const& rhs)
      {
        value_ = rhs.value_;
        return *this;
      }
      counter& operator=(std::size_t value)
      {
        value_ = value;
        return *this;
      }

      operator std::size_t() const
      {
        return value_;
      }
      operator std::size_t&()
      {
        return value_;
      }

      void inc_and_notify_all()
      {
        ++value_;
        cond_.notify_all();
      }

      void dec_and_notify_all()
      {
        --value_;
        cond_.notify_all();
      }
      void assign_and_notify_all(counter const& rhs)
      {
        value_ = rhs.value_;
        cond_.notify_all();
      }
      void assign_and_notify_all(std::size_t value)
      {
        value_ = value;
        cond_.notify_all();
      }
    };
    struct counter_is_not_zero
    {
      counter_is_not_zero(counter const& count) : count_(count) {}
      bool operator()() const { return count_ != 0; }
      counter const& count_;
    };
    struct counter_is_zero
    {
      counter_is_zero(counter const& count) : count_(count) {}
      bool operator()() const { return count_ == 0; }
      counter const& count_;
    };
    struct is_zero
    {
      is_zero(std::size_t& count) : count_(count) {}
      bool operator()() const { return count_ == 0; }
      std::size_t& count_;
    };
    struct not_equal
    {
      not_equal(std::size_t& x, std::size_t& y) : x_(x), y_(y) {}
      bool operator()() const { return x_ != y_; }
      std::size_t& x_;
      std::size_t& y_;
    };
  }
} // namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost

#include <boost/config/abi_suffix.hpp>

#endif

ext: hpp

max_stars_repo_name: jonetomtom/mars

max_issues_repo_name: qingkouwei/mediaones

max_forks_repo_name: pengjinning/mars


text:
#include <boost/mpi.hpp>
#include "mpi_impl/scatter_mesh.hpp"
#include "mpi_impl/poisson.hpp"

namespace mpi = boost::mpi;
using namespace schro_mpi;

double f(double x, double y)
{
    return x*x - y*y;
}

bool test_poisson(mpi::communicator& comm)
{
    int order = 6;

    Mesh<double> mesh = scatter_mesh<double>(order, "../meshes/small_mesh", comm, 0);
    mesh.compute_metrics();

    int dof = mesh.dof(); // processor-local degrees of freedom
    dof = mpi::all_reduce(comm, dof, std::plus<int>{}); // total degrees of freedom

    const auto& z = mesh.quadrature.x;

    SparseData<matrix<double>> F, u;
    for (auto& [e, element] : mesh.elements)
    {
        F[e] = arma::zeros(mesh.N, mesh.N);
        u[e] = arma::zeros(mesh.N, mesh.N);

        for (int i=0; i < mesh.N; ++i)
            for (int j=0; j < mesh.N; ++j)
            {
                auto [x, y] = mesh.elements[e].from_local_coo(z[i], z[j]);
                F[e](i, j) = f(x, y);
            }
    }

    auto rslts = poisson<double>(u, F, mesh, dof, 1e-10);

    if (comm.rank() == 0)
        std::cout << "poisson returned after " << rslts.n_iter << " iteration with residual " << rslts.residual << std::endl;

    return rslts.success;
}


text:
//////////////////////////////////////////////////////////////////////////////
//  Boost.Assign v2                                                         //
//                                                                          //
//  Copyright (C) 2003-2004 Thorsten Ottosen                                //
//  Copyright (C) 2011 Erwann Rogard                                        //
//  Use, modification and distribution are 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_ASSIGN_V2_REF_AUX_LIST_ARRAY_REBIND_ER_2011_HPP
#define BOOST_ASSIGN_V2_REF_AUX_LIST_ARRAY_REBIND_ER_2011_HPP
#include <boost/assign/v2/ref/aux_/list/fwd.hpp>
#include <boost/assign/v2/ref/aux_/list/at.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/size_t.hpp>

namespace boost{
namespace assign{
namespace v2{
namespace ref{
namespace list_aux{

    template<
        size_type K, typename A,
        typename Tag, typename H, typename T
    >
    void assign_array(
        ::boost::mpl::true_ /*exit*/,
        A& a,
        const list_aux::container<Tag, H, T>& l
    )
    {
        /*exit*/
    }

    template<
        size_type K, typename A,
        typename Tag, typename H, typename T
    >
    void assign_array(
        ::boost::mpl::false_ /*exit*/,
        A& a,
        const list_aux::container<Tag, H, T>& l
    )
    {
        typedef ::boost::mpl::int_<K-1> index_;
        // GCC4.4 wants fully qual at
        a[ K - 1 ].rebind( ref::at<K-1>( l ) ) ;
        typedef index_ next_size_;
        typedef ::boost::mpl::int_<0> zero_;
        typedef typename ::boost::mpl::equal_to<
                next_size_, zero_
        >::type exit_;
        assign_array<K-1>( exit_(), a, l );
    }

    // A must be a static array of reference wrappers
    template<typename A, typename Tag, typename H, typename T>
    void assign_array(
        A& a,
        list_aux::container<Tag, H, T> const & l
    )
    {
        typedef list_aux::container<Tag, H, T> list_;
        BOOST_STATIC_ASSERT( A::static_size <= list_::tail_static_size::value );
        typedef ::boost::mpl::int_<0> zero_;
        typedef ::boost::mpl::int_<A::static_size> size_;
        typedef typename ::boost::mpl::equal_to<size_, zero_>::type exit_;
        list_aux::assign_array<size_::value>( exit_(), a, l );
    }

}// list_aux

using list_aux::assign_array;

}// ref
}// v2
}// assign
}// boost

#endif


text:
#pragma once
#include <EASTL/vector.h>
#include <EASTL/list.h>
#include <boost/graph/adjacency_list.hpp>
#include "utils/dependency_graph.hpp"
namespace skr
{
namespace DAG
{
namespace ____
{
struct pmrVecS {
};
struct pmrListS {
};
} // namespace ____

template <class VertexProperty = boost::no_property,
class EdgeProperty = boost::no_property,
class GraphProperty = boost::no_property,
class EdgeListS = boost::listS>
using Graph = boost::adjacency_list<boost::vecS, boost::vecS,
boost::bidirectionalS,
VertexProperty, EdgeProperty, GraphProperty, EdgeListS>;

template <class VertexProperty = boost::no_property,
class EdgeProperty = boost::no_property,
class GraphProperty = boost::no_property,
class EdgeListS = boost::listS>
using GraphVertex =
typename boost::graph_traits<Graph<VertexProperty, GraphProperty, EdgeListS>>::
vertex_descriptor;

template <class VertexProperty = boost::no_property,
class EdgeProperty = boost::no_property,
class GraphProperty = boost::no_property,
class EdgeListS = boost::listS>
using GraphEdge =
typename boost::graph_traits<Graph<VertexProperty, GraphProperty, EdgeListS>>::
edge_descriptor;

template <class VertexProperty = boost::no_property,
class EdgeProperty = boost::no_property,
class GraphProperty = boost::no_property,
class EdgeListS = boost::listS>
using MutableGraph = boost::adjacency_list<boost::listS, boost::listS,
boost::bidirectionalS,
VertexProperty, EdgeProperty, GraphProperty, EdgeListS>;

template <class VertexProperty = boost::no_property,
class EdgeProperty = boost::no_property,
class GraphProperty = boost::no_property,
class EdgeListS = boost::listS>
using MutableGraphVertex =
typename boost::graph_traits<MutableGraph<VertexProperty, GraphProperty, EdgeListS>>::
vertex_descriptor;

template <class VertexProperty = boost::no_property,
class EdgeProperty = boost::no_property,
class GraphProperty = boost::no_property,
class EdgeListS = boost::listS>
using MutableGraphEdge =
typename boost::graph_traits<MutableGraph<VertexProperty, GraphProperty, EdgeListS>>::
edge_descriptor;

// returns the num of edges in the graph
using boost::num_edges;
// returns the num of vertices in the graph
using boost::num_vertices;

// returns the in degree of a vertex
using boost::in_degree;
// returns the out degree of a vertex
using boost::out_degree;

// returns the target vertex of a specific edge
using boost::target;
// returns the source vertex of a specific edge
using boost::source;

// returns the no. vertex in the graph
using boost::vertex;
using boost::vertices;

// returns the edge between A and B
// if no active edge the bool val in pair will be false
using boost::edge;
using boost::edges;

using boost::in_edges;
using boost::out_edges;

using boost::edge_range;

using boost::adjacent_vertices;
using boost::inv_adjacent_vertices;

using boost::add_edge;
using boost::remove_edge;

using boost::add_vertex;
using boost::clear_in_edges;
using boost::clear_out_edges;
using boost::clear_vertex;
using boost::remove_vertex;

template <typename... Ts,
typename bidirGraph = boost::adjacency_list<Ts...>,
typename bidirVertex = typename bidirGraph::vertex_descriptor,
typename IndexMap =
typename boost::property_map<bidirGraph, boost::vertex_index_t>::type>
auto vertex_number(bidirVertex vert, bidirGraph g)
{
    IndexMap index = get(boost::vertex_index, g);
    return index[vert];
}

template <typename prop_name_t, typename... Ts,
typename bidirGraph = boost::adjacency_list<Ts...>,
typename bidirVertex = typename bidirGraph::vertex_descriptor,
typename PropMap =
typename boost::property_map<bidirGraph, prop_name_t>::type>
auto get_vertex_property(bidirVertex vert, bidirGraph& g)
{
    PropMap prop = get(prop_name_t(), g);
    return prop[vert];
}

template <typename prop_name_t, typename Val, typename... Ts,
typename bidirGraph = boost::adjacency_list<Ts...>,
typename bidirVertex = typename bidirGraph::vertex_descriptor,
typename PropMap =
typename boost::property_map<bidirGraph, prop_name_t>::type>
void set_vertex_property(bidirVertex vert, bidirGraph& g, Val&& x)
{
    PropMap prop = get(prop_name_t(), g);
    put(prop, vert, x);
    prop = get(prop_name_t(), g);
    auto why = prop[vert];
}

template <typename prop_name_t, typename... Ts,
typename bidirGraph = boost::adjacency_list<Ts...>,
typename bidirEdge = typename bidirGraph::edge_descriptor,
typename PropMap =
typename boost::property_map<bidirGraph, prop_name_t>::type>
auto get_edge_property(bidirEdge vert, bidirGraph& g)
{
    PropMap prop = get(prop_name_t(), g);
    return prop[vert];
}
} // namespace DAG
} // namespace skr

namespace boost
{
template <class T>
struct container_gen<skr::DAG::____::pmrVecS, T> {
    using type = eastl::vector<T>;
};

template <class T>
struct container_gen<skr::DAG::____::pmrListS, T> {
    using type = eastl::list<T>;
};

template <>
struct parallel_edge_traits<skr::DAG::____::pmrVecS> {
    using type = allow_parallel_edge_tag;
};

template <>
struct parallel_edge_traits<skr::DAG::____::pmrListS> {
    using type = allow_parallel_edge_tag;
};

namespace detail
{
template <>
struct is_random_access<skr::DAG::____::pmrVecS> {
    enum
    {
        value = true
    };
    using type = mpl::true_;
};

template <>
struct is_random_access<skr::DAG::____::pmrListS> {
    enum
    {
        value = true
    };
    using type = mpl::true_;
};
} // namespace detail
} // namespace boost

namespace skr
{
class DependencyGraphBase : public DAG::Graph<DependencyGraph::Node*, DependencyGraph::Edge*>
{
public:
    using DAGVertex = DAG::GraphVertex<DependencyGraph::Node*, DependencyGraph::Edge*>;
    using DAGEdge = DAG::GraphEdge<DependencyGraph::Node*, DependencyGraph::Edge*>;

    static DependencyGraphBase* as(DependencyGraph* graph) SKR_NOEXCEPT;
};
} // namespace skr