Skip to content
Snippets Groups Projects
tuples.hh 8.49 KiB
Newer Older
  • Learn to ignore specific revisions
  • // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    // vi: set et ts=4 sw=2 sts=2:
    
    Jorrit Fahlke's avatar
    Jorrit Fahlke committed
    
    
    #ifndef DUNE_TUPLES_HH
    #define DUNE_TUPLES_HH
    
    
    Martin Nolte's avatar
    Martin Nolte committed
    #include <iostream>
    
    
    #include "typetraits.hh"
    
    
    namespace Dune {
    
      /** @addtogroup Common
       *
       * @{
       */
      /**
       * @file
    
    Oliver Sander's avatar
    Oliver Sander committed
       * @brief Fallback implementation of the std::tuple class
    
       *
       * This a refined implementation of the approach defined in
       * in the article &quot;Tuples and multiple return values
       * in C++&quot; of Jaakko J&auml;rvi (Turku Centre of Computer
       * Science, TUCS Technical Report No 249, March 1999,
       * ISBN 952-12-0401-X, ISSN 1239-1891) available from the
       * <a href="http://www.tucs.fi/publications/">TUCS publications archive</a>
       * @author Markus Blatt
       */
    
    
    
      template<class T>
      struct TupleAccessTraits
      {
    
        typedef typename ConstantVolatileTraits<T>::ConstType& ConstType;
    
        typedef T& NonConstType;
        typedef const typename ConstantVolatileTraits<T>::UnqualifiedType& ParameterType;
      };
    
    
      template<class T>
      struct TupleAccessTraits<T*>
      {
        typedef typename ConstantVolatileTraits<T>::ConstType* ConstType;
        typedef T* NonConstType;
        typedef T* ParameterType;
      };
    
    
      template<class T>
      struct TupleAccessTraits<T&>
      {
    
        typedef T& ConstType;
    
        typedef T& NonConstType;
        typedef T& ParameterType;
      };
    
      // pull in default implementations
    
      using std::tuple;
      using std::tuple_element;
    
      using std::tuple_size;
      using std::tie;
      using std::make_tuple;
    
      template<int i>
      struct tuple_writer
      {
    
        static std::ostream& put(std::ostream& os, const T& t, const char* delim=", ")
        {
    
    Martin Nolte's avatar
    Martin Nolte committed
          return tuple_writer<i-1>::put(os,t,delim)<<delim<<Dune::get<i-1>(t);
        }
    
        template< class T >
        static std::istream &get ( std::istream &is, T &t, const char *delim = "," )
        {
          tuple_writer< i-1 >::get( is, t, delim );
          for( const char *it = delim; is && (*it != 0); ++it )
          {
            char c = 0;
            is >> c;
            if( c != *it )
              is.setstate( std::ios::failbit );
          }
          return is >> Dune::get< i-1 >( t );
    
        }
      };
    
      template<>
      struct tuple_writer<1>
      {
        template<class T>
        static std::ostream& put(std::ostream& os, const T& t, const char* delim=", ")
    
    Martin Nolte's avatar
    Martin Nolte committed
          return os<<Dune::get<0>(t);
        }
    
        template< class T >
        static std::istream &get ( std::istream &is, T &t, const char *delim = ", " )
        {
          return is >> Dune::get< 0 >( t );
    
        }
      };
    
      template<>
      struct tuple_writer<0>
      {
    
        static std::ostream& put(std::ostream& os, const T& t, const char* delim=", ")
    
    Martin Nolte's avatar
    Martin Nolte committed
    
        template< class T >
        static std::istream &get ( std::istream &is, T &t, const char *delim = ", " )
        {
          return is;
        }
    
    Markus Blatt's avatar
    Markus Blatt committed
    
    
      /**
       * \brief Print a tuple.
       */
    
      template<typename T1>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1> & t)
      {
    
        typedef tuple<T1> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2> & t)
      {
    
        typedef tuple<T1,T2> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2, typename T3>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3> & t)
      {
    
        typedef tuple<T1,T2,T3> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2, typename T3, typename T4>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4> & t)
      {
    
        typedef tuple<T1,T2,T3,T4> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5> & t)
      {
    
        typedef tuple<T1,T2,T3,T4,T5> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6> & t)
      {
    
        typedef tuple<T1,T2,T3,T4,T5,T6> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7> & t)
      {
    
        typedef tuple<T1,T2,T3,T4,T5,T6,T7> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
          typename T8>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7,T8> & t)
      {
    
        typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
          typename T8, typename T9>
    
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> & t)
    
        typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
          typename T8, typename T9, typename T10>
      inline std::ostream& operator<<( std::ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> & t)
      {
    
        typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::put(os, t);
    
    Martin Nolte's avatar
    Martin Nolte committed
      /**
       * \brief Read a tuple.
       */
      template<typename T1>
      inline std::istream& operator>>( std::istream& is, tuple<T1> & t)
      {
        typedef tuple<T1> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2> & t)
      {
        typedef tuple<T1,T2> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3> & t)
      {
        typedef tuple<T1,T2,T3> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4> & t)
      {
        typedef tuple<T1,T2,T3,T4> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5> & t)
      {
        typedef tuple<T1,T2,T3,T4,T5> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6> & t)
      {
        typedef tuple<T1,T2,T3,T4,T5,T6> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7> & t)
      {
        typedef tuple<T1,T2,T3,T4,T5,T6,T7> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
          typename T8>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7,T8> & t)
      {
        typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
          typename T8, typename T9>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> & t)
      {
        typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }
    
      template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
          typename T8, typename T9, typename T10>
      inline std::istream& operator>>( std::istream& is, tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> & t)
      {
        typedef tuple<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> TupleT;
        return tuple_writer<tuple_size<TupleT>::value>::get(is, t);
      }