blob: 7ab30a91694687e1dd9643db75ecaf74bc5fb130 [file] [log] [blame]
/***************************************************************************
*
* podarray.h - definition of a fast array-like class template
*
* This is an internal header file used to implement the C++ Standard
* Library. It should never be #included directly by a program.
*
* $Id$
*
***************************************************************************
*
* 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 2001-2006 Rogue Wave Software.
*
**************************************************************************/
#ifndef _RWSTD_PODARRAY_H_INCLUDED
#define _RWSTD_PODARRAY_H_INCLUDED
#if __GNUG__ >= 3
# pragma GCC system_header
#endif // gcc >= 3
#include <string.h>
#include <rw/_traits.h>
#include <rw/_defs.h>
_RWSTD_NAMESPACE (__rw) {
// __rw_aligned_buffer specializations should be objects with static
// storage duration that must "survive" all other static objects and
// that do not need to be destroyed; this is a POD
template <class _TypeT>
struct __rw_aligned_buffer
{
union {
#ifndef _RWSTD_NO_LONG_DOUBLE
long double _C_pad; // guarantee suitable alignment
#else
double _C_pad;
#endif // _RWSTD_NO_LONG_DOUBLE
void *_C_void_pad;
void (*_C_pfn_pad)();
char _C_data [sizeof (_TypeT)]; // data to back _TypeT up with
} _C_buf;
void* _C_store () {
return _C_buf._C_data;
}
_TypeT* _C_data () {
return _RWSTD_REINTERPRET_CAST (_TypeT*, _C_buf._C_data);
}
};
// typedef prevents an MSVC 6.0 ICE
typedef _RWSTD_SIZE_T _SizeT;
_EXPORT template <class _TypeT, _SizeT _Size>
class __rw_pod_array
{
_SizeT _C_len;
_TypeT *_C_pbuf;
_TypeT _C_buffer [_Size];
public:
__rw_pod_array (): _C_len (0), _C_pbuf (_C_buffer) {
*_C_pbuf = _TypeT ();
}
explicit __rw_pod_array (const _TypeT *__a)
: _C_len (_C_length (__a))
// , _C_pbuf (_C_len < _Size ? _C_buffer : new _TypeT [_C_len + 1])
{
// initialze _C_pbuf here in order to prevent HP aCC 3.70
// ICE: see http://issues.apache.org/jira/browse/STDCXX-276
if (_C_len < _Size)
_C_pbuf = _C_buffer;
else
_C_pbuf = new _TypeT [_C_len + 1];
memcpy (_C_pbuf, __a, (_C_len + 1) * sizeof *__a);
}
__rw_pod_array (const _TypeT *__a, _SizeT __len)
: _C_len (__len) {
// initialze _C_pbuf here in order to prevent HP aCC 3.70
// ICE: see http://issues.apache.org/jira/browse/STDCXX-276
if (__len < _Size)
_C_pbuf = _C_buffer;
else
_C_pbuf = new _TypeT [__len + 1];
memcpy (_C_pbuf, __a, __len * sizeof *__a);
_C_pbuf [_C_len] = _TypeT ();
}
__rw_pod_array (const __rw_pod_array &__rhs)
: _C_len (__rhs._C_len) {
// initialze _C_pbuf here in order to prevent HP aCC 3.70
// ICE: see http://issues.apache.org/jira/browse/STDCXX-276
if (_C_len < _Size)
_C_pbuf = _C_buffer;
else
_C_pbuf = new _TypeT [_C_len + 1];
memcpy (_C_pbuf, __rhs._C_pbuf,
(_C_len + !!__rhs._C_pbuf) * sizeof *_C_pbuf);
}
~__rw_pod_array () {
if (_C_pbuf != _C_buffer)
delete[] _C_pbuf;
}
_TypeT* data () {
return _C_pbuf;
}
const _TypeT* data () const {
return _C_pbuf;
}
_TypeT* acquire (_TypeT *__a, _SizeT __len) {
_TypeT *__pbuf = _C_pbuf;
_C_pbuf = __a;
_C_len = __len;
return __pbuf;
}
_TypeT* acquire (_TypeT *__a) {
return acquire (__a, _C_length (__a));
}
_TypeT* release () {
_TypeT* const __pbuf = _C_pbuf;
_C_pbuf = _C_buffer;
return __pbuf;
}
static _SizeT max_size () {
return _Size;
}
_SizeT size () const {
return _C_len;
}
__rw_pod_array& append (const _TypeT*, _SizeT);
__rw_pod_array& append (const _TypeT *__a) {
_RWSTD_ASSERT (__a);
return append (__a, _C_length (__a));
}
__rw_pod_array& operator+= (const _TypeT *__a) {
_RWSTD_ASSERT (__a);
return append (__a);
}
__rw_pod_array& assign (const _TypeT *__a, _SizeT __len) {
return (_C_len = 0), append (__a, __len);
}
__rw_pod_array& assign (const _TypeT *__a) {
_RWSTD_ASSERT (__a);
return assign (__a, _C_length (__a));
}
__rw_pod_array& operator= (const _TypeT *__a) {
_RWSTD_ASSERT (__a);
return assign (__a);
}
__rw_pod_array& operator= (const __rw_pod_array &__rhs) {
return assign (__rhs._C_pbuf, __rhs._C_len);
}
private:
static _RWSTD_SIZE_T _C_length (const _TypeT *__a) {
#ifndef _RWSTD_NO_EXT_CHAR_TRAITS_PRIMARY
return _STD::char_traits<_TypeT>::length (__a);
#else // #ifdef _RWSTD_NO_EXT_CHAR_TRAITS_PRIMARY
_RWSTD_SIZE_T __len = 0;
for (; _TypeT () != *__a; ++__a, ++__len) ;
return __len;
#endif // _RWSTD_NO_EXT_CHAR_TRAITS_PRIMARY
}
};
typedef __rw_pod_array<char, 256> __rw_chararray;
} // namespace __rw
#if _RWSTD_DEFINE_TEMPLATE_FIRST (_POD_ARRAY)
# include "podarray.cc"
#endif // _RWSTD_DEFINE_TEMPLATE_FIRST (_POD_ARRAY)
_RWSTD_NAMESPACE (__rw) {
#if _RWSTD_INSTANTIATE (_POD_ARRAY, _CHAR)
// used throughout locale
_RWSTD_INSTANTIATE_2 (class __rw_pod_array<char, 256>);
#endif // _RWSTD_INSTANTIATE (_POD_ARRAY, _CHAR)
#if _RWSTD_INSTANTIATE (_POD_ARRAY, _UINT)
// used in collate.cpp
_RWSTD_INSTANTIATE_2 (class __rw_pod_array<const unsigned int*, 1024>);
#endif // _RWSTD_INSTANTIATE (_POD_ARRAY, _UINT)
} // namespace __rw
#if _RWSTD_DEFINE_TEMPLATE_LAST (_POD_ARRAY)
# include "podarray.cc"
#endif // _RWSTD_DEFINE_TEMPLATE_LAST (_POD_ARRAY)
#endif // _RWSTD_PODARRAY_H_INCLUDED