// utility standard header #pragma once #ifndef _UTILITY_ #define _UTILITY_ #ifndef RC_INVOKED #include #include #include #pragma pack(push,_CRT_PACKING) #pragma warning(push,3) #pragma push_macro("new") #undef new #pragma warning(disable: 4180 4512) _STD_BEGIN // TEMPLATE FUNCTION iter_swap (from ) template inline void swap(_Ty&, _Ty&) _NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value && is_nothrow_move_assignable<_Ty>::value); template inline void iter_swap(_FwdIt1 _Left, _FwdIt2 _Right) { // swap *_Left and *_Right swap(*_Left, *_Right); } // TEMPLATE FUNCTION swap template inline void swap(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size]) _NOEXCEPT_OP(_NOEXCEPT_OP(swap(*_Left, *_Right))) { // exchange arrays stored at _Left and _Right if (&_Left != &_Right) { // worth swapping, swap ranges _Ty *_First1 = _Left; _Ty *_Last1 = _First1 + _Size; _Ty *_First2 = _Right; for (; _First1 != _Last1; ++_First1, ++_First2) _STD iter_swap(_First1, _First2); } } template inline void swap(_Ty& _Left, _Ty& _Right) _NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value && is_nothrow_move_assignable<_Ty>::value) { // exchange values stored at _Left and _Right _Ty _Tmp = _Move(_Left); _Left = _Move(_Right); _Right = _Move(_Tmp); } // TEMPLATE FUNCTION _Swap_adl template inline void _Swap_adl(_Ty& _Left, _Ty& _Right) _NOEXCEPT_OP(_NOEXCEPT_OP(swap(_Left, _Right))) { // exchange values stored at _Left and _Right, using ADL swap(_Left, _Right); } // STRUCT piecewise_construct_t struct piecewise_construct_t { // tag type for pair tuple arguments }; _CONST_DATA piecewise_construct_t piecewise_construct{}; // TEMPLATE STRUCT pair template class tuple; template struct pair { // store a pair of values typedef pair<_Ty1, _Ty2> _Myt; typedef _Ty1 first_type; typedef _Ty2 second_type; _CONST_FUN pair() : first(), second() { // default construct } _CONST_FUN pair(const _Ty1& _Val1, const _Ty2& _Val2) : first(_Val1), second(_Val2) { // construct from specified values } pair(const pair&) = default; pair(pair&&) = default; template::value && is_convertible::value, void>::type> _CONST_FUN pair(const pair<_Other1, _Other2>& _Right) : first(_Right.first), second(_Right.second) { // construct from compatible pair } template _Myt& operator=(const pair<_Other1, _Other2>& _Right) { // assign from compatible pair first = _Right.first; second = _Right.second; return (*this); } template inline pair(_Tuple1& _Val1, _Tuple2& _Val2, integer_sequence, integer_sequence); template inline pair(piecewise_construct_t, tuple<_Types1...> _Val1, tuple<_Types2...> _Val2); template::value && is_convertible<_Other2, _Ty2>::value, void>::type> _CONST_FUN pair(_Other1&& _Val1, _Other2&& _Val2) _NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1&&>::value && is_nothrow_constructible<_Ty2, _Other2&&>::value)) : first(_STD forward<_Other1>(_Val1)), second(_STD forward<_Other2>(_Val2)) { // construct from moved values } template::value && is_convertible<_Other2, _Ty2>::value, void>::type> _CONST_FUN pair(pair<_Other1, _Other2>&& _Right) _NOEXCEPT_OP((is_nothrow_constructible<_Ty1, _Other1&&>::value && is_nothrow_constructible<_Ty2, _Other2&&>::value)) : first(_STD forward<_Other1>(_Right.first)), second(_STD forward<_Other2>(_Right.second)) { // construct from moved compatible pair } template _Myt& operator=(pair<_Other1, _Other2>&& _Right) { // assign from moved compatible pair first = _STD forward<_Other1>(_Right.first); second = _STD forward<_Other2>(_Right.second); return (*this); } _Myt& operator=(_Myt&& _Right) _NOEXCEPT_OP((is_nothrow_move_assignable<_Ty1>::value && is_nothrow_move_assignable<_Ty2>::value)) { // assign from moved pair first = _STD forward<_Ty1>(_Right.first); second = _STD forward<_Ty2>(_Right.second); return (*this); } void swap(_Myt& _Right) _NOEXCEPT_OP(_NOEXCEPT_OP(_Swap_adl(this->first, _Right.first)) && _NOEXCEPT_OP(_Swap_adl(this->second, _Right.second))) { // exchange contents with _Right if (this != &_Right) { // different, worth swapping _Swap_adl(first, _Right.first); _Swap_adl(second, _Right.second); } } _Myt& operator=(const _Myt& _Right) { // assign from copied pair first = _Right.first; second = _Right.second; return (*this); } _Ty1 first; // the first stored value _Ty2 second; // the second stored value }; // pair TEMPLATE FUNCTIONS template inline void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right) _NOEXCEPT_OP(_NOEXCEPT_OP(_Left.swap(_Right))) { // swap _Left and _Right pairs _Left.swap(_Right); } template inline _CONST_FUN bool operator==(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test for pair equality return (_Left.first == _Right.first && _Left.second == _Right.second); } template inline _CONST_FUN bool operator!=(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test for pair inequality return (!(_Left == _Right)); } template inline _CONST_FUN bool operator<(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left < _Right for pairs return (_Left.first < _Right.first || (!(_Right.first < _Left.first) && _Left.second < _Right.second)); } template inline _CONST_FUN bool operator>(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left > _Right for pairs return (_Right < _Left); } template inline _CONST_FUN bool operator<=(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left <= _Right for pairs return (!(_Right < _Left)); } template inline _CONST_FUN bool operator>=(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) { // test if _Left >= _Right for pairs return (!(_Left < _Right)); } // TEMPLATE FUNCTION make_pair template inline _CONST_FUN pair::type, typename _Unrefwrap<_Ty2>::type> make_pair(_Ty1&& _Val1, _Ty2&& _Val2) { // return pair composed from arguments typedef pair::type, typename _Unrefwrap<_Ty2>::type> _Mypair; return (_Mypair(_STD forward<_Ty1>(_Val1), _STD forward<_Ty2>(_Val2))); } // TEMPLATE OPERATORS namespace rel_ops { // nested namespace to hide relational operators from std template inline bool operator!=(const _Ty& _Left, const _Ty& _Right) { // test for inequality, in terms of equality return (!(_Left == _Right)); } template inline bool operator>(const _Ty& _Left, const _Ty& _Right) { // test if _Left > _Right, in terms of operator< return (_Right < _Left); } template inline bool operator<=(const _Ty& _Left, const _Ty& _Right) { // test if _Left <= _Right, in terms of operator< return (!(_Right < _Left)); } template inline bool operator>=(const _Ty& _Left, const _Ty& _Right) { // test if _Left >= _Right, in terms of operator< return (!(_Left < _Right)); } } _STD_END _STD_BEGIN template class array; // TEMPLATE STRUCT tuple_size template struct tuple_size { // size of non-tuple static_assert(_Always_false<_Tuple>::value, "The C++ Standard doesn't define tuple_size for this type."); }; template struct tuple_size > : integral_constant { // struct to determine number of elements in array }; template struct tuple_size > : integral_constant { // size of pair }; template struct tuple_size > : integral_constant { // size of tuple }; template struct tuple_size : tuple_size<_Tuple> { // size of const tuple }; template struct tuple_size : tuple_size<_Tuple> { // size of volatile tuple }; template struct tuple_size : tuple_size<_Tuple> { // size of const volatile tuple }; // CLASS tuple_element (find element by index) template struct tuple_element { // struct to enforce bounds checking static_assert(_Always_false<_Tuple>::value, "tuple_element index out of bounds"); }; template struct tuple_element<_Idx, array<_Ty, _Size> > { // struct to determine type of element _Idx in array static_assert(_Idx < _Size, "array index out of bounds"); typedef _Ty type; }; template struct tuple_element<0, pair<_Ty1, _Ty2> > { // struct to determine type of element 0 in pair typedef _Ty1 type; }; template struct tuple_element<1, pair<_Ty1, _Ty2> > { // struct to determine type of element 1 in pair typedef _Ty2 type; }; template struct tuple_element<0, tuple<_This, _Rest...> > { // select first element typedef _This type; typedef tuple<_This, _Rest...> _Ttype; }; template struct tuple_element<_Index, tuple<_This, _Rest...> > : public tuple_element<_Index - 1, tuple<_Rest...> > { // recursive tuple_element definition }; template struct tuple_element<_Index, const _Tuple> : public tuple_element<_Index, _Tuple> { // tuple_element for const typedef tuple_element<_Index, _Tuple> _Mybase; typedef typename add_const::type type; }; template struct tuple_element<_Index, volatile _Tuple> : public tuple_element<_Index, _Tuple> { // tuple_element for volatile typedef tuple_element<_Index, _Tuple> _Mybase; typedef typename add_volatile::type type; }; template struct tuple_element<_Index, const volatile _Tuple> : public tuple_element<_Index, _Tuple> { // tuple_element for const volatile typedef tuple_element<_Index, _Tuple> _Mybase; typedef typename add_cv::type type; }; template using tuple_element_t = typename tuple_element<_Index, _Tuple>::type; // TUPLE INTERFACE TO pair template inline _CONST_FUN _Ret _Pair_get(_Pair& _Pr, integral_constant) _NOEXCEPT { // get reference to element 0 in pair _Pr return (_Pr.first); } template inline _CONST_FUN _Ret _Pair_get(_Pair& _Pr, integral_constant) _NOEXCEPT { // get reference to element 1 in pair _Pr return (_Pr.second); } template inline _CONST_FUN typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT { // get reference to element at _Idx in pair _Pr typedef typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type& _Rtype; return (_Pair_get<_Rtype>(_Pr, integral_constant())); } template inline _CONST_FUN _Ty1& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT { // get reference to element _Ty1 in pair _Pr return (_STD get<0>(_Pr)); } template inline _CONST_FUN _Ty2& get(pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT { // get reference to element _Ty2 in pair _Pr return (_STD get<1>(_Pr)); } template inline _CONST_FUN const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT { // get const reference to element at _Idx in pair _Pr typedef const typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type& _Ctype; return (_Pair_get<_Ctype>(_Pr, integral_constant())); } template inline _CONST_FUN const _Ty1& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT { // get const reference to element _Ty1 in pair _Pr return (_STD get<0>(_Pr)); } template inline _CONST_FUN const _Ty2& get(const pair<_Ty1, _Ty2>& _Pr) _NOEXCEPT { // get const reference to element _Ty2 in pair _Pr return (_STD get<1>(_Pr)); } template inline _CONST_FUN typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT { // get rvalue reference to element at _Idx in pair _Pr typedef typename tuple_element<_Idx, pair<_Ty1, _Ty2> >::type&& _RRtype; return (_STD forward<_RRtype>(_STD get<_Idx>(_Pr))); } template inline _CONST_FUN _Ty1&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT { // get rvalue reference to element _Ty1 in pair _Pr return (_STD get<0>(_STD move(_Pr))); } template inline _CONST_FUN _Ty2&& get(pair<_Ty1, _Ty2>&& _Pr) _NOEXCEPT { // get rvalue reference to element _Ty2 in pair _Pr return (_STD get<1>(_STD move(_Pr))); } // TEMPLATE FUNCTION exchange template inline _Ty exchange(_Ty& _Val, _Other&& _New_val) { // assign _New_val to _Val, return previous _Val _Ty _Old_val = _STD move(_Val); _Val = _STD forward<_Other>(_New_val); return (_Old_val); } _STD_END _STD_BEGIN namespace tr1 { // TR1 additions using _STD get; using _STD tuple_element; using _STD tuple_size; } // namespace tr1 _STD_END #pragma pop_macro("new") #pragma warning(pop) #pragma pack(pop) #endif /* RC_INVOKED */ #endif /* _UTILITY_ */ /* * Copyright (c) by P.J. Plauger. All rights reserved. * Consult your license regarding permissions and restrictions. V6.50:0009 */