Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / CDR_Base.inl
blobc31c3b785553cff42129f41532fb23911aae6bf4
1 // -*- C++ -*-
2 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
3 // Take advantage of MSVC++ byte swapping compiler intrinsics (found
4 // in <stdlib.h>).
5 # pragma intrinsic (_byteswap_ushort, _byteswap_ulong, _byteswap_uint64)
6 #endif  /* ACE_HAS_INTRINSIC_BYTESWAP */
8 #if defined (ACE_HAS_BSWAP_16) || defined (ACE_HAS_BSWAP_32) || defined (ACE_HAS_BSWAP_64)
9 # include "ace/os_include/os_byteswap.h"
10 #endif
12 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 // The ACE_CDR::swap_X and ACE_CDR::swap_X_array routines are broken
16 // in 5 cases for optimization:
18 // * MSVC++ 7.1 or better
19 //   => Compiler intrinsics
21 // * AMD64 CPU + gnu g++
22 //   => gcc amd64 inline assembly.
24 // * x86 Pentium CPU + gnu g++
25 //   (ACE_HAS_PENTIUM && __GNUG__)
26 //   => gcc x86 inline assembly.
28 // * x86 Pentium CPU and (_MSC_VER) or BORLAND C++)
29 //   (ACE_HAS_PENTIUM && ( _MSC_VER || __BORLANDC__ )
30 //   => MSC x86 inline assembly.
32 // * 64 bit architecture
33 //   (ACE_SIZEOF_LONG == 8)
34 //   => shift/masks using 64bit words.
36 // * default
37 //   (none of the above)
38 //   => shift/masks using 32bit words.
40 // Some things you could find useful to know if you intend to mess
41 // with this optimizations for swaps:
43 //      * MSVC++ don't assume register values are conserved between
44 //        statements. So you can clobber any register you want,
45 //        whenever you want (well not *anyone* really, see manual).
46 //        The MSVC++ optimizer will try to pick different registers
47 //        for the C++ statements sorrounding your asm block, and if
48 //        it's not possible will use the stack.
50 //      * If you clobber registers with asm statements in gcc, you
51 //        better do it in an asm-only function, or save/restore them
52 //        before/after in the stack. If not, sorrounding C statements
53 //        could end using the same registers and big-badda-bum (been
54 //        there, done that...). The big-badda-bum could happen *even
55 //        if you specify the clobbered register in your asm's*.
56 //        Even better, use gcc asm syntax for detecting the register
57 //        asigned to a certain variable so you don't have to clobber any
58 //        register directly.
61 ACE_INLINE void
62 ACE_CDR::swap_2 (const char *orig, char* target)
64 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
65   // Take advantage of MSVC++ compiler intrinsic byte swapping
66   // function.
67   *reinterpret_cast<unsigned short *> (target) =
68     _byteswap_ushort (*reinterpret_cast<unsigned short const *> (orig));
69 #elif defined (ACE_HAS_BUILTIN_BSWAP16)
70   *reinterpret_cast<uint16_t *> (target) =
71     __builtin_bswap16 (*reinterpret_cast<uint16_t const *> (orig));
72 #elif defined (ACE_HAS_BSWAP16)
73   *reinterpret_cast<uint16_t *> (target) =
74     bswap16 (*reinterpret_cast<uint16_t const *> (orig));
75 #elif defined (ACE_HAS_BSWAP_16)
76   *reinterpret_cast<uint16_t *> (target) =
77     bswap_16 (*reinterpret_cast<uint16_t const *> (orig));
78 #elif defined(ACE_HAS_INTEL_ASSEMBLY)
79   unsigned short a =
80     *reinterpret_cast<const unsigned short*> (orig);
81   asm( "rolw $8, %0" : "=r" (a) : "0" (a) );
82   *reinterpret_cast<unsigned short*> (target) = a;
83 #elif defined (ACE_HAS_PENTIUM) \
84        && (defined(_MSC_VER) || defined(__BORLANDC__)) \
85        && !defined(ACE_LACKS_INLINE_ASSEMBLY)
86   __asm mov ebx, orig;
87   __asm mov ecx, target;
88   __asm mov ax, [ebx];
89   __asm rol ax, 8;
90   __asm mov [ecx], ax;
91 #else
92   ACE_UINT16 usrc = * reinterpret_cast<const ACE_UINT16*> (orig);
93   ACE_UINT16* udst = reinterpret_cast<ACE_UINT16*> (target);
94   *udst = (usrc << 8) | (usrc >> 8);
95 #endif /* ACE_HAS_PENTIUM */
98 ACE_INLINE void
99 ACE_CDR::swap_4 (const char* orig, char* target)
101 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
102   // Take advantage of MSVC++ compiler intrinsic byte swapping
103   // function.
104   *reinterpret_cast<unsigned long *> (target) =
105     _byteswap_ulong (*reinterpret_cast<unsigned long const *> (orig));
106 #elif defined (ACE_HAS_BUILTIN_BSWAP32)
107   *reinterpret_cast<uint32_t *> (target) =
108     __builtin_bswap32 (*reinterpret_cast<uint32_t const *> (orig));
109 #elif defined (ACE_HAS_BSWAP32)
110   *reinterpret_cast<uint32_t *> (target) =
111     bswap32 (*reinterpret_cast<uint32_t const *> (orig));
112 #elif defined (ACE_HAS_BSWAP_32)
113   *reinterpret_cast<uint32_t *> (target) =
114     bswap_32 (*reinterpret_cast<uint32_t const *> (orig));
115 #elif defined(ACE_HAS_INTEL_ASSEMBLY)
116   // We have ACE_HAS_PENTIUM, so we know the sizeof's.
117   unsigned int j =
118     *reinterpret_cast<const unsigned int*> (orig);
119   asm ("bswap %1" : "=r" (j) : "0" (j));
120   *reinterpret_cast<unsigned int*> (target) = j;
121 #elif defined(ACE_HAS_PENTIUM) \
122       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
123       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
124   __asm mov ebx, orig;
125   __asm mov ecx, target;
126   __asm mov eax, [ebx];
127   __asm bswap eax;
128   __asm mov [ecx], eax;
129 #else
130   ACE_UINT32 x = * reinterpret_cast<const ACE_UINT32*> (orig);
131   x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
132   * reinterpret_cast<ACE_UINT32*> (target) = x;
133 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
136 ACE_INLINE void
137 ACE_CDR::swap_8 (const char* orig, char* target)
139 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
140   // Take advantage of MSVC++ compiler intrinsic byte swapping
141   // function.
142   *reinterpret_cast<unsigned __int64 *> (target) =
143     _byteswap_uint64 (*reinterpret_cast<unsigned __int64 const *> (orig));
144 #elif defined (ACE_HAS_BUILTIN_BSWAP64)
145   *reinterpret_cast<uint64_t *> (target) =
146     __builtin_bswap64 (*reinterpret_cast<uint64_t const *> (orig));
147 #elif defined (ACE_HAS_BSWAP64)
148   *reinterpret_cast<uint64_t *> (target) =
149     bswap64 (*reinterpret_cast<uint64_t const *> (orig));
150 #elif defined (ACE_HAS_BSWAP_64)
151   *reinterpret_cast<uint64_t *> (target) =
152     bswap_64 (*reinterpret_cast<uint64_t const *> (orig));
153 #elif (defined (__amd64__) || defined (__x86_64__)) && defined(__GNUG__) \
154     && !defined(ACE_LACKS_INLINE_ASSEMBLY)
155   unsigned long x =
156     * reinterpret_cast<const unsigned long*> (orig);
157   asm ("bswapq %1" : "=r" (x) : "0" (x));
158   *reinterpret_cast<unsigned long*> (target) = x;
159 #elif defined(ACE_HAS_PENTIUM) && defined(__GNUG__) \
160     && !defined(ACE_LACKS_INLINE_ASSEMBLY)
161   unsigned int i =*reinterpret_cast<const unsigned int*> (orig);
162   unsigned int j = *reinterpret_cast<const unsigned int*> (orig + 4);
163   asm ("bswap %1" : "=r" (i) : "0" (i));
164   asm ("bswap %1" : "=r" (j) : "0" (j));
165   *reinterpret_cast<unsigned int*> (target + 4) = i;
166   *reinterpret_cast<unsigned int*> (target) = j;
167 #elif defined(ACE_HAS_PENTIUM) \
168       && (defined(_MSC_VER) || defined(__BORLANDC__)) \
169       && !defined(ACE_LACKS_INLINE_ASSEMBLY)
170   __asm mov ecx, orig;
171   __asm mov edx, target;
172   __asm mov eax, [ecx];
173   __asm mov ebx, 4[ecx];
174   __asm bswap eax;
175   __asm bswap ebx;
176   __asm mov 4[edx], eax;
177   __asm mov [edx], ebx;
178 #elif ACE_SIZEOF_LONG == 8
179   // 64 bit architecture.
180   unsigned long x = * reinterpret_cast<const unsigned long*> (orig);
181   unsigned long x84 = (x & 0x000000ff000000ffUL) << 24;
182   unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8;
183   unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8;
184   unsigned long x51 = (x & 0xff000000ff000000UL) >> 24;
185   x = (x84 | x73 | x62 | x51);
186   x = (x << 32) | (x >> 32);
187   *reinterpret_cast<unsigned long*> (target) = x;
188 #else
189   ACE_UINT32 x = * reinterpret_cast<const ACE_UINT32*> (orig);
190   ACE_UINT32 y = * reinterpret_cast<const ACE_UINT32*> (orig + 4);
191   x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
192   y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24);
193   * reinterpret_cast<ACE_UINT32*> (target) = y;
194   * reinterpret_cast<ACE_UINT32*> (target + 4) = x;
195 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
198 ACE_INLINE void
199 ACE_CDR::swap_16 (const char* orig, char* target)
201   swap_8 (orig + 8, target);
202   swap_8 (orig, target + 8);
205 ACE_INLINE size_t
206 ACE_CDR::first_size (size_t minsize)
208   if (minsize == 0)
209     return ACE_CDR::DEFAULT_BUFSIZE;
211   size_t newsize = ACE_CDR::DEFAULT_BUFSIZE;
212   while (newsize < minsize)
213     {
214       if (newsize < ACE_CDR::EXP_GROWTH_MAX)
215         {
216           // We grow exponentially at the beginning, this is fast and
217           // reduces the number of allocations.
219           // Quickly multiply by two using a bit shift.  This is
220           // guaranteed to work since the variable is an unsigned
221           // integer.
222           newsize <<= 1;
223         }
224       else
225         {
226           // but continuing with exponential growth can result in over
227           // allocations and easily yield an allocation failure.
228           // So we grow linearly when the buffer is too big.
229           newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
230         }
231     }
232   return newsize;
235 ACE_INLINE size_t
236 ACE_CDR::next_size (size_t minsize)
238   size_t newsize = ACE_CDR::first_size (minsize);
240   if (newsize == minsize)
241     {
242       // If necessary increment the size
243       if (newsize < ACE_CDR::EXP_GROWTH_MAX)
244         // Quickly multiply by two using a bit shift.  This is
245         // guaranteed to work since the variable is an unsigned
246         // integer.
247         newsize <<= 1;
248       else
249         newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
250     }
252   return newsize;
255 ACE_INLINE ACE_CDR::UShort
256 ACE_CDR::Fixed::fixed_digits () const
258   return this->digits_;
261 ACE_INLINE ACE_CDR::UShort
262 ACE_CDR::Fixed::fixed_scale () const
264   return this->scale_;
267 ACE_INLINE bool
268 ACE_CDR::Fixed::sign () const
270   return (this->value_[15] & 0xf) == NEGATIVE;
273 ACE_INLINE ACE_CDR::Octet
274 ACE_CDR::Fixed::digit (int n) const
276   const Octet x = this->value_[15 - (n + 1) / 2];
277   return (n % 2) ? x & 0xf : (x >> 4);
280 ACE_INLINE void
281 ACE_CDR::Fixed::digit (int n, int val)
283   const int idx = 15 - (n + 1) / 2;
284   this->value_[idx] = (n % 2) ? (this->value_[idx] & 0xf0) | val
285                               : ((val << 4) | (this->value_[idx] & 0xf));
288 ACE_INLINE
289 ACE_CDR::Fixed::Proxy::Proxy (bool high_nibble, Octet &element)
290   : high_nibble_ (high_nibble), element_ (element) {}
292 ACE_INLINE ACE_CDR::Fixed::Proxy &
293 ACE_CDR::Fixed::Proxy::operator= (Octet val)
295   this->element_ = this->high_nibble_
296     ? (val << 4) | (this->element_ & 0xf)
297     : ((this->element_ & 0xf0) | val);
298   return *this;
301 ACE_INLINE ACE_CDR::Fixed::Proxy &
302 ACE_CDR::Fixed::Proxy::operator+= (int rhs)
304   const Octet val = static_cast<Octet> (*this + rhs);
305   return *this = val;
308 ACE_INLINE ACE_CDR::Fixed::Proxy &
309 ACE_CDR::Fixed::Proxy::operator-= (int rhs)
311   const Octet val = static_cast<Octet> (*this - rhs);
312   return *this = val;
315 ACE_INLINE ACE_CDR::Fixed::Proxy &
316 ACE_CDR::Fixed::Proxy::operator++ ()
318   const Octet val = static_cast<Octet> (*this) + 1;
319   return *this = val;
322 ACE_INLINE ACE_CDR::Fixed::Proxy &
323 ACE_CDR::Fixed::Proxy::operator-- ()
325   const Octet val = static_cast<Octet>(*this) - 1;
326   return *this = val;
329 ACE_INLINE
330 ACE_CDR::Fixed::Proxy::operator ACE_CDR::Octet () const
332   return this->high_nibble_ ? this->element_ >> 4 : (this->element_ & 0xf);
335 ACE_INLINE
336 ACE_CDR::Fixed::IteratorBase::IteratorBase (int digit)
337   : digit_ (digit) {}
339 ACE_INLINE bool
340 ACE_CDR::Fixed::IteratorBase::high_nibble () const
342   return this->digit_ % 2 == 0;
345 ACE_INLINE ACE_CDR::Octet &
346 ACE_CDR::Fixed::IteratorBase::storage (Fixed *outer) const
348   return outer->value_[15 - (this->digit_ + 1) / 2];
351 ACE_INLINE ACE_CDR::Octet
352 ACE_CDR::Fixed::IteratorBase::storage (const Fixed *outer) const
354   return outer->value_[15 - (this->digit_ + 1) / 2];
357 ACE_INLINE bool
358 ACE_CDR::Fixed::IteratorBase::compare (const IteratorBase &rhs) const
360   return this->digit_ == rhs.digit_;
363 ACE_INLINE
364 ACE_CDR::Fixed::Iterator::Iterator (Fixed *outer, int digit)
365   : IteratorBase (digit), outer_ (outer) {}
367 ACE_INLINE ACE_CDR::Fixed::Proxy
368 ACE_CDR::Fixed::Iterator::operator* ()
370   return Proxy (this->high_nibble (), this->storage (this->outer_));
373 ACE_INLINE ACE_CDR::Fixed::Iterator &
374 ACE_CDR::Fixed::Iterator::operator+= (std::ptrdiff_t n)
376   this->digit_ += static_cast<int> (n);
377   return *this;
380 ACE_INLINE ACE_CDR::Fixed::Iterator &
381 ACE_CDR::Fixed::Iterator::operator++ ()
383   ++this->digit_;
384   return *this;
387 ACE_INLINE ACE_CDR::Fixed::Iterator
388 ACE_CDR::Fixed::Iterator::operator++ (int)
390   const Iterator cpy (*this);
391   ++this->digit_;
392   return cpy;
395 ACE_INLINE ACE_CDR::Fixed::Iterator &
396 ACE_CDR::Fixed::Iterator::operator-- ()
398   --this->digit_;
399   return *this;
402 ACE_INLINE ACE_CDR::Fixed::Iterator
403 ACE_CDR::Fixed::Iterator::operator-- (int)
405   const Iterator cpy (*this);
406   --this->digit_;
407   return cpy;
410 ACE_INLINE bool
411 ACE_CDR::Fixed::Iterator::operator== (const Iterator &rhs) const
413   return this->compare (rhs);
416 ACE_INLINE bool
417 ACE_CDR::Fixed::Iterator::operator!= (const Iterator &rhs) const
419   return !(*this == rhs);
422 ACE_INLINE
423 ACE_CDR::Fixed::ConstIterator::ConstIterator (const Fixed *outer, int digit)
424   : IteratorBase (digit), outer_ (outer) {}
426 ACE_INLINE ACE_CDR::Octet
427 ACE_CDR::Fixed::ConstIterator::operator* ()
429   const Octet storage = this->storage (this->outer_);
430   return this->high_nibble () ? storage >> 4 : (storage & 0xf);
433 ACE_INLINE ACE_CDR::Fixed::ConstIterator &
434 ACE_CDR::Fixed::ConstIterator::operator+= (std::ptrdiff_t n)
436   this->digit_ += static_cast<int> (n);
437   return *this;
440 ACE_INLINE ACE_CDR::Fixed::ConstIterator &
441 ACE_CDR::Fixed::ConstIterator::operator++ ()
443   ++this->digit_;
444   return *this;
447 ACE_INLINE ACE_CDR::Fixed::ConstIterator
448 ACE_CDR::Fixed::ConstIterator::operator++ (int)
450   const ConstIterator cpy (*this);
451   ++this->digit_;
452   return cpy;
455 ACE_INLINE ACE_CDR::Fixed::ConstIterator &
456 ACE_CDR::Fixed::ConstIterator::operator-- ()
458   --this->digit_;
459   return *this;
462 ACE_INLINE ACE_CDR::Fixed::ConstIterator
463 ACE_CDR::Fixed::ConstIterator::operator-- (int)
465   const ConstIterator cpy (*this);
466   --this->digit_;
467   return cpy;
470 ACE_INLINE bool
471 ACE_CDR::Fixed::ConstIterator::operator== (const ConstIterator &rhs) const
473   return this->compare (rhs);
476 ACE_INLINE bool
477 ACE_CDR::Fixed::ConstIterator::operator!= (const ConstIterator &rhs) const
479   return !(*this == rhs);
482 ACE_INLINE ACE_CDR::Fixed::Iterator
483 ACE_CDR::Fixed::begin ()
485   return Iterator (this);
488 ACE_INLINE ACE_CDR::Fixed::ConstIterator
489 ACE_CDR::Fixed::begin () const
491   return ConstIterator (this);
494 ACE_INLINE ACE_CDR::Fixed::ConstIterator
495 ACE_CDR::Fixed::cbegin () const
497   return ConstIterator (this);
500 ACE_INLINE ACE_CDR::Fixed::Iterator
501 ACE_CDR::Fixed::end ()
503   return Iterator (this, this->digits_);
506 ACE_INLINE ACE_CDR::Fixed::ConstIterator
507 ACE_CDR::Fixed::end () const
509   return ConstIterator (this, this->digits_);
512 ACE_INLINE ACE_CDR::Fixed::ConstIterator
513 ACE_CDR::Fixed::cend () const
515   return ConstIterator (this, this->digits_);
518 ACE_INLINE ACE_CDR::Fixed
519 ACE_CDR::Fixed::operator++ (int)
521   const Fixed cpy (*this);
522   ++*this;
523   return cpy;
526 ACE_INLINE ACE_CDR::Fixed
527 ACE_CDR::Fixed::operator-- (int)
529   const Fixed cpy (*this);
530   --*this;
531   return cpy;
534 ACE_INLINE ACE_CDR::Fixed
535 ACE_CDR::Fixed::operator+ () const
537   return *this;
540 ACE_INLINE ACE_CDR::Fixed
541 ACE_CDR::Fixed::operator- () const
543   Fixed f = *this;
544   f.value_[15] = (f.value_[15] & 0xf0) | (f.sign () ? POSITIVE : NEGATIVE);
545   return f;
548 ACE_INLINE void
549 ACE_CDR::Fixed::ltrim ()
551   for (int i = this->digits_ - 1; i >= this->scale_ && i > 0; --i)
552     if (this->digit (i) == 0)
553       --this->digits_;
554     else
555       break;
558 ACE_INLINE ACE_CDR::Fixed
559 operator+ (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
561   ACE_CDR::Fixed f = lhs;
562   f += rhs;
563   return f;
566 ACE_INLINE ACE_CDR::Fixed
567 operator- (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
569   ACE_CDR::Fixed f = lhs;
570   f -= rhs;
571   return f;
574 ACE_INLINE ACE_CDR::Fixed
575 operator* (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
577   ACE_CDR::Fixed f = lhs;
578   f *= rhs;
579   return f;
582 ACE_INLINE ACE_CDR::Fixed
583 operator/ (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
585   ACE_CDR::Fixed f = lhs;
586   f /= rhs;
587   return f;
590 ACE_INLINE bool
591 operator< (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
593   return lhs.less (rhs);
596 ACE_INLINE bool
597 operator> (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
599   return rhs < lhs;
602 ACE_INLINE bool
603 operator>= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
605   return !(lhs < rhs);
608 ACE_INLINE bool
609 operator<= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
611   return !(rhs < lhs);
614 ACE_INLINE bool
615 operator== (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
617   return lhs.equal (rhs);
620 ACE_INLINE bool
621 operator!= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
623   return !(lhs == rhs);
627 ACE_END_VERSIONED_NAMESPACE_DECL
629 // ****************************************************************