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