Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Tuple iterator by Anthony Williams

By: a guest on Dec 13th, 2012  |  syntax: C++  |  size: 21.40 KB  |  views: 79  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #ifndef ITERATORS_TUPLEIT_HH
  2. #define ITERATORS_TUPLEIT_HH
  3.  
  4. #include <iterator>
  5. #include <cstddef>
  6. #include <algorithm>
  7. #include <stdexcept>
  8. #include <new>
  9. #include "boost/tuple/tuple.hpp"
  10. #include "boost/tuple/tuple_comparison.hpp"
  11. #include "boost/utility.hpp"
  12. #include "boost/type_traits.hpp"
  13. #include "boost/optional.hpp" // for aligned_storage
  14. #include <memory>
  15.  
  16. namespace iterators
  17. {
  18.     namespace detail
  19.     {
  20.         void preincrementTuple(boost::tuples::null_type)
  21.         {
  22.         }
  23.  
  24.         template<typename TupleType>
  25.         void preincrementTuple(TupleType& lhs)
  26.         {
  27.             preincrementTuple(lhs.get_tail());
  28.             ++(lhs.template get<0>());
  29.         }
  30.  
  31.         void predecrementTuple(boost::tuples::null_type)
  32.         {
  33.         }
  34.  
  35.         template<typename TupleType>
  36.         void predecrementTuple(TupleType& lhs)
  37.         {
  38.             predecrementTuple(lhs.get_tail());
  39.             --(lhs.template get<0>());
  40.         }
  41.  
  42.         template<typename difference_type>
  43.         void addToTuple(boost::tuples::null_type,difference_type)
  44.         {
  45.         }
  46.  
  47.         template<typename difference_type,typename TupleType>
  48.         void addToTuple(TupleType& lhs,difference_type diff)
  49.         {
  50.             addToTuple(lhs.get_tail(),diff);
  51.             lhs.template get<0>()+=diff;
  52.         }
  53.  
  54.         template<typename difference_type>
  55.         void subFromTuple(boost::tuples::null_type,difference_type)
  56.         {
  57.         }
  58.  
  59.         template<typename difference_type,typename TupleType>
  60.         void subFromTuple(TupleType& lhs,difference_type diff)
  61.         {
  62.             subFromTuple(lhs.get_tail(),diff);
  63.             lhs.template get<0>()-=diff;
  64.         }
  65.  
  66.         template<typename difference_type,typename TupleType>
  67.         difference_type diffTuples(TupleType const& lhs,TupleType const& rhs);
  68.  
  69.         template<typename difference_type,typename TupleType>
  70.         struct DiffTupleHelper
  71.         {
  72.             static difference_type doDiff(TupleType const& lhs,TupleType const& rhs)
  73.             {
  74.                 difference_type res1=lhs.template get<0>()-rhs.template get<0>();
  75.                 difference_type res2=diffTuples<difference_type>(lhs.get_tail(),rhs.get_tail());
  76.                
  77.                 if(res1==res2)
  78.                 {
  79.                     return res1;
  80.                 }
  81.                
  82.                 throw std::logic_error("The iterators in the tuples are mismatched");
  83.             }
  84.         };
  85.  
  86.         template<typename difference_type,typename ValueType>
  87.         struct DiffTupleHelper<difference_type,boost::tuples::cons<ValueType,boost::tuples::null_type> >
  88.         {
  89.             static difference_type doDiff(boost::tuples::cons<ValueType,boost::tuples::null_type> const& lhs,boost::tuples::cons<ValueType,boost::tuples::null_type>  const& rhs)
  90.             {
  91.                 return lhs.template get<0>()-rhs.template get<0>();
  92.             }
  93.         };
  94.    
  95.         template<typename difference_type,typename TupleType>
  96.         difference_type diffTuples(TupleType const& lhs,TupleType const& rhs)
  97.         {
  98.             return DiffTupleHelper<difference_type,TupleType>::doDiff(lhs,rhs);
  99.         }
  100.  
  101.    
  102.  
  103.         template<typename SourceTuple>
  104.         struct MakeTupleTypeWithReferences
  105.         {
  106.             typedef MakeTupleTypeWithReferences<typename SourceTuple::tail_type> TailTupleTypeBuilder;
  107.             typedef typename TailTupleTypeBuilder::Type TailTupleType;
  108.             typedef boost::tuples::cons<typename boost::add_reference<typename SourceTuple::head_type>::type,
  109.                                         TailTupleType> Type;
  110.  
  111.             template<typename Tuple>
  112.             static Type makeTuple(Tuple& source)
  113.             {
  114.                 return Type(source.get_head(),TailTupleTypeBuilder::makeTuple(source.get_tail()));
  115.             }
  116.         };
  117.    
  118.         template<>
  119.         struct MakeTupleTypeWithReferences<boost::tuples::null_type>
  120.         {
  121.             typedef boost::tuples::null_type Type;
  122.  
  123.             static Type makeTuple(boost::tuples::null_type)
  124.             {
  125.                 return Type();
  126.             }
  127.         };
  128.  
  129.         typedef char Tiny;
  130.         struct Small
  131.         {
  132.             Tiny dummy[2];
  133.         };
  134.         struct Medium
  135.         {
  136.             Small dummy[2];
  137.         };
  138.         struct Large
  139.         {
  140.             Medium dummy[2];
  141.         };
  142.         struct Huge
  143.         {
  144.             Large dummy[2];
  145.         };
  146.  
  147.         template<unsigned>
  148.         struct CategoryMap
  149.         {
  150.             typedef void Type;
  151.         };
  152.        
  153.        
  154.  
  155. //     Tiny categoryCheck(std::output_iterator_tag*);
  156.         Small categoryCheck(std::input_iterator_tag*);
  157.         Medium categoryCheck(std::forward_iterator_tag*);
  158.         Large categoryCheck(std::bidirectional_iterator_tag*);
  159.         Huge categoryCheck(std::random_access_iterator_tag*);
  160.  
  161.  
  162. //     template<>
  163. //     struct CategoryMap<sizeof(Tiny)>
  164. //     {
  165. //      typedef std::output_iterator_tag Type;
  166. //     };
  167.  
  168.         template<>
  169.         struct CategoryMap<sizeof(Small)>
  170.         {
  171.             typedef std::input_iterator_tag Type;
  172.         };
  173.    
  174.         template<>
  175.         struct CategoryMap<sizeof(Medium)>
  176.         {
  177.             typedef std::forward_iterator_tag Type;
  178.         };
  179.  
  180.         template<>
  181.         struct CategoryMap<sizeof(Large)>
  182.         {
  183.             typedef std::bidirectional_iterator_tag Type;
  184.         };
  185.         template<>
  186.         struct CategoryMap<sizeof(Huge)>
  187.         {
  188.             typedef std::random_access_iterator_tag Type;
  189.         };
  190.  
  191.         template<typename Cat1,typename Cat2>
  192.         struct CommonCategory
  193.         {
  194.         private:
  195.             enum
  196.             {categorySize=sizeof(::iterators::detail::categoryCheck(false?(Cat1*)0:(Cat2*)0))
  197.             };
  198.         public:
  199.             typedef typename CategoryMap<categorySize>::Type Type;
  200.         };
  201.        
  202.         // specializations
  203.         template<typename Cat>
  204.         struct CommonCategory<std::output_iterator_tag,Cat>
  205.         {
  206.             typedef std::output_iterator_tag Type;
  207.         };
  208.         template<typename Cat>
  209.         struct CommonCategory<Cat,std::output_iterator_tag>
  210.         {
  211.             typedef std::output_iterator_tag Type;
  212.         };
  213.         template<>
  214.         struct CommonCategory<std::output_iterator_tag,std::output_iterator_tag>
  215.         {
  216.             typedef std::output_iterator_tag Type;
  217.         };
  218.         template<>
  219.         struct CommonCategory<std::input_iterator_tag,std::output_iterator_tag>
  220.         {
  221.             // no Type, because error
  222.         };
  223.         template<>
  224.         struct CommonCategory<std::output_iterator_tag,std::input_iterator_tag>
  225.         {
  226.             // no Type, because error
  227.         };
  228.  
  229.         void derefAndWrite(boost::tuples::null_type,boost::tuples::null_type)
  230.         {}
  231.  
  232.         template<typename IterTuple,typename SourceTuple>
  233.         void derefAndWrite(IterTuple& iters,SourceTuple const& source)
  234.         {
  235.             *iters.get_head()=source.get_head();
  236.             derefAndWrite(iters.get_tail(),source.get_tail());
  237.         }
  238.        
  239.     }
  240.  
  241.     // An OutputTuple holds a tuple of references to iterators, and writes to them on assignment
  242.     template<typename IterTuple>
  243.     struct OutputTuple:
  244.         public detail::MakeTupleTypeWithReferences<IterTuple>::Type,
  245.         boost::noncopyable
  246.     {
  247.     private:
  248.         typedef detail::MakeTupleTypeWithReferences<IterTuple> BaseTypeBuilder;
  249.         typedef typename BaseTypeBuilder::Type BaseType;
  250.     public:
  251.         OutputTuple(IterTuple& iters):
  252.             BaseType(BaseTypeBuilder::makeTuple(iters))
  253.         {}
  254.  
  255.         template<typename SomeTuple>
  256.         OutputTuple& operator=(const SomeTuple& other)
  257.         {
  258.             detail::derefAndWrite(static_cast<BaseType&>(*this),other);
  259.             return *this;
  260.         }
  261.     };
  262.  
  263.     // An OwningRefTuple holds a tuple of references,
  264.     // which may point to data within the tuple, or external to it
  265.  
  266.     namespace detail
  267.     {
  268.         struct PreserveReferences
  269.         {};
  270.  
  271.         template<typename OwnedType>
  272.         struct OwningBase
  273.         {
  274.             std::auto_ptr<OwnedType> tupleBuf;
  275.  
  276.             OwningBase()
  277.             {}
  278.            
  279.             template<typename SomeType>
  280.             OwningBase(SomeType &source):
  281.                 tupleBuf(new OwnedType(source))
  282.             {}
  283.            
  284.         };
  285.     }
  286.  
  287.     template<typename TupleType>
  288.     struct OwningRefTuple:
  289.         private detail::OwningBase<TupleType>,
  290.         public detail::MakeTupleTypeWithReferences<TupleType>::Type
  291.     {
  292.     private:
  293.         typedef detail::MakeTupleTypeWithReferences<TupleType> BaseTypeBuilder;
  294.         typedef typename BaseTypeBuilder::Type BaseType;
  295.         typedef detail::OwningBase<TupleType> OwningBaseType;
  296.     public:
  297.  
  298.         typedef typename BaseType::head_type head_type;
  299.         typedef typename BaseType::tail_type tail_type;
  300.  
  301.     private:
  302.         typedef TupleType OwnedTuple;
  303.  
  304.         OwnedTuple* getTuplePtr()
  305.         {
  306.             return this->tupleBuf.get();
  307.         }
  308.     public:
  309.         // copy from other types of tuples too
  310.         template<typename SomeTuple>
  311.         OwningRefTuple(const SomeTuple& other):
  312.             OwningBaseType(other),BaseType(BaseTypeBuilder::makeTuple(*getTuplePtr()))
  313.         {
  314.         }
  315.         // copying copies values by default
  316.         OwningRefTuple(const OwningRefTuple& other):
  317.             OwningBaseType(other),BaseType(BaseTypeBuilder::makeTuple(*getTuplePtr()))
  318.         {
  319.         }
  320.  
  321.         // allow user to specify
  322.         // whether to preserve references
  323.         template<typename SomeTuple>
  324.         OwningRefTuple(SomeTuple& other,detail::PreserveReferences const&):
  325.             BaseType(BaseTypeBuilder::makeTuple(other))
  326.         {
  327.         }
  328.  
  329.         // assignment assigns to referenced values
  330.         template<typename SomeTuple>
  331.         OwningRefTuple& operator=(const SomeTuple& other)
  332.         {
  333.             BaseType::operator=(other);
  334.             return *this;
  335.         }
  336.         OwningRefTuple& operator=(const OwningRefTuple& other)
  337.         {
  338.             BaseType::operator=(other);
  339.             return *this;
  340.         }
  341.     };
  342.  
  343.     namespace detail
  344.     {
  345.         template<typename IterTuple>
  346.         struct DerefIterTupleHelperKeepRef
  347.         {
  348.             typedef boost::tuples::cons<typename boost::add_reference<typename std::iterator_traits<typename IterTuple::head_type>::value_type>::type,
  349.                                         typename DerefIterTupleHelperKeepRef<typename IterTuple::tail_type>::Type> Type;
  350.         };
  351.  
  352.         template<>
  353.         struct DerefIterTupleHelperKeepRef<boost::tuples::null_type>
  354.         {
  355.             typedef boost::tuples::null_type Type;
  356.         };
  357.  
  358.         template<>
  359.         struct DerefIterTupleHelperKeepRef<const boost::tuples::null_type>
  360.         {
  361.             typedef boost::tuples::null_type Type;
  362.         };
  363.  
  364.  
  365.         template<typename IterTuple>
  366.         struct DerefIterTupleHelperNoRef
  367.         {
  368.             typedef boost::tuples::cons<typename std::iterator_traits<typename IterTuple::head_type>::value_type,
  369.                                         typename DerefIterTupleHelperNoRef<typename IterTuple::tail_type>::Type> Type;
  370.         };
  371.  
  372.         template<>
  373.         struct DerefIterTupleHelperNoRef<boost::tuples::null_type>
  374.         {
  375.             typedef boost::tuples::null_type Type;
  376.         };
  377.  
  378.         template<>
  379.         struct DerefIterTupleHelperNoRef<const boost::tuples::null_type>
  380.         {
  381.             typedef boost::tuples::null_type Type;
  382.         };
  383.  
  384.         boost::tuples::null_type derefIterTupleKeepRef(boost::tuples::null_type const& iters)
  385.         {
  386.             return iters;
  387.         }
  388.         template<typename IterTuple>
  389.         const typename DerefIterTupleHelperKeepRef<IterTuple>::Type derefIterTupleKeepRef(IterTuple& iters)
  390.         {
  391.             return typename DerefIterTupleHelperKeepRef<IterTuple>::Type(*iters.template get<0>(),derefIterTupleKeepRef(iters.get_tail()));
  392.         }
  393.  
  394.         boost::tuples::null_type derefIterTupleNoRef(boost::tuples::null_type const& iters)
  395.         {
  396.             return iters;
  397.         }
  398.         template<typename IterTuple>
  399.         typename DerefIterTupleHelperNoRef<IterTuple>::Type derefIterTupleNoRef(IterTuple& iters)
  400.         {
  401.             return typename DerefIterTupleHelperNoRef<IterTuple>::Type(*iters.template get<0>(),derefIterTupleNoRef(iters.get_tail()));
  402.         }
  403.  
  404.         // Define, construct and destroy the appropriate value_type for
  405.         // the given iterator category
  406.         template<typename Category,typename IterTuple>
  407.         struct ValueForCategory
  408.         {
  409.         private:
  410.             typedef typename IterTuple::head_type HeadIterType;
  411.             typedef typename IterTuple::tail_type TailTupleType;
  412.             typedef typename std::iterator_traits<HeadIterType>::value_type HeadValueType;
  413.             typedef typename ValueForCategory<Category,TailTupleType>::ValueTuple TailValueTuple;
  414.  
  415.         public:
  416.             typedef boost::tuples::cons<HeadValueType,TailValueTuple> ValueTuple;
  417.            
  418.             typedef OwningRefTuple<ValueTuple> value_type;
  419.             typedef value_type Type;
  420.            
  421.             static void construct(Type* p,IterTuple const& iters)
  422.             {
  423.                 // don't copy values, keep as references
  424.                 new (p) Type(derefIterTupleKeepRef(iters),::iterators::detail::PreserveReferences());
  425.             }
  426.            
  427.             static void destruct(Type* p)
  428.             {
  429.                 p->~OwningRefTuple<ValueTuple>();
  430.             }
  431.         };
  432.  
  433.         template<typename Category>
  434.         struct ValueForCategory<Category,boost::tuples::null_type>
  435.         {
  436.         private:
  437.         public:
  438.             typedef boost::tuples::null_type ValueTuple;
  439.         };
  440.  
  441.         template<typename IterTuple>
  442.         struct ValueForCategory<std::input_iterator_tag,IterTuple>
  443.         {
  444.         private:
  445.             typedef typename IterTuple::head_type HeadIterType;
  446.             typedef typename IterTuple::tail_type TailTupleType;
  447.             typedef typename std::iterator_traits<HeadIterType>::value_type HeadValueType;
  448.             typedef typename ValueForCategory<std::input_iterator_tag,TailTupleType>::ValueTuple TailValueTuple;
  449.  
  450.         public:
  451.             typedef boost::tuples::cons<HeadValueType,TailValueTuple> ValueTuple;
  452.            
  453.             typedef OwningRefTuple<ValueTuple> value_type;
  454.             typedef value_type Type;
  455.            
  456.             static void construct(Type* p,IterTuple const& iters)
  457.             {
  458.                 // copy values
  459.                 new (p) Type(derefIterTupleNoRef(iters));
  460.             }
  461.            
  462.             static void destruct(Type* p)
  463.             {
  464.                 p->~OwningRefTuple<ValueTuple>();
  465.             }
  466.         };
  467.  
  468.         template<>
  469.         struct ValueForCategory<std::input_iterator_tag,boost::tuples::null_type>
  470.         {
  471.         private:
  472.         public:
  473.             typedef boost::tuples::null_type ValueTuple;
  474.         };
  475.  
  476.         template<typename IterTuple>
  477.         struct ValueForCategory<std::output_iterator_tag,IterTuple>
  478.         {
  479.         public:
  480.             typedef OutputTuple<IterTuple> value_type;
  481.             typedef value_type Type;
  482.            
  483.             static void construct(Type* p,IterTuple& iters)
  484.             {
  485.                 // copy values
  486.                 new (p) Type(iters);
  487.             }
  488.            
  489.             static void destruct(Type* p)
  490.             {
  491.                 p->~OutputTuple<IterTuple>();
  492.             }
  493.         };
  494.  
  495.         template<>
  496.         struct ValueForCategory<std::output_iterator_tag,boost::tuples::null_type>
  497.         {
  498.         private:
  499.         public:
  500.         };
  501.  
  502.  
  503.         template<typename Category,typename IterTuple>
  504.         struct VFCSelector
  505.         {
  506.             typedef ValueForCategory<Category,IterTuple> Type;
  507.         };
  508.  
  509.         // Select the iterator_category and value_type for our TupleIt
  510.         template<typename IterTuple>
  511.         struct TupleItHelper
  512.         {
  513.             typedef typename IterTuple::head_type HeadIterType;
  514.             typedef typename IterTuple::tail_type TailTupleType;
  515.            
  516.             typedef typename std::iterator_traits<HeadIterType>::iterator_category Cat1;
  517.             typedef typename TupleItHelper<TailTupleType>::iterator_category Cat2;
  518.  
  519.             typedef typename CommonCategory<Cat1,Cat2>::Type iterator_category;
  520.             typedef typename VFCSelector<iterator_category,IterTuple>::Type ValueTypeDef;
  521.             typedef typename ValueTypeDef::value_type value_type;
  522.             typedef typename ValueTypeDef::Type DeRefType;
  523.  
  524.             typedef DeRefType& reference;
  525.             typedef DeRefType* pointer;
  526.  
  527.             typedef std::ptrdiff_t difference_type;
  528.  
  529.             typedef std::iterator<iterator_category,value_type,difference_type,pointer,reference> IteratorType;
  530.  
  531.             static void construct(DeRefType* p,IterTuple& iters)
  532.             {
  533.                 ValueTypeDef::construct(p,iters);
  534.             }
  535.            
  536.             static void destruct(DeRefType* p)
  537.             {
  538.                 ValueTypeDef::destruct(p);
  539.             }
  540.         };
  541.  
  542.         template<>
  543.         struct TupleItHelper<boost::tuples::null_type>
  544.         {
  545.             typedef std::random_access_iterator_tag iterator_category;
  546.         };
  547.     }
  548.  
  549.     // the actual Tuple Iterator itself
  550.     template<typename IterTuple>
  551.     struct TupleIt:
  552.         public detail::TupleItHelper<IterTuple>::IteratorType
  553.     {
  554.     private:
  555.         typedef detail::TupleItHelper<IterTuple> TupleDefs;
  556.     public:
  557.         typedef typename TupleDefs::iterator_category iterator_category;
  558.         typedef typename TupleDefs::value_type value_type;
  559.         typedef typename TupleDefs::difference_type difference_type;
  560.         typedef typename TupleDefs::reference reference;
  561.         typedef typename TupleDefs::pointer pointer;
  562.     private:
  563.         pointer getValuePtr() const
  564.         {
  565.             return reinterpret_cast<pointer>(dataCache.address());
  566.         }
  567.    
  568.         void emptyCache() const
  569.         {
  570.             if(cacheInitialized)
  571.             {
  572.                 TupleDefs::destruct(getValuePtr());
  573.                 cacheInitialized=false;
  574.             }
  575.         }
  576.  
  577.         void initCache() const
  578.         {
  579.             emptyCache();
  580.             TupleDefs::construct(getValuePtr(),iters);
  581.             cacheInitialized=true;
  582.         }
  583.    
  584.    
  585.     public:
  586.    
  587.         TupleIt(IterTuple iters_):
  588.             iters(iters_),cacheInitialized(false)
  589.         {}
  590.         template<typename OtherIterTuple>
  591.         TupleIt(const TupleIt<OtherIterTuple>& other):
  592.             iters(other.iters),cacheInitialized(false)
  593.         {}
  594.         TupleIt(const TupleIt& other):
  595.             iters(other.iters),cacheInitialized(false)
  596.         {}
  597.         TupleIt():
  598.             iters(),cacheInitialized(false)
  599.         {}
  600.    
  601.  
  602.         ~TupleIt()
  603.         {
  604.             emptyCache();
  605.         }
  606.  
  607.         void swap(TupleIt& other)
  608.         {
  609.             using std::swap;
  610.        
  611.             swap(iters,other.iters);
  612.         }
  613.  
  614.         TupleIt& operator=(TupleIt const& other)
  615.         {
  616.             emptyCache();
  617.             iters=other.iters;
  618.             return *this;
  619.         }
  620.  
  621.         // Input Iterator requirements
  622.         reference operator*() const
  623.         {
  624.             initCache();
  625.             return *getValuePtr();
  626.         }
  627.  
  628.         pointer operator->() const
  629.         {
  630.             initCache();
  631.             return getValuePtr();
  632.         }
  633.  
  634.         friend bool operator==(const TupleIt& lhs,const TupleIt& rhs)
  635.         {
  636.             return lhs.iters==rhs.iters;
  637.         }
  638.  
  639.         friend bool operator!=(const TupleIt& lhs,const TupleIt& rhs)
  640.         {
  641.             return lhs.iters!=rhs.iters;
  642.         }
  643.  
  644.         // Forward Iterator requirements
  645.         TupleIt& operator++()
  646.         {
  647.             detail::preincrementTuple(iters);
  648.             return *this;
  649.         }
  650.    
  651.         TupleIt operator++(int)
  652.         {
  653.             TupleIt temp(*this);
  654.             ++*this;
  655.             return temp;
  656.         }
  657.  
  658.         // Bidirectional Iterator requirements
  659.         TupleIt& operator--()
  660.         {
  661.             detail::predecrementTuple(iters);
  662.             return *this;
  663.         }
  664.    
  665.         TupleIt operator--(int)
  666.         {
  667.             TupleIt temp(*this);
  668.             --*this;
  669.             return temp;
  670.         }
  671.    
  672.         // Random-Access Iterator requirements
  673.         TupleIt& operator+=(difference_type n)
  674.         {
  675.             detail::addToTuple(iters,n);
  676.             return *this;
  677.         }
  678.  
  679.         TupleIt& operator-=(difference_type n)
  680.         {
  681.             detail::subFromTuple(iters,n);
  682.             return *this;
  683.         }
  684.  
  685.         friend difference_type operator-(const TupleIt& a,const TupleIt& b)
  686.         {
  687.             return detail::diffTuples<difference_type>(a.iters,b.iters);
  688.         }
  689.  
  690.         value_type operator[](difference_type n) const
  691.         {
  692.             return *(*this+n);
  693.         }
  694.  
  695.     private:
  696.         // everything is mutable so we can modify it without affecting const correctness
  697.         // of client code
  698.         mutable IterTuple iters;
  699.         mutable boost::optional_detail::aligned_storage<typename TupleDefs::DeRefType> dataCache;
  700.         mutable bool cacheInitialized;
  701.     };
  702.  
  703.     // more random-access iterator requirements
  704.     template<typename IterTuple>
  705.     TupleIt<IterTuple> operator+(std::ptrdiff_t n,TupleIt<IterTuple> temp)
  706.     {
  707.         temp+=n;
  708.         return temp;
  709.     }
  710.  
  711.     template<typename IterTuple>
  712.     TupleIt<IterTuple> operator+(TupleIt<IterTuple> temp,std::ptrdiff_t n)
  713.     {
  714.         temp+=n;
  715.         return temp;
  716.     }
  717.  
  718.     template<typename IterTuple>
  719.     TupleIt<IterTuple> operator-(TupleIt<IterTuple> temp,std::ptrdiff_t n)
  720.     {
  721.         temp-=n;
  722.         return temp;
  723.     }
  724.  
  725.     template<typename IterTuple,typename IterTuple2>
  726.     bool operator<(const TupleIt<IterTuple>& a,const TupleIt<IterTuple2>& b)
  727.     {
  728.         return (b-a)>0;
  729.     }
  730.  
  731.     template<typename IterTuple,typename IterTuple2>
  732.     bool operator>(const TupleIt<IterTuple>& a,const TupleIt<IterTuple2>& b)
  733.     {
  734.         return b<a;
  735.     }
  736.  
  737.     template<typename IterTuple,typename IterTuple2>
  738.     bool operator>=(const TupleIt<IterTuple>& a,const TupleIt<IterTuple2>& b)
  739.     {
  740.         return !(b<a);
  741.     }
  742.  
  743.     template<typename IterTuple,typename IterTuple2>
  744.     bool operator<=(const TupleIt<IterTuple>& a,const TupleIt<IterTuple2>& b)
  745.     {
  746.         return !(b>a);
  747.     }
  748.  
  749.     // implementation of swap and iter_swap
  750.     template<typename IterTuple>
  751.     void swap(TupleIt<IterTuple>& lhs,TupleIt<IterTuple>& rhs)
  752.     {
  753.         lhs.swap(rhs);
  754.     }
  755.    
  756. //     template<typename IterTuple,IterTuple2>
  757. //     void iter_swap(const TupleIt<IterTuple>& lhs,const TupleIt<IterTuple2>& rhs)
  758. //     {
  759. //      lhs.iter_swap(rhs);
  760. //     }
  761.  
  762.     template<typename Iter1,typename Iter2>
  763.     TupleIt<typename boost::tuples::tuple<Iter1,Iter2> > makeTupleIterator(Iter1 i1,Iter2 i2)
  764.     {
  765.         return TupleIt<typename boost::tuples::tuple<Iter1,Iter2> >(boost::make_tuple(i1,i2));
  766.     }
  767.  
  768.     template<typename Iter1,typename Iter2,typename Iter3>
  769.     TupleIt<typename boost::tuples::tuple<Iter1,Iter2,Iter3> > makeTupleIterator(Iter1 i1,Iter2 i2,Iter3 i3)
  770.     {
  771.         return TupleIt<typename boost::tuples::tuple<Iter1,Iter2,Iter3> >(boost::make_tuple(i1,i2,i3));
  772.     }
  773.  
  774.     template<typename Iter1,typename Iter2,typename Iter3,typename Iter4>
  775.     TupleIt<typename boost::tuples::tuple<Iter1,Iter2,Iter3,Iter4> > makeTupleIterator(Iter1 i1,Iter2 i2,Iter3 i3,Iter4 i4)
  776.     {
  777.         return TupleIt<typename boost::tuples::tuple<Iter1,Iter2,Iter3,Iter4> >(boost::make_tuple(i1,i2,i3,i4));
  778.     }
  779.    
  780. }
  781.  
  782. #endif