?? memory
字號:
// memory stl/clr header
#ifndef _CLI_MEMORY_
#define _CLI_MEMORY_
#include <cliext/iterator>
#include <cliext/utility> // for pair
#ifdef _M_CEE_SAFE
#define _PAIR_TYPE(iter_t) cliext::pair<iter_t, iter_t> // iterator pair
#define _PAIR_TYPE2(iter1_t, iter2_t) \
cliext::pair<iter1_t, iter2_t> // iterator pair
#define _STLCLRDB_ERROR(mesg)
#define _STLCLRDB_LT(left, right) ((left) < (right))
#define _STLCLRDB_LT_PRED(pred, left, right) ((pred)(left, right))
#define _STLCLRDB_POINTER(first)
#define _STLCLRDB_ORDER(first, last)
#define _STLCLRDB_ORDER_PRED(first, last, pred)
#define _STLCLRDB_RANGE(first, last)
#else /* _M_CEE_SAFE */
#include <climits> // for CHAR_MAX, UCHAR_MAX
#include <cstddef> // for ptrdiff_t, size_t
#include <cstring> // form mem* functions
#include <new> // for placement new
#include <utility> // for std::pair
#include <xutility> // for CHAR_MAX, UCHAR_MAX, iterator debugging
#define _PAIR_TYPE(iter_t) typename cliext::_Pick_pair< \
__is_value_class(iter_t) || __is_ref_class(iter_t), \
iter_t, iter_t>::value_type
#define _PAIR_TYPE2(iter1_t, iter2_t) typename cliext::_Pick_pair< \
__is_value_class(iter1_t) || __is_ref_class(iter1_t), \
iter1_t, iter2_t>::value_type // both managed or both unmanaged
namespace cliext {
template<bool _Is_managed,
typename _Value1_t,
typename _Value2_t>
class _Pick_pair; // select managed or unmanaged type
template<typename _Value1_t,
typename _Value2_t>
class _Pick_pair<false, _Value1_t, _Value2_t>
{ // define unmanaged type
public:
typedef std::pair<_Value1_t, _Value2_t> value_type;
};
template<typename _Value1_t,
typename _Value2_t>
class _Pick_pair<true, _Value1_t, _Value2_t>
{ // define managed type
public:
typedef cliext::pair<_Value1_t, _Value2_t> value_type;
};
} // namespace cliext
#if _HAS_ITERATOR_DEBUGGING
#ifndef _STLCLRDB_REPORT
#define _STLCLRDB_REPORT(mesg, file, line) \
std::_Debug_message(mesg, file, line)
#endif /* _STLCLRDB_REPORT */
#define _STLCLRDB_ERROR(mesg) \
_STLCLRDB_REPORT(mesg, __FILEW__, __LINE__)
#define _STLCLRDB_LT(left, right) \
cliext::_Stlclrdb_lt(left, right, __FILEW__, __LINE__)
#define _STLCLRDB_LT_PRED(pred, left, right) \
cliext::_Stlclrdb_lt_pred(pred, left, right, __FILEW__, __LINE__)
#define _STLCLRDB_POINTER(first) \
cliext::_Stlclrdb_pointer(first, __FILEW__, __LINE__)
#define _STLCLRDB_POINTER2(first, filew, line) \
cliext::_Stlclrdb_pointer(first, filew, line)
#define _STLCLRDB_ORDER(first, last) \
cliext::_Stlclrdb_order(first, last, __FILEW__, __LINE__)
#define _STLCLRDB_ORDER_PRED(first, last, pred) \
cliext::_Stlclrdb_order(first, last, pred, __FILEW__, __LINE__)
#define _STLCLRDB_RANGE(first, last) \
cliext::_Stlclrdb_range(first, last, __FILEW__, __LINE__)
#define _STLCLRDB_RANGE2(first, last, filew, line) \
cliext::_Stlclrdb_range(first, last, filew, line)
namespace cliext {
template<class _Ty1, class _Ty2> inline
bool _Stlclrdb_lt(_Ty1% _Left, _Ty2% _Right,
const wchar_t *_File, unsigned int _Line)
{ // test if _Left < _Right and operator< is strict weak ordering
if (!(_Left < _Right))
return (false);
else if (_Right < _Left)
_STLCLRDB_REPORT(L"invalid operator<", _File, _Line);
return (true);
}
template<class _Pr, class _Ty1, class _Ty2> inline
bool _Stlclrdb_lt_pred(_Pr _Pred, _Ty1% _Left, _Ty2% _Right,
const wchar_t *_File, unsigned int _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
if (!_Pred(_Left, _Right))
return (false);
else if (_Pred(_Right, _Left))
_STLCLRDB_REPORT(L"invalid operator<", _File, _Line);
return (true);
}
// TEMPLATE FUNCTION _Stlclrdb_pointer
template<class _InIt> inline
void _Stlclrdb_pointer(_InIt%, const wchar_t *, unsigned int)
{ // test pointer for non-singularity, arbitrary type
}
template<class _Ty> inline
void _Stlclrdb_pointer(const _Ty *_First, const wchar_t *_File,
unsigned int _Line)
{ // test iterator for non-singularity, const pointers
if (_First == 0)
_STLCLRDB_REPORT(L"invalid null pointer", _File, _Line);
}
template<class _Ty> inline
void _Stlclrdb_pointer(_Ty *_First, const wchar_t *_File,
unsigned int _Line)
{ // test iterator for non-singularity, pointers
if (_First == 0)
_STLCLRDB_REPORT(L"invalid null pointer", _File, _Line);
}
// TEMPLATE FUNCTION _Stlclrdb_order
template<class _InIt> inline
void _Stlclrdb_order2(_InIt _First, _InIt _Last,
const wchar_t *_File, unsigned int _Line, input_iterator_tag)
{ // test if range is ordered by operator<, input iterators
}
template<class _FwdIt> inline
void _Stlclrdb_order2(_FwdIt _First, _FwdIt _Last,
const wchar_t *_File, unsigned int _Line, forward_iterator_tag)
{ // test if range is ordered by operator<, forward iterators
for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First)
if (_STLCLRDB_LT(*_Next, *_First))
_STLCLRDB_REPORT(L"sequence not ordered", _File, _Line);
}
template<class _InIt> inline
void _Stlclrdb_order(_InIt _First, _InIt _Last,
const wchar_t *_File, unsigned int _Line)
{ // test is range is ordered by operator<
_STLCLRDB_RANGE2(_First, _Last, _File, _Line);
_Stlclrdb_order2(_First, _Last, _File, _Line, _Iter_category(_First));
}
// TEMPLATE FUNCTION _Stlclrdb_order WITH PRED
template<class _InIt,
class _Pr> inline
void _Stlclrdb_order2(_InIt _First, _InIt _Last, _Pr _Pred,
const wchar_t *_File, unsigned int _Line, input_iterator_tag)
{ // test if range is ordered by predicate, input iterators
}
template<class _FwdIt,
class _Pr> inline
void _Stlclrdb_order2(_FwdIt _First, _FwdIt _Last, _Pr _Pred,
const wchar_t *_File, unsigned int _Line, forward_iterator_tag)
{ // test if range is ordered by predicate, forward iterators
for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First)
if (_STLCLRDB_LT_PRED(_Pred, *_Next, *_First))
_STLCLRDB_REPORT(L"sequence not ordered", _File, _Line);
}
template<class _InIt,
class _Pr> inline
void _Stlclrdb_order(_InIt _First, _InIt _Last, _Pr _Pred,
const wchar_t *_File, unsigned int _Line)
{ // test if range is ordered by predicate
_STLCLRDB_RANGE2(_First, _Last, _File, _Line);
_STLCLRDB_POINTER2(_Pred, _File, _Line);
_Stlclrdb_order2(_First, _Last, _Pred, _File, _Line,
_Iter_category(_First));
}
// TEMPLATE FUNCTION _Stlclrdb_range
template<class _InIt> inline
void _Stlclrdb_range2(_InIt, _InIt,
const wchar_t *, unsigned int, input_iterator_tag)
{ // test iterator pair for valid range, arbitrary iterators
}
template<class _RanIt> inline
void _Stlclrdb_range2(_RanIt _First, _RanIt _Last,
const wchar_t *_Filew, unsigned int _Line,
random_access_iterator_tag)
{ // test iterator pair for valid range, random-access iterators
if (_First != _Last)
{ // check for non-null pointers, valid range
_STLCLRDB_POINTER2(_First, _Filew, _Line);
_STLCLRDB_POINTER2(_Last, _Filew, _Line);
if (_Last < _First)
_STLCLRDB_REPORT(L"invalid iterator range", _Filew, _Line);
}
}
template<class _InIt> inline
void _Stlclrdb_range(_InIt _First, _InIt _Last,
const wchar_t *_Filew, unsigned int _Line)
{ // test iterator pair for valid range
_Stlclrdb_range2(_First, _Last, _Filew, _Line, _Iter_category(_First));
}
} // namespace cliext
#else /* _HAS_ITERATOR_DEBUGGING */
#define _STLCLRDB_LT(left, right) ((left) < (right))
#define _STLCLRDB_LT_PRED(pred, left, right) ((pred)(left, right))
#define _STLCLRDB_POINTER(first)
#define _STLCLRDB_ORDER(first, last)
#define _STLCLRDB_ORDER_PRED(first, last, pred)
#define _STLCLRDB_RANGE(first, last)
#endif /* _HAS_ITERATOR_DEBUGGING */
#endif /* _M_CEE_SAFE */
namespace cliext {
//
// UN/MANAGED TEMP BUFFER SELECTOR
//
template<typename _Value_t>
value class _Temp_gc_iterator;
template<typename _Value_t>
class _Temp_iterator;
#ifdef _M_CEE_SAFE
#define _TEMP_ITER(iter_t, value_t) _Temp_gc_iterator<value_t>
#else /* _M_CEE_SAFE */
#define _TEMP_ITER(iter_t, value_t) typename cliext::_Pick_tbuf< \
__is_value_class(iter_t) || __is_ref_class(iter_t), value_t>::value_type
template<bool _Is_managed,
typename _Value_t>
class _Pick_tbuf; // select managed or unmanaged type
template<typename _Value_t>
class _Pick_tbuf<false, _Value_t>
{ // define unmanaged type
public:
typedef cliext::_Temp_iterator<_Value_t> value_type;
};
template<typename _Value_t>
class _Pick_tbuf<true, _Value_t>
{ // define managed type
public:
typedef cliext::_Temp_gc_iterator<_Value_t> value_type;
};
// TEMPLATE FUNCTION get_temporary_buffer
template<class _Ty> inline
pair<_Ty *, std::ptrdiff_t>
get_temporary_buffer(std::ptrdiff_t _Count)
{ // get raw temporary buffer of up to _Count elements
_Ty *_Pbuf;
if (_Count < 0)
_Count = 0;
for (_Pbuf = 0; 0 < _Count; _Count /= 2)
try
{ // try to allocate storage
_Pbuf = (_Ty *)::operator new(_Count * sizeof (_Ty));
break;
}
catch (...)
{ // loop if new fails
}
return (pair<_Ty *, std::ptrdiff_t>(_Pbuf, _Count));
}
// TEMPLATE FUNCTION return_temporary_buffer
template<class _Ty> inline
void return_temporary_buffer(_Ty *_Pbuf)
{ // delete raw temporary buffer
::operator delete(_Pbuf);
}
// TEMPLATE CLASS _Temp_iterator
template<class _Ty>
class _Temp_iterator
{ // wrap stores to unmanaged temporary buffer as output iterator
public:
typedef _Temp_iterator<_Ty> _Mytype_t;
typedef _Ty *_Pty;
typedef output_iterator_tag iterator_category;
_Temp_iterator(std::ptrdiff_t _Count = 0)
{ // construct from desired temporary buffer size
_Buf._Begin = 0;
_Buf._Current = 0;
_Buf._Hiwater = 0;
_Buf._Size = _Count; // memorize size for lazy allocation
_Pbuf = &_Buf;
}
_Temp_iterator(const _Temp_iterator& _Right)
{ // construct from _Right (share active buffer)
_Buf._Begin = 0; // clear stored buffer, for safe destruction
_Buf._Current = 0;
_Buf._Hiwater = 0;
_Buf._Size = 0;
*this = _Right;
}
~_Temp_iterator()
{ // destroy the object
if (_Buf._Begin != 0)
{ // destroy any constructed elements in buffer
for (_Pty _Next = _Buf._Begin;
_Next != _Buf._Hiwater; ++_Next)
_Next->~_Ty();
return_temporary_buffer(_Buf._Begin);
}
}
_Temp_iterator& operator=(const _Temp_iterator& _Right)
{ // assign _Right (share active buffer)
_Pbuf = _Right._Pbuf;
return (*this);
}
_Temp_iterator& operator=(_Ty& _Val)
{ // assign or construct value into active buffer, and increment
if (_Pbuf->_Current < _Pbuf->_Hiwater)
*_Pbuf->_Current++ = _Val; // below high water mark, assign
else
{ // above high water mark, construct
_Pty _Ptr = &*_Pbuf->_Current;
::new (_Ptr) _Ty(_Val);
_Pbuf->_Hiwater = ++_Pbuf->_Current;
}
return (*this);
}
_Temp_iterator& operator*()
{ // pretend to return designated value
return (*this);
}
_Temp_iterator& operator++()
{ // pretend to preincrement
return (*this);
}
_Temp_iterator& operator++(int)
{ // pretend to postincrement
return (*this);
}
_Temp_iterator& _Init()
{ // set pointer at beginning of buffer
_Pbuf->_Current = _Pbuf->_Begin;
return (*this);
}
_Pty _First() const
{ // return pointer to beginning of buffer
return (_Pbuf->_Begin);
}
_Pty _Last() const
{ // return pointer past end of buffer contents
return (_Pbuf->_Current);
}
std::ptrdiff_t _Maxlen()
{ // return size of buffer
if (_Pbuf->_Begin == 0 && 0 < _Pbuf->_Size)
{ // allocate buffer on first size query
pair<_Pty, std::ptrdiff_t> _Pair =
get_temporary_buffer<_Ty>(_Pbuf->_Size);
_Pbuf->_Begin = _Pair.first;
_Pbuf->_Current = _Pair.first;
_Pbuf->_Hiwater = _Pair.first;
_Pbuf->_Size = _Pair.second;
}
return (_Pbuf->_Size);
}
//_STLCLR_FIELD_ACCESS:
struct _Bufpar
{ // control information for a temporary buffer
_Pty _Begin; // pointer to beginning of buffer
_Pty _Current; // pointer to next available element
_Pty _Hiwater; // pointer to first unconstructed element
std::ptrdiff_t _Size; // length of buffer
};
_Bufpar _Buf; // buffer control stored in iterator
_Bufpar *_Pbuf; // pointer to active buffer control
};
#endif /* _M_CEE_SAFE */
// TEMPLATE CLASS _Temp_gc_iterator
template<class _Ty>
value class _Temp_gc_iterator
{ // wrap stores to managed temporary buffer as output iterator
public:
typedef _Temp_gc_iterator<_Ty> _Mytype_t;
typedef cli::array<_Ty> _Myarray_t;
typedef ArrayContainer<_Ty> _Mycont_t;
typedef typename _Mycont_t::iterator iterator;
_Temp_gc_iterator(int _Count)
: _Mysize(_Count), _Mycont(nullptr), _Next(nullptr)
{ // construct from desired temporary buffer size
}
static _Ty% operator*(_Temp_gc_iterator% _Left)
{ // return designated value
return (_Left._Next->get_ref());
}
_Temp_gc_iterator operator++()
{ // preincrement
_Next->next();
return (*this);
}
iterator operator++(int)
{ // postincrement
iterator _Temp = *_Next;
_Next->next();
return (_Temp);
}
_Temp_gc_iterator _Init()
{ // set pointer at beginning of buffer
*_Next = _Mycont->begin();
return (*this);
}
iterator _First()
{ // return pointer to beginning of buffer
return (_Mycont->begin());
}
iterator _Last()
{ // return pointer past end of buffer contents
return (*_Next);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -