add boost on mac
This commit is contained in:
154
macx64/include/boost/poly_collection/detail/segment_split.hpp
Normal file
154
macx64/include/boost/poly_collection/detail/segment_split.hpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/* Copyright 2016-2017 Joaquin M Lopez Munoz.
|
||||
* 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)
|
||||
*
|
||||
* See http://www.boost.org/libs/poly_collection for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_POLY_COLLECTION_DETAIL_SEGMENT_SPLIT_HPP
|
||||
#define BOOST_POLY_COLLECTION_DETAIL_SEGMENT_SPLIT_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/poly_collection/detail/iterator_traits.hpp>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace poly_collection{
|
||||
|
||||
namespace detail{
|
||||
|
||||
/* breakdown of an iterator range into local_base_iterator segments */
|
||||
|
||||
template<typename PolyCollectionIterator>
|
||||
class segment_splitter
|
||||
{
|
||||
using traits=iterator_traits<PolyCollectionIterator>;
|
||||
using local_base_iterator=typename traits::local_base_iterator;
|
||||
using base_segment_info_iterator=typename traits::base_segment_info_iterator;
|
||||
|
||||
public:
|
||||
struct info
|
||||
{
|
||||
const std::type_info& type_info()const noexcept{return *pinfo_;}
|
||||
local_base_iterator begin()const noexcept{return begin_;}
|
||||
local_base_iterator end()const noexcept{return end_;}
|
||||
|
||||
const std::type_info* pinfo_;
|
||||
local_base_iterator begin_,end_;
|
||||
};
|
||||
|
||||
struct iterator:iterator_facade<iterator,info,std::input_iterator_tag,info>
|
||||
{
|
||||
iterator()=default;
|
||||
|
||||
private:
|
||||
friend class segment_splitter;
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
iterator(
|
||||
base_segment_info_iterator it,
|
||||
const PolyCollectionIterator& first,const PolyCollectionIterator& last):
|
||||
it{it},pfirst{&first},plast{&last}{}
|
||||
iterator(
|
||||
const PolyCollectionIterator& first,const PolyCollectionIterator& last):
|
||||
it{traits::base_segment_info_iterator_from(first)},
|
||||
pfirst{&first},plast{&last}
|
||||
{}
|
||||
|
||||
info dereference()const noexcept
|
||||
{
|
||||
return {
|
||||
&it->type_info(),
|
||||
it==traits::base_segment_info_iterator_from(*pfirst)?
|
||||
traits::local_base_iterator_from(*pfirst):it->begin(),
|
||||
it==traits::base_segment_info_iterator_from(*plast)?
|
||||
traits::local_base_iterator_from(*plast):it->end()
|
||||
};
|
||||
}
|
||||
|
||||
bool equal(const iterator& x)const noexcept{return it==x.it;}
|
||||
void increment()noexcept{++it;}
|
||||
|
||||
base_segment_info_iterator it;
|
||||
const PolyCollectionIterator* pfirst;
|
||||
const PolyCollectionIterator* plast;
|
||||
};
|
||||
|
||||
segment_splitter(
|
||||
const PolyCollectionIterator& first,const PolyCollectionIterator& last):
|
||||
pfirst{&first},plast{&last}{}
|
||||
|
||||
iterator begin()const noexcept{return {*pfirst,*plast};}
|
||||
|
||||
iterator end()const noexcept
|
||||
{
|
||||
auto slast=traits::base_segment_info_iterator_from(*plast);
|
||||
if(slast!=traits::end_base_segment_info_iterator_from(*plast))++slast;
|
||||
return {slast,*plast,*plast};
|
||||
}
|
||||
|
||||
private:
|
||||
const PolyCollectionIterator* pfirst;
|
||||
const PolyCollectionIterator* plast;
|
||||
};
|
||||
|
||||
template<typename PolyCollectionIterator>
|
||||
segment_splitter<PolyCollectionIterator>
|
||||
segment_split(
|
||||
const PolyCollectionIterator& first,const PolyCollectionIterator& last)
|
||||
{
|
||||
return {first,last};
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* equivalent to for(auto i:segment_split(first,last))f(i) */
|
||||
|
||||
template<typename PolyCollectionIterator,typename F>
|
||||
void for_each_segment(
|
||||
const PolyCollectionIterator& first,const PolyCollectionIterator& last,F&& f)
|
||||
{
|
||||
using traits=iterator_traits<PolyCollectionIterator>;
|
||||
using info=typename segment_splitter<PolyCollectionIterator>::info;
|
||||
|
||||
auto sfirst=traits::base_segment_info_iterator_from(first),
|
||||
slast=traits::base_segment_info_iterator_from(last),
|
||||
send=traits::end_base_segment_info_iterator_from(last);
|
||||
auto lbfirst=traits::local_base_iterator_from(first),
|
||||
lblast=traits::local_base_iterator_from(last);
|
||||
|
||||
if(sfirst!=slast){
|
||||
for(;;){
|
||||
f(info{&sfirst->type_info(),lbfirst,sfirst->end()});
|
||||
++sfirst;
|
||||
if(sfirst==slast)break;
|
||||
lbfirst=sfirst->begin();
|
||||
}
|
||||
if(sfirst!=send)f(info{&sfirst->type_info(),sfirst->begin(),lblast});
|
||||
}
|
||||
else if(sfirst!=send){
|
||||
f(info{&sfirst->type_info(),lbfirst,lblast});
|
||||
}
|
||||
}
|
||||
#else
|
||||
template<typename PolyCollectionIterator,typename F>
|
||||
void for_each_segment(
|
||||
const PolyCollectionIterator& first,const PolyCollectionIterator& last,F&& f)
|
||||
{
|
||||
for(auto i:segment_split(first,last))f(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* namespace poly_collection::detail */
|
||||
|
||||
} /* namespace poly_collection */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user