⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tuple_basic.hpp

📁 CGAL is a collaborative effort of several sites in Europe and Israel. The goal is to make the most i
💻 HPP
📖 第 1 页 / 共 2 页
字号:
//  tuple_basic.hpp -----------------------------------------------------// Copyright (C) 1999, 2000 Jaakko J鋜vi (jaakko.jarvi@cs.utu.fi)//// 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)// For more information, see http://www.boost.org// Outside help:// This and that, Gary Powell.// Fixed return types for get_head/get_tail// ( and other bugs ) per suggestion of Jens Maurer// simplified element type accessors + bug fix  (Jeremy Siek)// Several changes/additions according to suggestions by Douglas Gregor,// William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,// David Abrahams.// Revision history:// 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes// 2002 04 18 Jaakko: tuple element types can be void or plain function//                    types, as long as no object is created.//                    Tuple objects can no hold even noncopyable types//                    such as arrays.// 2001 10 22 John Maddock//      Fixes for Borland C++// 2001 08 30 David Abrahams//      Added default constructor for cons<>.// -----------------------------------------------------------------#ifndef BOOST_TUPLE_BASIC_HPP#define BOOST_TUPLE_BASIC_HPP#include <utility> // needed for the assignment from pair to tuple#include "boost/type_traits/cv_traits.hpp"#include "boost/type_traits/function_traits.hpp"#include "boost/detail/workaround.hpp" // needed for BOOST_WORKAROUNDnamespace boost {namespace tuples {// -- null_type --------------------------------------------------------struct null_type {};// a helper function to provide a const null_type type temporarynamespace detail {  inline const null_type cnull() { return null_type(); }// -- if construct ------------------------------------------------// Proposed by Krzysztof Czarnecki and Ulrich Eiseneckertemplate <bool If, class Then, class Else> struct IF { typedef Then RET; };template <class Then, class Else> struct IF<false, Then, Else> {  typedef Else RET;};} // end detail// - cons forward declaration -----------------------------------------------template <class HT, class TT> struct cons;// - tuple forward declaration -----------------------------------------------template <  class T0 = null_type, class T1 = null_type, class T2 = null_type,  class T3 = null_type, class T4 = null_type, class T5 = null_type,  class T6 = null_type, class T7 = null_type, class T8 = null_type,  class T9 = null_type>class tuple;// tuple_length forward declarationtemplate<class T> struct length;namespace detail {// -- generate error template, referencing to non-existing members of this// template is used to produce compilation errors intentionallytemplate<class T>class generate_error;// - cons getters --------------------------------------------------------// called: get_class<N>::get<RETURN_TYPE>(aTuple)template< int N >struct get_class {  template<class RET, class HT, class TT >  inline static RET get(const cons<HT, TT>& t)  {#if BOOST_WORKAROUND(__IBMCPP__,==600)    // vacpp 6.0 is not very consistent regarding the member template keyword    // Here it generates an error when the template keyword is used.    return get_class<N-1>::get<RET>(t.tail);#else    return get_class<N-1>::BOOST_NESTED_TEMPLATE get<RET>(t.tail);#endif  }  template<class RET, class HT, class TT >  inline static RET get(cons<HT, TT>& t)  {#if BOOST_WORKAROUND(__IBMCPP__,==600)    return get_class<N-1>::get<RET>(t.tail);#else    return get_class<N-1>::BOOST_NESTED_TEMPLATE get<RET>(t.tail);#endif  }};template<>struct get_class<0> {  template<class RET, class HT, class TT>  inline static RET get(const cons<HT, TT>& t)  {    return t.head;  }  template<class RET, class HT, class TT>  inline static RET get(cons<HT, TT>& t)  {    return t.head;  }};} // end of namespace detail// -cons type accessors ----------------------------------------// typename tuples::element<N,T>::type gets the type of the// Nth element ot T, first element is at index 0// -------------------------------------------------------#ifndef BOOST_NO_CV_SPECIALIZATIONStemplate<int N, class T>struct element{private:  typedef typename T::tail_type Next;public:  typedef typename element<N-1, Next>::type type;};template<class T>struct element<0,T>{  typedef typename T::head_type type;};template<int N, class T>struct element<N, const T>{private:  typedef typename T::tail_type Next;  typedef typename element<N-1, Next>::type unqualified_type;public:#if BOOST_WORKAROUND(__BORLANDC__,<0x600)  typedef const unqualified_type type;#else  typedef typename boost::add_const<unqualified_type>::type type;#endif};template<class T>struct element<0,const T>{#if BOOST_WORKAROUND(__BORLANDC__,<0x600)  typedef const typename T::head_type type;#else  typedef typename boost::add_const<typename T::head_type>::type type;#endif};#else // def BOOST_NO_CV_SPECIALIZATIONSnamespace detail {template<int N, class T, bool IsConst>struct element_impl{private:  typedef typename T::tail_type Next;public:  typedef typename element_impl<N-1, Next, IsConst>::type type;};template<int N, class T>struct element_impl<N, T, true /* IsConst */>{private:  typedef typename T::tail_type Next;public:  typedef const typename element_impl<N-1, Next, true>::type type;};template<class T>struct element_impl<0, T, false /* IsConst */>{  typedef typename T::head_type type;};template<class T>struct element_impl<0, T, true /* IsConst */>{  typedef const typename T::head_type type;};} // end of namespace detailtemplate<int N, class T>struct element:   public detail::element_impl<N, T, ::boost::is_const<T>::value>{};#endif// -get function templates -----------------------------------------------// Usage: get<N>(aTuple)// -- some traits classes for get functions// access traits lifted from detail namespace to be part of the interface,// (Joel de Guzman's suggestion). Rationale: get functions are part of the// interface, so should the way to express their return types be.template <class T> struct access_traits {  typedef const T& const_type;  typedef T& non_const_type;  typedef const typename boost::remove_cv<T>::type& parameter_type;// used as the tuple constructors parameter types// Rationale: non-reference tuple element types can be cv-qualified.// It should be possible to initialize such types with temporaries,// and when binding temporaries to references, the reference must// be non-volatile and const. 8.5.3. (5)};template <class T> struct access_traits<T&> {  typedef T& const_type;  typedef T& non_const_type;  typedef T& parameter_type;};// get function for non-const cons-lists, returns a reference to the elementtemplate<int N, class HT, class TT>inline typename access_traits<                  typename element<N, cons<HT, TT> >::type                >::non_const_typeget(cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {#if BOOST_WORKAROUND(__IBMCPP__,==600 )  return detail::get_class<N>::#else  return detail::get_class<N>::BOOST_NESTED_TEMPLATE#endif         get<           typename access_traits<             typename element<N, cons<HT, TT> >::type           >::non_const_type,           HT,TT         >(c);}// get function for const cons-lists, returns a const reference to// the element. If the element is a reference, returns the reference// as such (that is, can return a non-const reference)template<int N, class HT, class TT>inline typename access_traits<                  typename element<N, cons<HT, TT> >::type                >::const_typeget(const cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {#if BOOST_WORKAROUND(__IBMCPP__,==600)  return detail::get_class<N>::#else  return detail::get_class<N>::BOOST_NESTED_TEMPLATE#endif         get<           typename access_traits<             typename element<N, cons<HT, TT> >::type           >::const_type,           HT,TT         >(c);}// -- the cons template  --------------------------------------------------namespace detail {//  These helper templates wrap void types and plain function types.//  The reationale is to allow one to write tuple types with those types//  as elements, even though it is not possible to instantiate such object.//  E.g: typedef tuple<void> some_type; // ok//  but: some_type x; // failstemplate <class T> class non_storeable_type {  non_storeable_type();};template <class T> struct wrap_non_storeable_type {  typedef typename IF<    ::boost::is_function<T>::value, non_storeable_type<T>, T  >::RET type;};template <> struct wrap_non_storeable_type<void> {  typedef non_storeable_type<void> type;};} // detailtemplate <class HT, class TT>struct cons {  typedef HT head_type;  typedef TT tail_type;  typedef typename    detail::wrap_non_storeable_type<head_type>::type stored_head_type;  stored_head_type head;  tail_type tail;  typename access_traits<stored_head_type>::non_const_type  get_head() { return head; }  typename access_traits<tail_type>::non_const_type  get_tail() { return tail; }  typename access_traits<stored_head_type>::const_type  get_head() const { return head; }  typename access_traits<tail_type>::const_type  get_tail() const { return tail; }  cons() : head(), tail() {}  //  cons() : head(detail::default_arg<HT>::f()), tail() {}  // the argument for head is not strictly needed, but it prevents  // array type elements. This is good, since array type elements  // cannot be supported properly in any case (no assignment,  // copy works only if the tails are exactly the same type, ...)  cons(typename access_traits<stored_head_type>::parameter_type h,       const tail_type& t)    : head (h), tail(t) {}  template <class T1, class T2, class T3, class T4, class T5,            class T6, class T7, class T8, class T9, class T10>  cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )    : head (t1),      tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())      {}  template <class T2, class T3, class T4, class T5,            class T6, class T7, class T8, class T9, class T10>  cons( const null_type& t1, T2& t2, T3& t3, T4& t4, T5& t5,        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )    : head (),      tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())      {}  template <class HT2, class TT2>  cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}  template <class HT2, class TT2>  cons& operator=( const cons<HT2, TT2>& u ) {    head=u.head; tail=u.tail; return *this;  }  // must define assignment operator explicitly, implicit version is  // illformed if HT is a reference (12.8. (12))  cons& operator=(const cons& u) {    head = u.head; tail = u.tail;  return *this;  }  template <class T1, class T2>  cons& operator=( const std::pair<T1, T2>& u ) {    BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2    head = u.first; tail.head = u.second; return *this;  }  // get member functions (non-const and const)  template <int N>  typename access_traits<             typename element<N, cons<HT, TT> >::type           >::non_const_type  get() {    return boost::tuples::get<N>(*this); // delegate to non-member get  }  template <int N>  typename access_traits<             typename element<N, cons<HT, TT> >::type           >::const_type  get() const {    return boost::tuples::get<N>(*this); // delegate to non-member get  }};template <class HT>struct cons<HT, null_type> {  typedef HT head_type;  typedef null_type tail_type;  typedef cons<HT, null_type> self_type;  typedef typename    detail::wrap_non_storeable_type<head_type>::type stored_head_type;  stored_head_type head;  typename access_traits<stored_head_type>::non_const_type  get_head() { return head; }  null_type get_tail() { return null_type(); }  typename access_traits<stored_head_type>::const_type  get_head() const { return head; }  const null_type get_tail() const { return null_type(); }  //  cons() : head(detail::default_arg<HT>::f()) {}  cons() : head() {}  cons(typename access_traits<stored_head_type>::parameter_type h,       const null_type& = null_type())    : head (h) {}  template<class T1>  cons(T1& t1, const null_type&, const null_type&, const null_type&,       const null_type&, const null_type&, const null_type&,       const null_type&, const null_type&, const null_type&)  : head (t1) {}  cons(const null_type&,       const null_type&, const null_type&, const null_type&,       const null_type&, const null_type&, const null_type&,       const null_type&, const null_type&, const null_type&)  : head () {}  template <class HT2>  cons( const cons<HT2, null_type>& u ) : head(u.head) {}  template <class HT2>  cons& operator=(const cons<HT2, null_type>& u )  { head = u.head; return *this; }  // must define assignment operator explicitely, implicit version  // is illformed if HT is a reference  cons& operator=(const cons& u) { head = u.head; return *this; }  template <int N>  typename access_traits<             typename element<N, self_type>::type            >::non_const_type  get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {    return boost::tuples::get<N>(*this);  }  template <int N>  typename access_traits<             typename element<N, self_type>::type           >::const_type  get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) const {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -