查找boost多索引标记以索引和索引数

查找boost多索引标记以索引和索引数,boost,boost-multi-index,Boost,Boost Multi Index,我有一个模板类(CrMultiIndex),它作为模板参数接收boostmultiindex(GlobalHash)的定义 我需要: 根据使用的索引向我的模板类添加统计信息。 因此,我需要一种方法,用现有索引的数量在init处调整向量(m_StatsByIndex)的大小 我仍然希望用户根据标签而不是索引号进行搜索。 所以我需要一种从标记到索引号的转换方法,这样我就可以根据向量中的索引更新向量中的统计信息 我有模板课 template <typename KeysType, typenam

我有一个模板类(CrMultiIndex),它作为模板参数接收boostmultiindex(GlobalHash)的定义

我需要:

  • 根据使用的索引向我的模板类添加统计信息。 因此,我需要一种方法,用现有索引的数量在init处调整向量(m_StatsByIndex)的大小
  • 我仍然希望用户根据标签而不是索引号进行搜索。 所以我需要一种从标记到索引号的转换方法,这样我就可以根据向量中的索引更新向量中的统计信息
  • 我有模板课

    template <typename KeysType, typename MultiIndexType>
    class CrMultiIndex
    {
    
    std::vector<SrStatisticsByIndex> m_StatsByIndex;
    
    public:
    MultiIndexType *m_pMultiIndex=NULL; 
    
    CrMultiIndex()
    {
        m_pMultiIndex = new MultiIndexType(typename 
        MultiIndexType::ctor_args_list());
    }
    
    模板
    类多重索引
    {
    std::向量m_StatsByIndex;
    公众:
    MultiIndexType*m_pMultiIndex=NULL;
    CrMultiIndex()
    {
    m_pMultiIndex=新的多索引类型(typename
    MultiIndexType::ctor_args_list();
    }
    
    以下是boost多索引容器的定义:

    typedef boost::multi_index::multi_index_container<
      CrUsersKeys,
      UsersKey_hash_indices/*,
      bip::allocator<CrUsersKeys,bip::managed_shared_memory::segment_manager>*/
    > GlobalHash;
    
    typedef boost::多索引::多索引容器<
    克鲁斯基,
    UsersKey\u hash\u索引/*,
    bip::分配器*/
    >全局哈希;
    
    具有根据标签进行搜索的功能

    template <typename TagType,typename SearchingKey>
    typename MultiIndexType::template index<TagType>::type::iterator  
    GetIteratorBy(SearchingKey & key)
    {
        return  m_pMultiIndex->template get<TagType>().find(key) ;
    }
    
    模板
    typename MultiIndexType::模板索引::类型::迭代器
    GetIteratorBy(SearchingKey和key)
    {
    返回m_pMultiIndex->template get().find(key);
    }
    

    代码位于

    您需要查询嵌入的索引类型列表:

    typedef typename MultiIndexType::index_type_list::size NumberOfIndexes;
    
    template <typename Tag> constexpr static size_t IndexOfTag() {
        namespace mpl = boost::mpl;
        using tl = typename MultiIndexType::index_type_list;
        using B  = typename mpl::begin<tl>::type;
        using helper = typename MultiIndexType::template index<Tag>;
        static_assert(helper::index_found, "index not found");
        auto N = mpl::distance<B, typename helper::iter>::value;
        return N;
    }
    

    作为对sehe答案的补充,这是对
    IndexOfTag
    的重写,它不依赖于未记录的Boost。多索引功能:

    #include <iostream>
    #include <boost/multi_index/member.hpp>           // for member
    #include <boost/multi_index/hashed_index.hpp>     // for hashed_unique
    #include <boost/multi_index/ordered_index.hpp>    // for ordered_non_unique
    #include <boost/multi_index_container.hpp>        // for multi_index_container
    
    namespace bmi = boost::multi_index;
    
    struct SrStatisticsByIndex {
        int deleted;
        int searchedSuccessfully;
        int searchedNotFound;
    };
    
    template <typename MultiIndexType, typename ValueType = typename MultiIndexType::value_type> 
    class CrMultiIndex {
    
        typedef typename MultiIndexType::index_type_list::size NumberOfIndexes;
    
        template <typename Tag> constexpr static size_t IndexOfTag() {
            using tl = typename MultiIndexType::index_type_list;
            using B  = typename boost::mpl::begin<tl>::type;
            using helper = typename MultiIndexType::template index<Tag>;
            static_assert(helper::index_found, "index not found");
    
            return boost::mpl::distance<B, typename helper::iter>::value;
        }
    
      public:
        MultiIndexType m_pMultiIndex;
    
        template <typename Tag> SrStatisticsByIndex& GetStats()
            { return m_StatsByIndex.at(IndexOfTag<Tag>()); }
    
        template <typename Tag> SrStatisticsByIndex const& GetStats() const
            { return m_StatsByIndex.at(IndexOfTag<Tag>()); }
    
        // All the protected function are non locking function
        template <typename TagType, typename SearchingKey>
            typename MultiIndexType::template index<TagType>::type::iterator 
        GetIteratorBy(SearchingKey &key) {
            auto& idx   = m_pMultiIndex.template get<TagType>();
            auto& stats = GetStats<TagType>();
    
            auto it = idx.find(key);
            ++(it == idx.end()? stats.searchedNotFound : stats.searchedSuccessfully);
    
            return it;
        }
    
        void Insert(ValueType const &key) {
            std::cout << (m_pMultiIndex.insert(key).second? "success":"failed") << std::endl;
        }
    
      private:
        std::vector<SrStatisticsByIndex> m_StatsByIndex { NumberOfIndexes() };
    };
    
    class CrUsersValue {
        int val1;
        int val2;
    };
    
    class CrUsersKeys {
      public:
        int IMSI;
        int TIMESTAMP;
        CrUsersValue val;
    };
    
    typedef boost::multi_index::multi_index_container<
            CrUsersKeys,
            bmi::indexed_by<
                bmi::ordered_non_unique<bmi::tag<struct TIMESTAMP_tag>,
                                        bmi::member<CrUsersKeys, int, &CrUsersKeys::TIMESTAMP> >,
                bmi::hashed_unique<bmi::tag<struct IMSI_tag>,
                                   bmi::member<CrUsersKeys, int, &CrUsersKeys::IMSI> /*, boost::hash<int>, std::equal_to<int>*/>
            >
            /*, bip::allocator<CrUsersKeys,bip::managed_shared_memory::segment_manager>*/
        >
        GlobalHash;
    
    int main() {
        CrMultiIndex<GlobalHash> multi;
    
        CrUsersKeys key;
        key.IMSI = 2;
        multi.Insert(key);
    
        int searchKey = 2;
        auto it = multi.GetIteratorBy<IMSI_tag>(searchKey);
        if (it != multi.m_pMultiIndex.get<IMSI_tag>().end())
            std::cout << "found " << std::endl;
    }
    
    template<typename MultiIndexContainer,std::size_t N=0>
    struct index_position:index_position<MultiIndexContainer,N+1>
    {
      using index_type=typename boost::multi_index::nth_index<MultiIndexContainer,N>::type;
      using index_position<MultiIndexContainer,N+1>::case_of;
      static constexpr std::size_t case_of(std::in_place_type_t<index_type>){return N;}
    };
    
    template<typename MultiIndexContainer>
    struct index_position<
      MultiIndexContainer,
      boost::mpl::size<typename MultiIndexContainer::index_type_list>::value
    >
    {
      static constexpr void case_of(...){}
    };
    
    template <typename MultiIndexContainer,typename Tag>
    constexpr std::size_t IndexOfTag()
    {
      using index_type=typename boost::multi_index::index<MultiIndexContainer,Tag>::type;
      return index_position<MultiIndexContainer>::case_of(std::in_place_type<index_type>);
    }
    
    template<typename MultiIndexContainer,std::size_t N=0>
    struct index_position:index_position<MultiIndexContainer,N+1>
    {
      using index_type=typename boost::multi_index::nth_index<MultiIndexContainer,N>::type;
      using index_position<MultiIndexContainer,N+1>::case_of;
      static constexpr std::size_t case_of(index_type*){return N;}
    };
    
    template<typename MultiIndexContainer>
    struct index_position<
      MultiIndexContainer,
      boost::mpl::size<typename MultiIndexContainer::index_type_list>::value
    >
    {
      static constexpr void case_of(...){}
    };
    
    template <typename MultiIndexContainer,typename Tag>
    constexpr std::size_t IndexOfTag()
    {
      using index_type=typename boost::multi_index::index<MultiIndexContainer,Tag>::type;
      return index_position<MultiIndexContainer>::case_of((index_type*)(nullptr));
    }
    
    模板
    结构索引位置:索引位置
    {
    使用index\u type=typename boost::multi\u index::nth\u index::type;
    使用索引位置::case\u of;
    静态constexpr std::size\u t case\u of(std::in\u place\u type\t){return N;}
    };
    模板
    结构索引位置<
    多索引容器,
    boost::mpl::size::value
    >
    {
    (…){}的静态constexpr void情况_
    };
    模板
    constexpr std::size\u t IndexOfTag()
    {
    使用index\u type=typename boost::multi\u index::index::type;
    返回索引位置::case类型(std::in位置类型);
    }
    
    在C++14中编辑:

    #include <iostream>
    #include <boost/multi_index/member.hpp>           // for member
    #include <boost/multi_index/hashed_index.hpp>     // for hashed_unique
    #include <boost/multi_index/ordered_index.hpp>    // for ordered_non_unique
    #include <boost/multi_index_container.hpp>        // for multi_index_container
    
    namespace bmi = boost::multi_index;
    
    struct SrStatisticsByIndex {
        int deleted;
        int searchedSuccessfully;
        int searchedNotFound;
    };
    
    template <typename MultiIndexType, typename ValueType = typename MultiIndexType::value_type> 
    class CrMultiIndex {
    
        typedef typename MultiIndexType::index_type_list::size NumberOfIndexes;
    
        template <typename Tag> constexpr static size_t IndexOfTag() {
            using tl = typename MultiIndexType::index_type_list;
            using B  = typename boost::mpl::begin<tl>::type;
            using helper = typename MultiIndexType::template index<Tag>;
            static_assert(helper::index_found, "index not found");
    
            return boost::mpl::distance<B, typename helper::iter>::value;
        }
    
      public:
        MultiIndexType m_pMultiIndex;
    
        template <typename Tag> SrStatisticsByIndex& GetStats()
            { return m_StatsByIndex.at(IndexOfTag<Tag>()); }
    
        template <typename Tag> SrStatisticsByIndex const& GetStats() const
            { return m_StatsByIndex.at(IndexOfTag<Tag>()); }
    
        // All the protected function are non locking function
        template <typename TagType, typename SearchingKey>
            typename MultiIndexType::template index<TagType>::type::iterator 
        GetIteratorBy(SearchingKey &key) {
            auto& idx   = m_pMultiIndex.template get<TagType>();
            auto& stats = GetStats<TagType>();
    
            auto it = idx.find(key);
            ++(it == idx.end()? stats.searchedNotFound : stats.searchedSuccessfully);
    
            return it;
        }
    
        void Insert(ValueType const &key) {
            std::cout << (m_pMultiIndex.insert(key).second? "success":"failed") << std::endl;
        }
    
      private:
        std::vector<SrStatisticsByIndex> m_StatsByIndex { NumberOfIndexes() };
    };
    
    class CrUsersValue {
        int val1;
        int val2;
    };
    
    class CrUsersKeys {
      public:
        int IMSI;
        int TIMESTAMP;
        CrUsersValue val;
    };
    
    typedef boost::multi_index::multi_index_container<
            CrUsersKeys,
            bmi::indexed_by<
                bmi::ordered_non_unique<bmi::tag<struct TIMESTAMP_tag>,
                                        bmi::member<CrUsersKeys, int, &CrUsersKeys::TIMESTAMP> >,
                bmi::hashed_unique<bmi::tag<struct IMSI_tag>,
                                   bmi::member<CrUsersKeys, int, &CrUsersKeys::IMSI> /*, boost::hash<int>, std::equal_to<int>*/>
            >
            /*, bip::allocator<CrUsersKeys,bip::managed_shared_memory::segment_manager>*/
        >
        GlobalHash;
    
    int main() {
        CrMultiIndex<GlobalHash> multi;
    
        CrUsersKeys key;
        key.IMSI = 2;
        multi.Insert(key);
    
        int searchKey = 2;
        auto it = multi.GetIteratorBy<IMSI_tag>(searchKey);
        if (it != multi.m_pMultiIndex.get<IMSI_tag>().end())
            std::cout << "found " << std::endl;
    }
    
    template<typename MultiIndexContainer,std::size_t N=0>
    struct index_position:index_position<MultiIndexContainer,N+1>
    {
      using index_type=typename boost::multi_index::nth_index<MultiIndexContainer,N>::type;
      using index_position<MultiIndexContainer,N+1>::case_of;
      static constexpr std::size_t case_of(std::in_place_type_t<index_type>){return N;}
    };
    
    template<typename MultiIndexContainer>
    struct index_position<
      MultiIndexContainer,
      boost::mpl::size<typename MultiIndexContainer::index_type_list>::value
    >
    {
      static constexpr void case_of(...){}
    };
    
    template <typename MultiIndexContainer,typename Tag>
    constexpr std::size_t IndexOfTag()
    {
      using index_type=typename boost::multi_index::index<MultiIndexContainer,Tag>::type;
      return index_position<MultiIndexContainer>::case_of(std::in_place_type<index_type>);
    }
    
    template<typename MultiIndexContainer,std::size_t N=0>
    struct index_position:index_position<MultiIndexContainer,N+1>
    {
      using index_type=typename boost::multi_index::nth_index<MultiIndexContainer,N>::type;
      using index_position<MultiIndexContainer,N+1>::case_of;
      static constexpr std::size_t case_of(index_type*){return N;}
    };
    
    template<typename MultiIndexContainer>
    struct index_position<
      MultiIndexContainer,
      boost::mpl::size<typename MultiIndexContainer::index_type_list>::value
    >
    {
      static constexpr void case_of(...){}
    };
    
    template <typename MultiIndexContainer,typename Tag>
    constexpr std::size_t IndexOfTag()
    {
      using index_type=typename boost::multi_index::index<MultiIndexContainer,Tag>::type;
      return index_position<MultiIndexContainer>::case_of((index_type*)(nullptr));
    }
    
    模板
    结构索引位置:索引位置
    {
    使用index\u type=typename boost::multi\u index::nth\u index::type;
    使用索引位置::case\u of;
    静态constexpr std::size\u t case\u of(index\u type*){return N;}
    };
    模板
    结构索引位置<
    多索引容器,
    boost::mpl::size::value
    >
    {
    (…){}的静态constexpr void情况_
    };
    模板
    constexpr std::size\u t IndexOfTag()
    {
    使用index\u type=typename boost::multi\u index::index::type;
    返回索引位置::((索引类型*)(nullptr))的情况;
    }
    
    Hi@sehe,你依靠的是没有文档的
    index::iter
    index::index\u-found
    @joaqínMLópezMuñoz,这就是为什么我也添加了另一种方法。当然,使用
    has_标签仍然存在欺骗行为,但是你知道……有没有一种文档化的方法可以做到这一点而不需要做很多双重工作吗?我会接受这一点和一点接受可能需要对boost更新进行调整。您好@sehe,谢谢您的最后一个答案。您是否也有办法将索引转换为标记(n_到_标记)?我的目的是循环索引并生成带有typeid(T)的标记名字符串。name()@sehe I发布了另一个
    IndexOfTag
    实现。您好@joaqínMLópezMuñoz,谢谢您的最后一个答案。您是否也有办法将索引转换为标记(n_to_标记)?我的目的是循环索引并生成带有typeid(T)的标记名字符串。name()在初始化时,我使用c++14Ah。我不确定
    index_type
    是否仍然包含标记(在相同的匹配上留下不明确的结果的可能性)。我认为这是非常优雅的,尽管使用
    std::inplace_type_t
    让我觉得…尖锐,这也不必要地要求c++17。@sehe在c++4中重写(我发现
    std::inplace_-type_-t
    非常不言自明,因此我最初使用它;
    index_-type*
    备选方案在我看来更难被读者理解)。我没有收到你对
    索引类型
    的评论,包括标签。@davidbobo用C++14重写。至于你的额外请求,你能提出一个新问题吗?@sehe我同意你的看法
    标识
    就地类型
    更干净。我知道有一些预定义的
    标准
    结构用于传递类型es作为函数args。