| // -*- C++ -*- |
| /*************************************************************************** |
| * |
| * tuple - fixed-size collections with variable, heterogenous types |
| * |
| * $Id: tuple 677458 2008-07-16 22:49:27Z elemings $ |
| * |
| *************************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed |
| * with this work for additional information regarding copyright |
| * ownership. The ASF licenses this file to you under the Apache |
| * License, Version 2.0 (the "License"); you may not use this file |
| * except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. See the License for the specific language governing |
| * permissions and limitations under the License. |
| * |
| * Copyright 2008 Rogue Wave Software, Inc. |
| * |
| **************************************************************************/ |
| |
| #ifndef _RWSTD_TUPLE_INCLUDED |
| # define _RWSTD_TUPLE_INCLUDED |
| |
| # include <rw/_defs.h> |
| |
| # if defined _RWSTD_NO_EXT_CXX_0X |
| # error _RWSTD_NO_EXT_CXX_0X defined and C++0x header included |
| # endif // defined _RWSTD_NO_EXT_CXX_0X |
| |
| # include <rw/_forward.h> // for _RWSTD_FORWARD, _RWSTD_MOVE |
| # include <rw/_meta_cv.h> // for _RWSTD_ADD_CONST |
| # include <rw/_meta_help.h> // for __rw_integral_constant |
| # include <rw/_meta_ref.h> // for _RWSTD_ADD_LVALUE_REFERENCE |
| # include <rw/_pair.h> // for std::pair |
| |
| # include <rw/_tuple.h> |
| |
| # if !defined _RWSTD_NO_VARIADIC_TEMPLATES |
| |
| |
| _RWSTD_NAMESPACE (std) { |
| |
| |
| // 20.3.1, class template tuple: |
| |
| template <class... _TypesT> |
| class tuple; |
| |
| _RWSTD_SPECIALIZED_CLASS |
| class tuple<> |
| { |
| // empty |
| }; |
| |
| template <class... _TypesT> |
| class tuple |
| : public _RW::__rw_tuple<_TypesT...> |
| { |
| typedef _RW::__rw_tuple<_TypesT...> _Base; |
| |
| # undef _BaseU |
| # define _BaseU _RW::__rw_tuple<_TypesU...> |
| |
| public: |
| |
| tuple () |
| : _Base () { /* empty */ } |
| |
| // employ _RWSTD_STATIC_CAST to ensure compiler binds to correct |
| // base class ctors and operators |
| |
| tuple (const tuple& __tuple) |
| : _Base (_RWSTD_STATIC_CAST (const _Base&, __tuple)) { /* empty */ } |
| |
| tuple& operator= (const tuple& __tuple) { |
| _Base::operator= (_RWSTD_STATIC_CAST (const _Base&, __tuple)); |
| return *this; |
| } |
| |
| explicit |
| tuple (const _TypesT&... __values) |
| : _Base (__values...) { /* empty */ } |
| |
| template <class... _TypesU> |
| tuple (const tuple<_TypesU...>& __tuple) |
| : _Base (_RWSTD_STATIC_CAST (const _BaseU&, __tuple)) { /* empty */ } |
| |
| template <class... _TypesU> |
| tuple& operator= (const tuple<_TypesU...>& __tuple) { |
| _Base::operator= (_RWSTD_STATIC_CAST (const _BaseU&, __tuple)); |
| return *this; |
| } |
| |
| # if !defined _RWSTD_NO_RVALUE_REFERENCES |
| |
| tuple (tuple&& __tuple) |
| : _Base (_RWSTD_FORWARD (_Base, __tuple)) { /* empty */ } |
| |
| tuple& operator= (tuple&& __tuple) { |
| _Base::operator= (_RWSTD_FORWARD (_Base, __tuple)); |
| return *this; |
| } |
| |
| template <class... _TypesU> |
| explicit tuple (_TypesU&&... __values) |
| : _Base (_RWSTD_FORWARD (_TypesU, __values)...) { /* empty */ } |
| |
| template <class... _TypesU> |
| tuple (tuple<_TypesU...>&& __tuple) |
| : _Base (_RWSTD_FORWARD (_BaseU, __tuple)) { /* empty */ } |
| |
| template <class... _TypesU> |
| tuple& operator= (tuple<_TypesU...>&& __tuple) { |
| _Base::operator= (_RWSTD_FORWARD (_BaseU, __tuple)); |
| return *this; |
| } |
| |
| // allocator-extended constructors: |
| |
| template <class _Alloc, class... _TypesU> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| const _TypesU&&... __values); |
| |
| template <class _Alloc> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| tuple&& __tuple); |
| |
| template <class _Alloc, class... _TypesU> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| tuple<_TypesU...>&& __tuple); |
| |
| # endif // !defined _RWSTD_NO_RVALUE_REFERENCES |
| |
| # undef _BaseU |
| |
| template <class _Alloc> |
| tuple (allocator_arg_t, const _Alloc& __alloc); |
| |
| template <class _Alloc> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| const _TypesT&... __values); |
| |
| template <class _Alloc> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| const tuple& __tuple); |
| |
| template <class _Alloc, class... _TypesU> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| const tuple<_TypesU...>& __tuple); |
| |
| }; |
| |
| |
| template <class _TypeT1, class _TypeT2> |
| class tuple<_TypeT1, _TypeT2> |
| : public _RW::__rw_tuple<_TypeT1, _TypeT2> |
| { |
| typedef _RW::__rw_tuple<_TypeT1, _TypeT2> _Base; |
| |
| # undef _BaseU |
| # define _BaseU _RW::__rw_tuple<_TypeU1, _TypeU2> |
| |
| public: |
| |
| // 20.3.1.2, construction: |
| |
| tuple () |
| : _Base () { /* empty */ } |
| |
| tuple (const tuple& __tuple) |
| : _Base (_RWSTD_STATIC_CAST (const _Base&, __tuple)) { /* empty */ } |
| |
| tuple& operator= (const tuple& __tuple) { |
| _Base::operator= (_RWSTD_STATIC_CAST (const _Base&, __tuple)); |
| return *this; |
| } |
| |
| tuple (const _TypeT1& __x, const _TypeT2& __y) |
| : _Base (__x, __y) { /* empty */ } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple (const tuple<_TypeU1, _TypeU2>& __tuple) |
| : _Base (_RWSTD_STATIC_CAST (const _BaseU&, __tuple)) { /* empty */ } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple& operator= (const tuple<_TypeU1, _TypeU2>& __tuple) { |
| _Base::operator= (_RWSTD_STATIC_CAST (const _BaseU&, __tuple)); |
| return *this; |
| } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple (const pair<_TypeU1, _TypeU2>& __pair) |
| : _Base (__pair.first, __pair.second) { /* empty */ } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple& operator= (const pair<_TypeU1, _TypeU2>& __pair) { |
| _Base::operator= (__pair.first, __pair.second); |
| return *this; |
| } |
| |
| # if !defined _RWSTD_NO_RVALUE_REFERENCES |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple (_TypeU1&& __x, _TypeU2&& __y) |
| : _Base (_RWSTD_MOVE (__x), _RWSTD_MOVE (__y)) { /* empty */ } |
| |
| tuple (tuple&& __tuple) |
| : _Base (_RWSTD_FORWARD (_Base, __tuple)) { /* empty */ } |
| |
| tuple& operator= (tuple&& __tuple) { |
| _Base::operator= (_RWSTD_FORWARD (_Base, __tuple)); |
| return *this; |
| } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple (tuple<_TypeU1, _TypeU2>&& __tuple) |
| : _Base (_RWSTD_FORWARD (_BaseU, __tuple)) |
| { /* empty */ } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple& operator= (tuple<_TypeU1, _TypeU2>&& __tuple) { |
| _Base::operator= (_RWSTD_FORWARD (_BaseU, __tuple)); |
| return *this; |
| } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple (pair<_TypeU1, _TypeU2>&& __pair) |
| : _Base (_RWSTD_MOVE (__pair.first), |
| _RWSTD_MOVE ( __pair.second)) { /* empty */ } |
| |
| template <class _TypeU1, class _TypeU2> |
| tuple& operator= (pair<_TypeU1, _TypeU2>&& __pair) { |
| _Base::operator= (__pair.first, __pair.second); |
| return *this; |
| } |
| |
| // allocator-extended constructors: |
| |
| template <class _Alloc, class _TypeU1, class _TypeU2> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| pair<_TypeU1, _TypeU2>&& __pair); |
| |
| # endif // !defined _RWSTD_NO_RVALUE_REFERENCES |
| |
| # undef _BaseU |
| |
| template <class _Alloc, class _TypeU1, class _TypeU2> |
| tuple (allocator_arg_t, const _Alloc& __alloc, |
| const pair<_TypeU1, _TypeU2>& __pair); |
| |
| }; |
| |
| |
| // 20.3.1.1, tuple traits: |
| |
| template <class _Type, class _Alloc> |
| struct uses_allocator; |
| |
| template <class... _TypesT, class _Alloc> |
| struct uses_allocator<tuple<_TypesT...>, _Alloc> |
| : _RW::__rw_true_type |
| { |
| // empty |
| }; |
| |
| |
| template <class _Type> |
| struct constructible_with_allocator_prefix; |
| |
| template <class... _TypesT> |
| struct constructible_with_allocator_prefix<tuple<_TypesT...> > |
| : _RW::__rw_true_type |
| { |
| // empty |
| }; |
| |
| |
| // 20.3.3, tuple creation functions: |
| |
| const _RW::__rw_ignore ignore = _RW::__rw_ignore (); |
| |
| |
| # if !defined _RWSTD_NO_RVALUE_REFERENCES |
| |
| template <class... _TypesT> |
| inline tuple<typename _RW::__rw_make_tuple<_TypesT>::_C_type...> |
| make_tuple (_TypesT&&... __values) |
| { |
| typedef tuple<typename _RW::__rw_make_tuple<_TypesT>::_C_type...> _Tuple; |
| return _Tuple (_RWSTD_FORWARD (_TypesT, __values)...); |
| } |
| |
| |
| template <class... _TypesT, class... _TypesU> |
| tuple<_TypesT..., _TypesU...> |
| tuple_cat (tuple<_TypesT...>&& __x, |
| const tuple<_TypesU...>& __y); |
| |
| template <class... _TypesT, class... _TypesU> |
| tuple<_TypesT..., _TypesU...> |
| tuple_cat (const tuple<_TypesT...>& __x, |
| tuple<_TypesU...>&& __y); |
| |
| template <class... _TypesT, class... _TypesU> |
| tuple<_TypesT..., _TypesU...> |
| tuple_cat (tuple<_TypesT...>&& __x, |
| tuple<_TypesU...>&& __y); |
| |
| # endif // !defined _RWSTD_NO_RVALUE_REFERENCES |
| |
| template <class... _TypesT, class... _TypesU> |
| tuple<_TypesT..., _TypesU...> |
| tuple_cat (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y); |
| |
| |
| template <class... _TypesT> |
| inline tuple<_TypesT&...> |
| tie (_TypesT&... __values) |
| { |
| return tuple<_TypesT&...> (__values...); |
| } |
| |
| |
| // 20.3.1.4, tuple helper classes: |
| |
| template <class _TypesT> |
| class tuple_size; |
| |
| template <class... _TypesT> |
| class tuple_size< tuple<_TypesT...> > |
| : public _RW::__rw_integral_constant< _RWSTD_SIZE_T, |
| sizeof... (_TypesT) > |
| { |
| // empty |
| }; |
| |
| |
| template <_RWSTD_SIZE_T _Index, class... _TypesT> |
| struct tuple_element; |
| |
| template <class _Head, class... _Tail> |
| struct tuple_element<0, tuple<_Head, _Tail...> > |
| { |
| typedef _Head type; |
| |
| //internal: |
| |
| typedef _RW::__rw_tuple<_Head, _Tail...> _Tuple; |
| |
| typedef typename _RWSTD_ADD_LVALUE_REFERENCE (_Head) _Ref; |
| typedef typename _RWSTD_ADD_CONST (_Head) _ConstHead; |
| typedef typename _RWSTD_ADD_LVALUE_REFERENCE (_ConstHead) _ConstRef; |
| |
| static _Ref |
| _C_get (_Tuple& __tuple) { return __tuple._C_head (); } |
| |
| static _ConstRef |
| _C_get (const _Tuple& __tuple) { return __tuple._C_head (); } |
| }; |
| |
| template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail> |
| struct tuple_element<_Index, tuple<_Head, _Tail...> > |
| : public tuple_element<_Index - 1, tuple<_Tail...> > |
| { |
| // empty |
| }; |
| |
| |
| // 20.3.1.5, element access: |
| |
| template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail> |
| inline typename tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref |
| get (tuple<_Head, _Tail...>& __tuple) |
| { |
| typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple; |
| return _Tuple::_C_get (__tuple); |
| } |
| |
| template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail> |
| inline typename tuple_element<_Index, tuple<_Head, _Tail...> >::_ConstRef |
| get (const tuple<_Head, _Tail...>& __tuple) |
| { |
| typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple; |
| return _Tuple::_C_get (__tuple); |
| } |
| |
| |
| // 20.3.1.6, relational operators: |
| |
| template <class... _TypesT, class... _TypesU> |
| inline bool |
| operator== (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y) |
| { |
| return _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesT...>&, __x) |
| == _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesU...>&, __y); |
| } |
| |
| _RWSTD_SPECIALIZED_FUNCTION |
| inline bool |
| operator== (const tuple<>& /*__x*/, |
| const tuple<>& /*__y*/) |
| { |
| return true; |
| } |
| |
| template <class... _TypesT, class... _TypesU> |
| inline bool |
| operator< (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y) |
| { |
| return _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesT...>&, __x) |
| < _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesU...>&, __y); |
| } |
| |
| _RWSTD_SPECIALIZED_FUNCTION |
| inline bool |
| operator< (const tuple<>& /*__x*/, |
| const tuple<>& /*__y*/) |
| { |
| return false; |
| } |
| |
| template <class... _TypesT, class... _TypesU> |
| inline bool |
| operator!= (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y) |
| { |
| return !(__x == __y); |
| } |
| |
| template <class... _TypesT, class... _TypesU> |
| inline bool |
| operator> (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y) |
| { |
| return __y < __x; |
| } |
| |
| template <class... _TypesT, class... _TypesU> |
| inline bool |
| operator<= (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y) |
| { |
| return !(__y < __x); |
| } |
| |
| template <class... _TypesT, class... _TypesU> |
| inline bool |
| operator>= (const tuple<_TypesT...>& __x, |
| const tuple<_TypesU...>& __y) |
| { |
| return !(__x < __y); |
| } |
| |
| |
| } // namespace std |
| |
| |
| # endif // !defined _RWSTD_NO_VARIADIC_TEMPLATES |
| |
| #endif // _RWSTD_TUPLE_INCLUDED |