1 #include "ace/CDR_Base.h"
3 #if !defined (__ACE_INLINE__)
4 # include "ace/CDR_Base.inl"
5 #endif /* ! __ACE_INLINE__ */
7 #include "ace/Message_Block.h"
8 #include "ace/OS_Memory.h"
9 #include "ace/OS_NS_string.h"
11 #ifdef ACE_LACKS_IOSTREAM_TOTALLY
12 #include "ace/OS_NS_stdio.h"
14 #include "ace/streams.h"
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 #if defined (NONNATIVE_LONGDOUBLE)
25 static constexpr ACE_INT16 max_eleven_bit
= 0x3ff;
26 static constexpr ACE_INT16 max_fifteen_bit
= 0x3fff;
27 #endif /* NONNATIVE_LONGDOUBLE */
29 // See comments in CDR_Base.inl about optimization cases for swap_XX_array.
31 ACE_CDR::swap_2_array (char const * orig
, char* target
, size_t n
)
33 // ACE_ASSERT(n > 0); The caller checks that n > 0
35 // We pretend that AMD64/GNU G++ systems have a Pentium CPU to
36 // take advantage of the inline assembly implementation.
38 // Later, we try to read in 32 or 64 bit chunks,
39 // so make sure we don't do that for unaligned addresses.
40 #if ACE_SIZEOF_LONG == 8 && \
41 !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__))
42 char const * const o8
= ACE_ptr_align_binary (orig
, 8);
43 while (orig
< o8
&& n
> 0)
45 ACE_CDR::swap_2 (orig
, target
);
51 char const * const o4
= ACE_ptr_align_binary (orig
, 4);
52 // this is an _if_, not a _while_. The mismatch can only be by 2.
55 ACE_CDR::swap_2 (orig
, target
);
65 // Loop unrolling. Here be dragons.
68 // (n & (~3)) is the greatest multiple of 4 not bigger than n.
69 // In the while loop ahead, orig will move over the array by 8 byte
70 // increments (4 elements of 2 bytes).
71 // end marks our barrier for not falling outside.
72 char const * const end
= orig
+ 2 * (n
& (~3));
74 // See if we're aligned for writing in 64 or 32 bit chunks...
75 #if ACE_SIZEOF_LONG == 8 && \
76 !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__))
77 if (target
== ACE_ptr_align_binary (target
, 8))
79 if (target
== ACE_ptr_align_binary (target
, 4))
84 #if defined (ACE_HAS_INTEL_ASSEMBLY)
86 * reinterpret_cast<const unsigned int*> (orig
);
88 * reinterpret_cast<const unsigned int*> (orig
+ 4);
89 asm ( "bswap %1" : "=r" (a
) : "0" (a
) );
90 asm ( "bswap %1" : "=r" (b
) : "0" (b
) );
91 asm ( "rol $16, %1" : "=r" (a
) : "0" (a
) );
92 asm ( "rol $16, %1" : "=r" (b
) : "0" (b
) );
93 * reinterpret_cast<unsigned int*> (target
) = a
;
94 * reinterpret_cast<unsigned int*> (target
+ 4) = b
;
95 #elif defined(ACE_HAS_PENTIUM) \
96 && (defined(_MSC_VER) || defined(__BORLANDC__)) \
97 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
99 __asm mov edx
, target
;
100 __asm mov eax
, [ecx
];
101 __asm mov ebx
, 4[ecx
];
106 __asm mov
[edx
], eax
;
107 __asm mov
4[edx
], ebx
;
108 #elif ACE_SIZEOF_LONG == 8
109 // 64 bit architecture.
110 unsigned long a
= * reinterpret_cast<const unsigned long*> (orig
);
112 unsigned long a1
= (a
& 0x00ff00ff00ff00ffUL
) << 8;
113 unsigned long a2
= (a
& 0xff00ff00ff00ff00UL
) >> 8;
117 * reinterpret_cast<unsigned long*> (target
) = a
;
119 ACE_UINT32 a
= * reinterpret_cast<const ACE_UINT32
*> (orig
);
120 ACE_UINT32 b
= * reinterpret_cast<const ACE_UINT32
*> (orig
+ 4);
122 ACE_UINT32 a1
= (a
& 0x00ff00ffU
) << 8;
123 ACE_UINT32 b1
= (b
& 0x00ff00ffU
) << 8;
124 ACE_UINT32 a2
= (a
& 0xff00ff00U
) >> 8;
125 ACE_UINT32 b2
= (b
& 0xff00ff00U
) >> 8;
130 * reinterpret_cast<ACE_UINT32
*> (target
) = a
;
131 * reinterpret_cast<ACE_UINT32
*> (target
+ 4) = b
;
139 // We're out of luck. We have to write in 2 byte chunks.
142 #if defined (ACE_HAS_INTEL_ASSEMBLY)
144 * reinterpret_cast<const unsigned int*> (orig
);
146 * reinterpret_cast<const unsigned int*> (orig
+ 4);
147 asm ( "bswap %1" : "=r" (a
) : "0" (a
) );
148 asm ( "bswap %1" : "=r" (b
) : "0" (b
) );
149 // We're little endian.
150 * reinterpret_cast<unsigned short*> (target
+ 2)
151 = (unsigned short) (a
& 0xffff);
152 * reinterpret_cast<unsigned short*> (target
+ 6)
153 = (unsigned short) (b
& 0xffff);
154 asm ( "shrl $16, %1" : "=r" (a
) : "0" (a
) );
155 asm ( "shrl $16, %1" : "=r" (b
) : "0" (b
) );
156 * reinterpret_cast<unsigned short*> (target
+ 0)
157 = (unsigned short) (a
& 0xffff);
158 * reinterpret_cast<unsigned short*> (target
+ 4)
159 = (unsigned short) (b
& 0xffff);
160 #elif defined (ACE_HAS_PENTIUM) \
161 && (defined (_MSC_VER) || defined (__BORLANDC__)) \
162 && !defined (ACE_LACKS_INLINE_ASSEMBLY)
164 __asm mov edx
, target
;
165 __asm mov eax
, [ecx
];
166 __asm mov ebx
, 4[ecx
];
169 // We're little endian.
170 __asm mov
2[edx
], ax
;
171 __asm mov
6[edx
], bx
;
174 __asm mov
0[edx
], ax
;
175 __asm mov
4[edx
], bx
;
176 #elif ACE_SIZEOF_LONG == 8
177 // 64 bit architecture.
178 unsigned long a
= * reinterpret_cast<const unsigned long*> (orig
);
180 unsigned long a1
= (a
& 0x00ff00ff00ff00ffUL
) << 8;
181 unsigned long a2
= (a
& 0xff00ff00ff00ff00UL
) >> 8;
185 ACE_UINT16 b1
= static_cast<ACE_UINT16
> (a
>> 48);
186 ACE_UINT16 b2
= static_cast<ACE_UINT16
> ((a
>> 32) & 0xffff);
187 ACE_UINT16 b3
= static_cast<ACE_UINT16
> ((a
>> 16) & 0xffff);
188 ACE_UINT16 b4
= static_cast<ACE_UINT16
> (a
& 0xffff);
190 #if defined(ACE_LITTLE_ENDIAN)
191 * reinterpret_cast<ACE_UINT16
*> (target
) = b4
;
192 * reinterpret_cast<ACE_UINT16
*> (target
+ 2) = b3
;
193 * reinterpret_cast<ACE_UINT16
*> (target
+ 4) = b2
;
194 * reinterpret_cast<ACE_UINT16
*> (target
+ 6) = b1
;
196 * reinterpret_cast<ACE_UINT16
*> (target
) = b1
;
197 * reinterpret_cast<ACE_UINT16
*> (target
+ 2) = b2
;
198 * reinterpret_cast<ACE_UINT16
*> (target
+ 4) = b3
;
199 * reinterpret_cast<ACE_UINT16
*> (target
+ 6) = b4
;
202 ACE_UINT32 a
= * reinterpret_cast<const ACE_UINT32
*> (orig
);
203 ACE_UINT32 b
= * reinterpret_cast<const ACE_UINT32
*> (orig
+ 4);
205 ACE_UINT32 a1
= (a
& 0x00ff00ff) << 8;
206 ACE_UINT32 b1
= (b
& 0x00ff00ff) << 8;
207 ACE_UINT32 a2
= (a
& 0xff00ff00) >> 8;
208 ACE_UINT32 b2
= (b
& 0xff00ff00) >> 8;
213 ACE_UINT32 c1
= static_cast<ACE_UINT16
> (a
>> 16);
214 ACE_UINT32 c2
= static_cast<ACE_UINT16
> (a
& 0xffff);
215 ACE_UINT32 c3
= static_cast<ACE_UINT16
> (b
>> 16);
216 ACE_UINT32 c4
= static_cast<ACE_UINT16
> (b
& 0xffff);
218 #if defined(ACE_LITTLE_ENDIAN)
219 * reinterpret_cast<ACE_UINT16
*> (target
) = c2
;
220 * reinterpret_cast<ACE_UINT16
*> (target
+ 2) = c1
;
221 * reinterpret_cast<ACE_UINT16
*> (target
+ 4) = c4
;
222 * reinterpret_cast<ACE_UINT16
*> (target
+ 6) = c3
;
224 * reinterpret_cast<ACE_UINT16
*> (target
) = c1
;
225 * reinterpret_cast<ACE_UINT16
*> (target
+ 2) = c2
;
226 * reinterpret_cast<ACE_UINT16
*> (target
+ 4) = c3
;
227 * reinterpret_cast<ACE_UINT16
*> (target
+ 6) = c4
;
236 // (n & 3) == (n % 4).
239 ACE_CDR::swap_2 (orig
, target
);
244 ACE_CDR::swap_2 (orig
, target
);
249 ACE_CDR::swap_2 (orig
, target
);
254 ACE_CDR::swap_4_array (char const * orig
, char* target
, size_t n
)
256 // ACE_ASSERT (n > 0); The caller checks that n > 0
258 #if ACE_SIZEOF_LONG == 8
259 // Later, we read from *orig in 64 bit chunks,
260 // so make sure we don't generate unaligned readings.
261 char const * const o8
= ACE_ptr_align_binary (orig
, 8);
262 // The mismatch can only be by 4.
265 ACE_CDR::swap_4 (orig
, target
);
270 #endif /* ACE_SIZEOF_LONG == 8 */
276 // Loop unrolling. Here be dragons.
279 // (n & (~3)) is the greatest multiple of 4 not bigger than n.
280 // In the while loop, orig will move over the array by 16 byte
281 // increments (4 elements of 4 bytes).
282 // ends marks our barrier for not falling outside.
283 char const * const end
= orig
+ 4 * (n
& (~3));
285 #if ACE_SIZEOF_LONG == 8
286 // 64 bits architecture.
287 // See if we can write in 8 byte chunks.
288 if (target
== ACE_ptr_align_binary (target
, 8))
292 unsigned long a
= * reinterpret_cast<const long*> (orig
);
293 unsigned long b
= * reinterpret_cast<const long*> (orig
+ 8);
295 #if defined(ACE_HAS_INTEL_ASSEMBLY)
296 asm ("bswapq %1" : "=r" (a
) : "0" (a
));
297 asm ("bswapq %1" : "=r" (b
) : "0" (b
));
298 asm ("rol $32, %1" : "=r" (a
) : "0" (a
));
299 asm ("rol $32, %1" : "=r" (b
) : "0" (b
));
301 unsigned long a84
= (a
& 0x000000ff000000ffL
) << 24;
302 unsigned long b84
= (b
& 0x000000ff000000ffL
) << 24;
303 unsigned long a73
= (a
& 0x0000ff000000ff00L
) << 8;
304 unsigned long b73
= (b
& 0x0000ff000000ff00L
) << 8;
305 unsigned long a62
= (a
& 0x00ff000000ff0000L
) >> 8;
306 unsigned long b62
= (b
& 0x00ff000000ff0000L
) >> 8;
307 unsigned long a51
= (a
& 0xff000000ff000000L
) >> 24;
308 unsigned long b51
= (b
& 0xff000000ff000000L
) >> 24;
310 a
= (a84
| a73
| a62
| a51
);
311 b
= (b84
| b73
| b62
| b51
);
314 * reinterpret_cast<long*> (target
) = a
;
315 * reinterpret_cast<long*> (target
+ 8) = b
;
323 // We are out of luck, we have to write in 4 byte chunks.
326 unsigned long a
= * reinterpret_cast<const long*> (orig
);
327 unsigned long b
= * reinterpret_cast<const long*> (orig
+ 8);
329 #if defined(ACE_HAS_INTEL_ASSEMBLY)
330 asm ("bswapq %1" : "=r" (a
) : "0" (a
));
331 asm ("bswapq %1" : "=r" (b
) : "0" (b
));
332 asm ("rol $32, %1" : "=r" (a
) : "0" (a
));
333 asm ("rol $32, %1" : "=r" (b
) : "0" (b
));
335 unsigned long a84
= (a
& 0x000000ff000000ffL
) << 24;
336 unsigned long b84
= (b
& 0x000000ff000000ffL
) << 24;
337 unsigned long a73
= (a
& 0x0000ff000000ff00L
) << 8;
338 unsigned long b73
= (b
& 0x0000ff000000ff00L
) << 8;
339 unsigned long a62
= (a
& 0x00ff000000ff0000L
) >> 8;
340 unsigned long b62
= (b
& 0x00ff000000ff0000L
) >> 8;
341 unsigned long a51
= (a
& 0xff000000ff000000L
) >> 24;
342 unsigned long b51
= (b
& 0xff000000ff000000L
) >> 24;
344 a
= (a84
| a73
| a62
| a51
);
345 b
= (b84
| b73
| b62
| b51
);
348 ACE_UINT32 c1
= static_cast<ACE_UINT32
> (a
>> 32);
349 ACE_UINT32 c2
= static_cast<ACE_UINT32
> (a
& 0xffffffff);
350 ACE_UINT32 c3
= static_cast<ACE_UINT32
> (b
>> 32);
351 ACE_UINT32 c4
= static_cast<ACE_UINT32
> (b
& 0xffffffff);
353 #if defined (ACE_LITTLE_ENDIAN)
354 * reinterpret_cast<ACE_UINT32
*> (target
+ 0) = c2
;
355 * reinterpret_cast<ACE_UINT32
*> (target
+ 4) = c1
;
356 * reinterpret_cast<ACE_UINT32
*> (target
+ 8) = c4
;
357 * reinterpret_cast<ACE_UINT32
*> (target
+ 12) = c3
;
359 * reinterpret_cast<ACE_UINT32
*> (target
+ 0) = c1
;
360 * reinterpret_cast<ACE_UINT32
*> (target
+ 4) = c2
;
361 * reinterpret_cast<ACE_UINT32
*> (target
+ 8) = c3
;
362 * reinterpret_cast<ACE_UINT32
*> (target
+ 12) = c4
;
369 #else /* ACE_SIZEOF_LONG != 8 */
373 #if defined (ACE_HAS_PENTIUM) && defined (__GNUG__)
374 unsigned int a
= *reinterpret_cast<const unsigned int*> (orig
);
375 unsigned int b
= *reinterpret_cast<const unsigned int*> (orig
+ 4);
376 unsigned int c
= *reinterpret_cast<const unsigned int*> (orig
+ 8);
377 unsigned int d
= *reinterpret_cast<const unsigned int*> (orig
+ 12);
379 asm ("bswap %1" : "=r" (a
) : "0" (a
));
380 asm ("bswap %1" : "=r" (b
) : "0" (b
));
381 asm ("bswap %1" : "=r" (c
) : "0" (c
));
382 asm ("bswap %1" : "=r" (d
) : "0" (d
));
384 *reinterpret_cast<unsigned int*> (target
) = a
;
385 *reinterpret_cast<unsigned int*> (target
+ 4) = b
;
386 *reinterpret_cast<unsigned int*> (target
+ 8) = c
;
387 *reinterpret_cast<unsigned int*> (target
+ 12) = d
;
388 #elif defined (ACE_HAS_PENTIUM) \
389 && (defined (_MSC_VER) || defined (__BORLANDC__)) \
390 && !defined (ACE_LACKS_INLINE_ASSEMBLY)
392 __asm mov esi
, target
394 __asm mov ecx
, 4[eax
]
395 __asm mov ebx
, 8[eax
]
396 __asm mov eax
, 12[eax
]
402 __asm mov
4[esi
], ecx
403 __asm mov
8[esi
], ebx
404 __asm mov
12[esi
], eax
406 ACE_UINT32 a
= * reinterpret_cast<const ACE_UINT32
*> (orig
);
407 ACE_UINT32 b
= * reinterpret_cast<const ACE_UINT32
*> (orig
+ 4);
408 ACE_UINT32 c
= * reinterpret_cast<const ACE_UINT32
*> (orig
+ 8);
409 ACE_UINT32 d
= * reinterpret_cast<const ACE_UINT32
*> (orig
+ 12);
411 // Expect the optimizer reordering this A LOT.
412 // We leave it this way for clarity.
413 a
= (a
<< 24) | ((a
& 0xff00) << 8) | ((a
& 0xff0000) >> 8) | (a
>> 24);
414 b
= (b
<< 24) | ((b
& 0xff00) << 8) | ((b
& 0xff0000) >> 8) | (b
>> 24);
415 c
= (c
<< 24) | ((c
& 0xff00) << 8) | ((c
& 0xff0000) >> 8) | (c
>> 24);
416 d
= (d
<< 24) | ((d
& 0xff00) << 8) | ((d
& 0xff0000) >> 8) | (d
>> 24);
418 * reinterpret_cast<ACE_UINT32
*> (target
) = a
;
419 * reinterpret_cast<ACE_UINT32
*> (target
+ 4) = b
;
420 * reinterpret_cast<ACE_UINT32
*> (target
+ 8) = c
;
421 * reinterpret_cast<ACE_UINT32
*> (target
+ 12) = d
;
428 #endif /* ACE_SIZEOF_LONG == 8 */
430 // (n & 3) == (n % 4).
433 ACE_CDR::swap_4 (orig
, target
);
438 ACE_CDR::swap_4 (orig
, target
);
443 ACE_CDR::swap_4 (orig
, target
);
448 // We don't benefit from unrolling in swap_8_array and swap_16_array
449 // (swap_8 and swap_16 are big enough).
452 ACE_CDR::swap_8_array (char const * orig
, char* target
, size_t n
)
454 // ACE_ASSERT(n > 0); The caller checks that n > 0
456 char const * const end
= orig
+ 8*n
;
459 swap_8 (orig
, target
);
466 ACE_CDR::swap_16_array (char const * orig
, char* target
, size_t n
)
468 // ACE_ASSERT(n > 0); The caller checks that n > 0
470 char const * const end
= orig
+ 16*n
;
473 swap_16 (orig
, target
);
480 ACE_CDR::mb_align (ACE_Message_Block
*mb
)
482 #if !defined (ACE_CDR_IGNORE_ALIGNMENT)
483 char * const start
= ACE_ptr_align_binary (mb
->base (),
484 ACE_CDR::MAX_ALIGNMENT
);
486 char * const start
= mb
->base ();
487 #endif /* ACE_CDR_IGNORE_ALIGNMENT */
493 ACE_CDR::grow (ACE_Message_Block
*mb
, size_t minsize
)
496 ACE_CDR::first_size (minsize
+ ACE_CDR::MAX_ALIGNMENT
);
498 if (newsize
<= mb
->size ())
502 mb
->data_block ()->clone_nocopy (0, newsize
);
507 // Do the equivalent of ACE_CDR::mb_align() here to avoid having
508 // to allocate an ACE_Message_Block on the stack thereby avoiding
509 // the manipulation of the data blocks reference count
510 size_t mb_len
= mb
->length ();
511 char *start
= ACE_ptr_align_binary (db
->base (),
512 ACE_CDR::MAX_ALIGNMENT
);
514 ACE_OS::memcpy (start
, mb
->rd_ptr (), mb_len
);
517 // Setting the data block on the mb resets the read and write
518 // pointers back to the beginning. We must set the rd_ptr to the
519 // aligned start and adjust the write pointer to the end
521 mb
->wr_ptr (start
+ mb_len
);
523 // Remove the DONT_DELETE flags from mb
524 mb
->clr_self_flags (ACE_Message_Block::DONT_DELETE
);
530 ACE_CDR::total_length (const ACE_Message_Block
* begin
,
531 const ACE_Message_Block
* end
)
534 // Compute the total size.
535 for (const ACE_Message_Block
*i
= begin
;
543 ACE_CDR::consolidate (ACE_Message_Block
*dst
,
544 const ACE_Message_Block
*src
)
549 size_t const newsize
=
550 ACE_CDR::first_size (ACE_CDR::total_length (src
, 0)
551 + ACE_CDR::MAX_ALIGNMENT
);
553 if (dst
->size (newsize
) == -1)
556 #if !defined (ACE_CDR_IGNORE_ALIGNMENT)
557 // We must copy the contents of src into the new buffer, but
558 // respecting the alignment.
560 ptrdiff_t(src
->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT
;
562 ptrdiff_t(dst
->rd_ptr ()) % ACE_CDR::MAX_ALIGNMENT
;
563 ptrdiff_t offset
= srcalign
- dstalign
;
565 offset
+= ACE_CDR::MAX_ALIGNMENT
;
566 dst
->rd_ptr (static_cast<size_t> (offset
));
567 dst
->wr_ptr (dst
->rd_ptr ());
568 #endif /* ACE_CDR_IGNORE_ALIGNMENT */
570 for (const ACE_Message_Block
* i
= src
;
574 // If the destination and source are the same, do not
575 // attempt to copy the data. Just update the write pointer.
576 if (dst
->wr_ptr () != i
->rd_ptr ())
577 dst
->copy (i
->rd_ptr (), i
->length ());
579 dst
->wr_ptr (i
->length ());
584 #if defined (NONNATIVE_LONGDOUBLE)
586 ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble::NativeImpl
& rhs
)
588 ACE_OS::memset (this->ld
, 0, sizeof (this->ld
));
590 if (sizeof (rhs
) == 8)
592 #if defined (ACE_LITTLE_ENDIAN)
593 static const size_t byte_zero
= 1;
594 static const size_t byte_one
= 0;
596 ACE_CDR::swap_8 (reinterpret_cast<const char*> (&rhs
), rhs_ptr
);
598 static const size_t byte_zero
= 0;
599 static const size_t byte_one
= 1;
600 const char* rhs_ptr
= reinterpret_cast<const char*> (&rhs
);
602 ACE_INT16 sign
= static_cast<ACE_INT16
> (
603 static_cast<signed char> (rhs_ptr
[0])) & 0x8000;
604 ACE_INT16 exponent
= ((rhs_ptr
[0] & 0x7f) << 4) |
605 ((rhs_ptr
[1] >> 4) & 0xf);
606 const char* exp_ptr
= reinterpret_cast<const char*> (&exponent
);
608 // Infinity and NaN have an exponent of 0x7ff in 64-bit IEEE
609 if (exponent
== 0x7ff)
613 else if (exponent
) // exponent 0 stays 0 in 128-bit
615 exponent
= (exponent
- max_eleven_bit
) + max_fifteen_bit
;
619 // Store the sign bit and exponent
620 this->ld
[0] = exp_ptr
[byte_zero
];
621 this->ld
[1] = exp_ptr
[byte_one
];
623 // Store the mantissa. In an 8 byte double, it is split by
624 // 4 bits (because of the 12 bits for sign and exponent), so
625 // we have to shift and or the rhs to get the right bytes.
627 bool direction
= true;
628 for (size_t ri
= 1; ri
< sizeof (rhs
);)
632 this->ld
[li
] |= ((rhs_ptr
[ri
] << 4) & 0xf0);
638 this->ld
[li
] |= ((rhs_ptr
[ri
] >> 4) & 0xf);
643 #if defined (ACE_LITTLE_ENDIAN)
644 ACE_OS::memcpy (rhs_ptr
, this->ld
, sizeof (this->ld
));
645 ACE_CDR::swap_16 (rhs_ptr
, this->ld
);
650 ACE_OS::memcpy(this->ld
,
651 reinterpret_cast<const char*> (&rhs
), sizeof (rhs
));
657 ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble
& rhs
)
665 ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble
&rhs
) const
667 return ACE_OS::memcmp (this->ld
, rhs
.ld
, 16) == 0;
671 ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble
&rhs
) const
673 return ACE_OS::memcmp (this->ld
, rhs
.ld
, 16) != 0;
676 ACE_CDR::LongDouble::operator ACE_CDR::LongDouble::NativeImpl () const
678 ACE_CDR::LongDouble::NativeImpl ret
= 0.0;
679 char* lhs_ptr
= reinterpret_cast<char*> (&ret
);
681 if (sizeof (ret
) == 8)
683 #if defined (ACE_LITTLE_ENDIAN)
684 static const size_t byte_zero
= 1;
685 static const size_t byte_one
= 0;
687 ACE_CDR::swap_16 (this->ld
, copy
);
689 static const size_t byte_zero
= 0;
690 static const size_t byte_one
= 1;
691 const char* copy
= this->ld
;
693 ACE_INT16 exponent
= 0;
694 char* exp_ptr
= reinterpret_cast<char*> (&exponent
);
695 exp_ptr
[byte_zero
] = copy
[0];
696 exp_ptr
[byte_one
] = copy
[1];
698 ACE_INT16 sign
= (exponent
& 0x8000);
701 // Infinity and NaN have an exponent of 0x7fff in 128-bit IEEE
702 if (exponent
== 0x7fff)
706 else if (exponent
) // exponent 0 stays 0 in 64-bit
708 exponent
= (exponent
- max_fifteen_bit
) + max_eleven_bit
;
710 exponent
= (exponent
<< 4) | sign
;
712 // Store the sign and exponent
713 lhs_ptr
[0] = exp_ptr
[byte_zero
];
714 lhs_ptr
[1] = exp_ptr
[byte_one
];
716 // Store the mantissa. In an 8 byte double, it is split by
717 // 4 bits (because of the 12 bits for sign and exponent), so
718 // we have to shift and or the rhs to get the right bytes.
720 bool direction
= true;
721 for (size_t ri
= 2; li
< sizeof (ret
);) {
724 lhs_ptr
[li
] |= ((copy
[ri
] >> 4) & 0xf);
730 lhs_ptr
[li
] |= ((copy
[ri
] & 0xf) << 4);
736 #if defined (ACE_LITTLE_ENDIAN)
737 ACE_CDR::swap_8 (lhs_ptr
, lhs_ptr
);
742 ACE_OS::memcpy(lhs_ptr
, this->ld
, sizeof (ret
));
745 // This bit of code is unnecessary. However, this code is
746 // necessary to work around a bug in the gcc 4.1.1 optimizer.
747 ACE_CDR::LongDouble tmp
;
752 #endif /* NONNATIVE_LONGDOUBLE */
757 ACE_CDR::Fixed
ACE_CDR::Fixed::from_integer (ACE_CDR::LongLong val
)
760 f
.value_
[15] = (val
< 0) ? NEGATIVE
: POSITIVE
;
767 const int mod
= static_cast<int> (val
% 10);
768 const unsigned int digit
= (mod
< 0) ? -mod
: mod
;
770 f
.value_
[idx
--] |= digit
<< 4;
772 f
.value_
[idx
] = digit
;
775 if (val
>= 10 || val
<= -10)
781 ACE_OS::memset (f
.value_
, 0, idx
+ !high
);
785 ACE_CDR::Fixed
ACE_CDR::Fixed::from_integer (ACE_CDR::ULongLong val
)
788 f
.value_
[15] = POSITIVE
;
795 const unsigned int digit
= val
% 10;
797 f
.value_
[idx
--] |= digit
<< 4;
799 f
.value_
[idx
] = digit
;
808 ACE_OS::memset (f
.value_
, 0, idx
+ !high
);
812 ACE_CDR::Fixed
ACE_CDR::Fixed::from_floating (LongDouble val
)
814 #if defined ACE_VXWORKS && !defined __RTP__
815 typedef double BigFloat
;
816 #elif defined NONNATIVE_LONGDOUBLE
817 typedef LongDouble::NativeImpl BigFloat
;
819 using BigFloat
= LongDouble
;
823 f
.digits_
= f
.scale_
= 0;
824 bool negative
= false;
831 // How many digits are to the left of the decimal point?
832 const size_t digits_left
=
833 static_cast<size_t> (1 + ((val
> 0) ? std::log10 (val
) : 0));
834 if (digits_left
> MAX_DIGITS
)
836 ACE_OS::memset (f
.value_
, 0, sizeof f
.value_
);
840 f
.digits_
= MAX_DIGITS
;
843 BigFloat frac_part
= std::modf (val
, &int_part
);
845 // Insert the integer part from least to most significant
846 int idx
= (static_cast<int> (digits_left
) + 1) / 2 - 1;
847 bool high
= digits_left
% 2;
850 for (size_t i
= 0; i
< digits_left
; ++i
, high
= !high
)
852 const Octet digit
= static_cast<Octet
> (std::fmod (int_part
, 10));
854 f
.value_
[idx
--] |= digit
<< 4;
856 f
.value_
[idx
] = digit
;
860 // Insert the fractional part from most to least significant
861 idx
= static_cast<int> (digits_left
/ 2);
862 high
= digits_left
% 2 == 0;
863 for (size_t i
= digits_left
; i
< MAX_DIGITS
; ++i
, high
= !high
)
866 const Octet digit
= static_cast<Octet
> (frac_part
);
869 f
.value_
[idx
] = digit
<< 4;
871 f
.value_
[idx
++] |= digit
;
874 if (frac_part
>= 0.5)
875 ++f
; // scale set after here so that ++ applies to the fractional part
877 f
.scale_
= static_cast<Octet
> (MAX_DIGITS
- digits_left
);
879 f
.value_
[15] |= negative
? NEGATIVE
: POSITIVE
;
883 void ACE_CDR::Fixed::normalize (UShort min_scale
)
885 if (this->value_
[15] & 0xf0 || !this->scale_
)
888 // Calculate the number of nibbles that can be moved.
889 ACE_CDR::Octet nibbles
= 0;
890 while (this->digit(nibbles
) == 0 && this->scale_
- nibbles
> min_scale
)
893 // Move and clear the nibbles.
894 for (ACE_CDR::Octet idx
= nibbles
; idx
!= this->digits_
; ++idx
) {
895 this->digit (idx
- nibbles
, this->digit (idx
));
896 this->digit (idx
, 0);
899 this->scale_
-= nibbles
;
900 this->digits_
-= nibbles
;
903 ACE_CDR::Fixed
ACE_CDR::Fixed::from_string (const char *str
)
905 const bool negative
= *str
== '-';
906 if (negative
|| *str
== '+')
909 const size_t span
= ACE_OS::strspn (str
, ".0123456789");
912 f
.value_
[15] = negative
? NEGATIVE
: POSITIVE
;
918 for (size_t iter
= span
; iter
&& f
.digits_
< MAX_DIGITS
; --iter
, high
= !high
)
920 if (str
[iter
- 1] == '.')
922 f
.scale_
= static_cast<Octet
> (span
- iter
);
927 const unsigned int digit
= str
[iter
- 1] - '0';
929 f
.value_
[idx
--] |= digit
<< 4;
931 f
.value_
[idx
] = digit
;
935 if (!f
.scale_
&& span
> f
.digits_
&& str
[span
- f
.digits_
- 1] == '.')
936 f
.scale_
= f
.digits_
;
939 ACE_OS::memset (f
.value_
, 0, idx
+ !high
);
943 ACE_CDR::Fixed
ACE_CDR::Fixed::from_octets (const Octet
*array
, int len
,
947 ACE_OS::memcpy (f
.value_
+ 16 - len
, array
, len
);
948 ACE_OS::memset (f
.value_
, 0, 16 - len
);
951 f
.digits_
= len
* 2 - 1;
952 if (len
> 1 && (array
[0] >> 4) == 0)
958 ACE_CDR::Fixed::operator ACE_CDR::LongLong () const
962 for (int i
= this->digits_
- 1; i
>= this->scale_
; --i
)
963 val
= 10 * val
+ this->digit (i
);
971 ACE_CDR::Fixed::operator ACE_CDR::LongDouble () const
973 LongDouble val
= ACE_CDR_LONG_DOUBLE_INITIALIZER
;
975 for (int i
= this->digits_
- 1; i
>= this->scale_
; --i
)
976 ACE_CDR_LONG_DOUBLE_ASSIGNMENT (val
, 10 * val
+ this->digit (i
));
978 for (int i
= this->scale_
- 1; i
>= 0; --i
)
979 val
+= this->digit (i
) * std::pow (10.0l, i
- this->scale_
);
987 ACE_CDR::Fixed
ACE_CDR::Fixed::round (UShort scale
) const
990 if (scale
< f
.scale_
)
992 for (UShort i
= 0; i
< f
.scale_
- scale
; ++i
)
995 const bool negative
= f
.sign ();
997 f
.value_
[15] = (f
.value_
[15] & 0xf0) | POSITIVE
;
998 if (this->digit (this->scale_
- scale
- 1) >= 5)
1002 f
.scale_
= static_cast<Octet
> (scale
);
1004 if (negative
&& !!f
)
1005 f
.value_
[15] = (f
.value_
[15] & 0xf0) | NEGATIVE
;
1010 ACE_CDR::Fixed
ACE_CDR::Fixed::truncate (UShort scale
) const
1013 if (scale
< f
.scale_
)
1015 for (UShort i
= 0; i
< f
.scale_
- scale
; ++i
)
1017 f
.normalize (scale
);
1020 f
.value_
[15] = (f
.value_
[15] & 0xf0) | POSITIVE
;
1022 f
.value_
[15] = (f
.value_
[15] & 0xf0) | NEGATIVE
;
1029 struct BufferAppender
1031 BufferAppender (char *buffer
, size_t buffer_size
)
1032 : buffer_ (buffer
), buffer_size_ (buffer_size
), idx_ (0) {}
1034 bool operator+= (char ch
)
1036 if (this->idx_
== this->buffer_size_
- 1)
1038 this->buffer_
[this->idx_
++] = ch
;
1042 char *const buffer_
;
1043 const size_t buffer_size_
;
1048 bool ACE_CDR::Fixed::to_string (char *buffer
, size_t buffer_size
) const
1050 if (!buffer
|| buffer_size
< 2)
1053 const bool negative
= this->sign ();
1056 BufferAppender
ba (buffer
+ negative
, buffer_size
- negative
);
1058 for (int i
= 15 - this->digits_
/ 2; i
< 16; ++i
)
1060 const Octet high
= this->value_
[i
] >> 4, low
= this->value_
[i
] & 0xf;
1062 if ((15 - i
) * 2 != this->digits_
)
1064 if (this->scale_
== 1 + 2 * (15 - i
))
1066 if (!ba
.idx_
&& !(ba
+= '0'))
1073 if ((ba
.idx_
|| high
) && !(ba
+= '0' + high
))
1077 if (this->scale_
&& this->scale_
== 2 * (15 - i
))
1079 if (!ba
.idx_
&& !(ba
+= '0'))
1086 if (i
< 15 && (ba
.idx_
|| low
) && !(ba
+= '0' + low
))
1090 if (!ba
.idx_
&& !(ba
+= '0'))
1093 buffer
[ba
.idx_
+ negative
] = 0;
1097 const ACE_CDR::Octet
*ACE_CDR::Fixed::to_octets (int &n
) const
1099 n
= (this->digits_
+ 2) / 2;
1100 return 16 - n
+ reinterpret_cast<const Octet
*> (this->value_
);
1103 ACE_CDR::Fixed::ConstIterator
ACE_CDR::Fixed::pre_add (const ACE_CDR::Fixed
&f
)
1105 ConstIterator rhs_iter
= f
.begin ();
1106 if (f
.scale_
> this->scale_
)
1108 const int scale_diff
= f
.scale_
- this->scale_
;
1109 rhs_iter
+= scale_diff
- this->lshift (scale_diff
);
1112 if (f
.digits_
- f
.scale_
> this->digits_
- this->scale_
)
1114 ACE_CDR::Octet new_digits
= this->digits_
+ (f
.digits_
- f
.scale_
) - (this->digits_
- this->scale_
);
1115 if (new_digits
> MAX_DIGITS
)
1117 for (size_t i
= 0; i
< static_cast<size_t> (new_digits
- MAX_DIGITS
); ++i
)
1118 this->digit (static_cast<int> (i
), 0);
1119 this->normalize (this->scale_
- (new_digits
- MAX_DIGITS
));
1120 this->digits_
= MAX_DIGITS
;
1123 this->digits_
= new_digits
;
1128 ACE_CDR::Fixed
&ACE_CDR::Fixed::operator+= (const Fixed
&rhs
)
1130 if (!this->sign () && rhs
.sign ())
1131 return *this -= -rhs
;
1133 if (this->sign () && !rhs
.sign ())
1135 Fixed negated
= -*this;
1137 return *this = -negated
;
1140 ConstIterator rhs_iter
= this->pre_add (rhs
);
1142 Iterator lhs_iter
= this->begin ();
1143 if (this->scale_
> rhs
.scale_
)
1144 lhs_iter
+= this->scale_
- rhs
.scale_
;
1147 for (; rhs_iter
!= rhs
.end (); ++lhs_iter
, ++rhs_iter
)
1149 const Octet digit
= *lhs_iter
+ *rhs_iter
+ carry
;
1151 *lhs_iter
= digit
- (carry
? 10 : 0);
1156 if (this->digits_
< MAX_DIGITS
)
1161 else if (this->scale_
)
1164 this->normalize (this->scale_
- 1);
1165 this->digit (MAX_DIGITS
- 1, 1);
1172 int ACE_CDR::Fixed::lshift (int digits
)
1175 for (; bytes
< digits
/ 2; ++bytes
)
1176 if (this->value_
[bytes
])
1180 if ((digits
% 2) && !(this->value_
[bytes
] & 0xf0))
1182 for (int i
= 0; i
< 15 - bytes
; ++i
)
1183 this->value_
[i
] = (this->value_
[i
+ bytes
] & 0xf) << 4
1184 | (this->value_
[i
+ bytes
+ 1] >> 4);
1185 std::memset (this->value_
+ 15 - bytes
, 0, bytes
);
1186 this->value_
[15] &= 0xf;
1187 shifted
= 2 * bytes
+ 1;
1191 std::memmove (this->value_
, this->value_
+ bytes
, 16 - bytes
);
1192 this->value_
[15] &= 0xf;
1193 std::memset (this->value_
+ 16 - bytes
, 0, bytes
- 1);
1194 this->value_
[15 - bytes
] &= 0xf0;
1195 shifted
= 2 * bytes
;
1198 this->digits_
+= shifted
;
1199 if (this->digits_
> MAX_DIGITS
)
1200 this->digits_
= MAX_DIGITS
;
1202 this->scale_
+= shifted
;
1203 if (this->scale_
> MAX_DIGITS
)
1204 this->scale_
= MAX_DIGITS
;
1209 ACE_CDR::Fixed
&ACE_CDR::Fixed::operator-= (const Fixed
&rhs
)
1211 if (!this->sign () && rhs
.sign ())
1212 return *this += -rhs
;
1214 if (this->sign () && !rhs
.sign ())
1216 Fixed negated
= -*this;
1218 return *this = -negated
;
1221 const Fixed before
= *this;
1222 ConstIterator rhs_iter
= this->pre_add (rhs
);
1224 Iterator lhs_iter
= this->begin ();
1225 if (this->scale_
> rhs
.scale_
)
1226 lhs_iter
+= this->scale_
- rhs
.scale_
;
1228 bool borrow
= false;
1229 for (; rhs_iter
!= rhs
.end (); ++lhs_iter
, ++rhs_iter
)
1230 if (*rhs_iter
+ borrow
<= *lhs_iter
)
1232 *lhs_iter
-= *rhs_iter
+ borrow
;
1237 *lhs_iter
+= 10 - *rhs_iter
- borrow
;
1241 while (borrow
&& lhs_iter
!= this->end ())
1251 return *this = -(rhs
- before
);
1257 ACE_CDR::Fixed
&ACE_CDR::Fixed::operator*= (const Fixed
&rhs
)
1259 if (!this->sign () && rhs
.sign ())
1260 this->value_
[15] = (this->value_
[15] & 0xf0) | NEGATIVE
;
1261 else if (this->sign () && rhs
.sign ())
1262 this->value_
[15] = (this->value_
[15] & 0xf0) | POSITIVE
;
1268 Octet temp
[MAX_DIGITS
* 2];
1271 for (int col
= 0; col
< this->digits_
+ right
.digits_
; ++col
)
1273 for (int row
= (std::max
) (0, col
- this->digits_
+ 1);
1274 row
< (std::min
) (col
+ 1, int (right
.digits_
)); ++row
)
1275 carry
+= this->digit (col
- row
) * right
.digit (row
);
1276 temp
[col
] = carry
% 10;
1280 this->digits_
+= right
.digits_
;
1281 this->scale_
+= right
.scale_
;
1282 int digit_offset
= 0;
1284 if (this->digits_
> MAX_DIGITS
)
1286 digit_offset
= this->digits_
- MAX_DIGITS
;
1287 this->digits_
= MAX_DIGITS
;
1288 if (this->scale_
> digit_offset
)
1289 this->scale_
-= digit_offset
;
1292 for (int i
= 0; i
< this->digits_
; ++i
)
1293 this->digit (i
, temp
[i
+ digit_offset
]);
1299 ACE_CDR::Fixed
&ACE_CDR::Fixed::operator/= (const Fixed
&rhs
)
1304 if (rhs
.scale_
&& rhs
.scale_
<= this->scale_
)
1305 this->scale_
-= rhs
.scale_
;
1306 else if (rhs
.scale_
)
1308 const Octet shifted
= this->lshift (rhs
.scale_
- this->scale_
);
1309 this->scale_
-= shifted
;
1312 Fixed rhs_no_scale
= rhs
;
1313 rhs_no_scale
.scale_
= 0;
1314 rhs_no_scale
.value_
[15] = (rhs_no_scale
.value_
[15] & 0xf0) | POSITIVE
;
1315 rhs_no_scale
.ltrim ();
1319 if (!this->sign () && rhs
.sign ())
1320 this->value_
[15] = (this->value_
[15] & 0xf0) | NEGATIVE
;
1321 else if (this->sign () && rhs
.sign ())
1322 this->value_
[15] = (this->value_
[15] & 0xf0) | POSITIVE
;
1324 static const Fixed one
= from_integer (LongLong (1)),
1325 two
= from_integer (LongLong (2)),
1326 three
= from_integer (LongLong (3)),
1327 five
= from_integer (LongLong (5));
1329 if (rhs_no_scale
== one
)
1332 // Most sig digit of rhs must be >= 5
1333 switch (rhs_no_scale
.digit (rhs_no_scale
.digits_
- 1))
1336 return *this = (*this * five
) / (rhs_no_scale
* five
);
1338 return *this = (*this * three
) / (rhs_no_scale
* three
);
1341 return *this = (*this * two
) / (rhs_no_scale
* two
);
1346 const bool neg
= this->sign ();
1348 this->value_
[15] = (this->value_
[15] & 0xf0) | POSITIVE
;
1351 Fixed q
= this->div_helper2 (rhs_no_scale
, r
);
1352 q
.scale_
= this->scale_
;
1355 *this = neg
? -q
: q
;
1360 const int shift
= q
.lshift (MAX_DIGITS
);
1363 const Octet scale
= r
.lshift (shift
);
1366 r
= r
.div_helper2 (rhs_no_scale
, r2
);
1371 *this = neg
? -q
: q
;
1376 ACE_CDR::Fixed
ACE_CDR::Fixed::div_helper2 (const Fixed
&rhs
, Fixed
&r
) const
1378 if (this->digits_
< rhs
.digits_
)
1380 else if (this->digits_
== rhs
.digits_
)
1386 return from_integer (LongLong (1));
1388 else if (this->digits_
== rhs
.digits_
+ 1)
1389 return this->div_helper1 (rhs
, r
);
1392 const int dig
= this->digits_
- rhs
.digits_
- 1;
1393 Fixed top
= *this, bot
= *this; // split with bot having dig digits
1394 for (int i
= 0; i
< dig
; ++i
)
1396 for (int i
= dig
; i
< this->digits_
; ++i
)
1400 top
.normalize (this->scale_
);
1403 const Fixed qtop
= top
.div_helper1 (rhs
, rtop
);
1404 const Fixed qbot
= rtop
.join (dig
, bot
).div_helper2 (rhs
, r
);
1405 return qtop
.join (dig
, qbot
);
1408 return from_integer ();
1411 ACE_CDR::Fixed
ACE_CDR::Fixed::div_helper1 (const Fixed
&rhs
, Fixed
&r
) const
1413 static const Fixed ten
= from_integer (LongLong (10));
1414 if (*this >= rhs
* ten
)
1415 return ten
+ (*this - rhs
* ten
).div_helper1 (rhs
, r
);
1417 int q
= (this->digit (this->digits_
- 1) * 10 +
1418 this->digit (this->digits_
- 2)) / rhs
.digit (rhs
.digits_
- 1);
1421 Fixed t
= from_integer (LongLong (q
)) * rhs
;
1422 t
.scale_
= this->scale_
;
1423 for (int i
= 0; i
< 2 && t
> *this; ++i
)
1430 return from_integer (LongLong (q
));
1433 ACE_CDR::Fixed
ACE_CDR::Fixed::join (int digits
, const Fixed
&bot
) const
1436 res
.digits_
= this->digits_
+ digits
;
1437 for (int i
= digits
; i
< MAX_DIGITS
&& i
- digits
< this->digits_
; ++i
)
1438 res
.digit (i
, this->digit (i
- digits
));
1442 ACE_CDR::Fixed
&ACE_CDR::Fixed::operator++ ()
1446 this->value_
[15] = (this->value_
[15] & 0xf0) | POSITIVE
;
1447 if (!!--*this) // decrement and check if result is nonzero
1448 this->value_
[15] = (this->value_
[15] & 0xf0) | NEGATIVE
;
1452 Iterator iter
= this->begin ();
1453 iter
+= this->scale_
;
1454 for (; iter
!= this->end (); ++iter
)
1463 if (this->digits_
< MAX_DIGITS
)
1472 ACE_CDR::Fixed
&ACE_CDR::Fixed::operator-- ()
1476 this->value_
[15] = (this->value_
[15] & 0xf0) | POSITIVE
;
1478 this->value_
[15] = (this->value_
[15] & 0xf0) | NEGATIVE
;
1482 Fixed before
= *this;
1483 Iterator iter
= this->begin ();
1484 iter
+= this->scale_
;
1485 for (; iter
!= this->end (); ++iter
)
1494 *this = before
- from_integer (ULongLong (1));
1499 bool ACE_CDR::Fixed::operator! () const
1501 static const Octet ZERO
[] = {0, 0, 0, 0, 0, 0, 0, 0,
1502 0, 0, 0, 0, 0, 0, 0, POSITIVE
};
1503 return 0 == ACE_OS::memcmp (this->value_
, ZERO
, sizeof ZERO
);
1506 ACE_OSTREAM_TYPE
&operator<< (ACE_OSTREAM_TYPE
&lhs
, const ACE_CDR::Fixed
&rhs
)
1508 char digits
[ACE_CDR::Fixed::MAX_STRING_SIZE
];
1509 rhs
.to_string (digits
, sizeof digits
);
1511 #ifdef ACE_LACKS_IOSTREAM_TOTALLY
1512 ACE_OS::fputs (digits
, &lhs
);
1519 #ifndef ACE_LACKS_IOSTREAM_TOTALLY
1520 std::istream
&operator>> (std::istream
&lhs
, ACE_CDR::Fixed
&rhs
)
1524 ACE_CDR::LongDouble ld
;
1525 ACE_CDR_LONG_DOUBLE_ASSIGNMENT (ld
, num
);
1526 rhs
= ACE_CDR::Fixed::from_floating (ld
);
1531 bool ACE_CDR::Fixed::less (const ACE_CDR::Fixed
&rhs
) const
1533 const Fixed
&lhs
= *this;
1534 if (lhs
.sign () != rhs
.sign ())
1537 // signs of lhs and rhs are the same so lhs < rhs reduces to:
1538 // if positive, |lhs| < |rhs|
1539 // if negative, |rhs| < |lhs|
1540 // 'a' will refer to the value left of < and 'b' to the value to the right
1541 const ACE_CDR::Fixed
&a
= lhs
.sign () ? rhs
: lhs
,
1542 &b
= lhs
.sign () ? lhs
: rhs
;
1544 if (a
.scale_
== b
.scale_
)
1545 return ACE_OS::memcmp (a
.value_
, b
.value_
, sizeof a
.value_
) < 0;
1547 const int a_int_dig
= a
.digits_
- a
.scale_
, b_int_dig
= b
.digits_
- b
.scale_
;
1549 if (a_int_dig
> b_int_dig
)
1551 for (int i
= 1; i
<= a_int_dig
- b_int_dig
; ++i
)
1552 if (a
.digit (a
.digits_
- i
))
1555 else if (a_int_dig
< b_int_dig
)
1557 for (int i
= 1; i
<= b_int_dig
- a_int_dig
; ++i
)
1558 if (b
.digit (b
.digits_
- i
))
1562 const int common_frac
= (std::min
) (a
.scale_
, b
.scale_
),
1563 common_dig
= (std::min
) (a_int_dig
, b_int_dig
) + common_frac
,
1564 a_off
= a
.scale_
- common_frac
, // a's offset (more scale than b)
1565 b_off
= b
.scale_
- common_frac
; // b's offset (more scale than a)
1567 for (int i
= 1; i
<= common_dig
; ++i
)
1568 if (a
.digit (a_off
+ common_dig
- i
) < b
.digit (b_off
+ common_dig
- i
))
1571 for (int i
= 1; i
<= a_off
; ++i
)
1572 if (a
.digit (a_off
- i
))
1575 for (int i
= 1; i
<= b_off
; ++i
)
1576 if (b
.digit (b_off
- i
))
1582 bool ACE_CDR::Fixed::equal (const ACE_CDR::Fixed
&rhs
) const
1584 const Fixed
&lhs
= *this;
1585 if (lhs
.sign () != rhs
.sign ())
1588 if (lhs
.scale_
== rhs
.scale_
)
1589 return 0 == ACE_OS::memcmp (lhs
.value_
, rhs
.value_
, sizeof lhs
.value_
);
1591 const ACE_CDR::Fixed
&more
= (lhs
.scale_
> rhs
.scale_
) ? lhs
: rhs
,
1592 &fewer
= (lhs
.scale_
> rhs
.scale_
) ? rhs
: lhs
;
1594 const ACE_CDR::Octet scale_diff
= more
.scale_
- fewer
.scale_
;
1596 ACE_CDR::Fixed::ConstIterator more_iter
= more
.begin (),
1597 more_end
= more
.end ();
1599 for (ACE_CDR::Octet i
= 0; i
< scale_diff
; ++i
)
1600 if (more_iter
== more_end
|| *more_iter
++)
1601 return false; // digits in more that are missing in fewer must be 0
1603 ACE_CDR::Fixed::ConstIterator fewer_iter
= fewer
.begin (),
1604 fewer_end
= fewer
.end ();
1606 while (more_iter
!= more_end
&& fewer_iter
!= fewer_end
)
1607 if (*more_iter
++ != *fewer_iter
++)
1608 return false; // digits in common must match
1610 while (more_iter
!= more_end
)
1612 return false; // extra (more significant) digits in more must be 0
1614 while (fewer_iter
!= fewer_end
)
1616 return false; // extra (more significant) digits in fewer must be 0
1621 ACE_END_VERSIONED_NAMESPACE_DECL