blob: 691048ab5b153d88cd939918ceb726ac472b2d65 [file] [log] [blame]
// -*- 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