1 // @HEADER
2 // ***********************************************************************
3 //
4 //                    Teuchos: Common Tools Package
5 //                 Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_SERIALIZATION_TRAITS_HELPERS_HPP
43 #define TEUCHOS_SERIALIZATION_TRAITS_HELPERS_HPP
44 
45 #include "Teuchos_SerializationTraits.hpp"
46 #include "Teuchos_ArrayView.hpp"
47 #include "Teuchos_Array.hpp"
48 
49 namespace Teuchos {
50 
51 /** \brief A class for instantiating a default serialization object.
52  *
53  * The serialization buffer classes below are generalized beyond using the
54  * SerializationTraits to use a general serialization object.  This is to
55  * allow for more general types of serialization, e.g., when other data needs
56  * to be used.
57  *
58  * \note (mfh 16 Nov 2014) I honestly have no idea what the above
59  *   comment means.  My guess is that serializers should have little
60  *   if any state, so there is probably no benefit to keeping around a
61  *   static DefaultSerializerType object for every type T for which we
62  *   might want to send and receive data.  Furthermore, the
63  *   deallocation of static objects requires careful management, in
64  *   particular if they depend on MPI in any way.  (I recommend using
65  *   the "MPI_Finalize hook for MPI_COMM_SELF" idiom, as discussed in
66  *   the MPI standard.)  Thus, I've chosen to remove the static
67  *   objects, and just return new instances each time.
68  */
69 template <typename Ordinal, typename T>
70 class DefaultSerializer {
71 public:
72   //! Typename of default serializer
73   typedef SerializationTraits<Ordinal,T> DefaultSerializerType;
74 
75   //! Return an instance of the default serializer.
getDefaultSerializer()76   static DefaultSerializerType getDefaultSerializer() {
77     DefaultSerializerType s;
78     return s;
79   }
80 
81   //! Return an RCP of an instance of the default serializer
getDefaultSerializerRCP()82   static Teuchos::RCP<DefaultSerializerType> getDefaultSerializerRCP() {
83     return Teuchos::rcp (new DefaultSerializerType ());
84   }
85 };
86 
87 /** \brief Encapsulate how an array of non-const objects with value sematics
88  * is serialized into a <tt>char[]</tt> array.
89  *
90  * Default version templated on bool indicating whether direct serialization
91  * is supported.  The default version is empty with specializations below
92  * for direct and indirect serialization.
93  */
94 template <typename Ordinal, typename T, typename Serializer,
95           bool direct = Serializer::supportsDirectSerialization>
96 class ValueTypeSerializationBufferImp {};
97 
98 /** \brief Encapsulate how an array of const objects with value sematics is
99  * serialized into a <tt>const char[]</tt> array.
100  *
101  * Default version templated on bool indicating whether direct serialization
102  * is supported.  The default version is empty with specializations below
103  * for direct and indirect serialization.
104  */
105 template <typename Ordinal, typename T, typename Serializer,
106           bool direct = Serializer::supportsDirectSerialization>
107 class ConstValueTypeSerializationBufferImp {};
108 
109 /** \brief Encapsulate how an array of non-const serialized objects with value
110  * sematics stored in a <tt>char[]</tt> array is deserialized to a
111  * <tt>T[]</tt> array and then serialized back again.
112  *
113  * Default version templated on bool indicating whether direct serialization
114  * is supported.  The default version is empty with specializations below
115  * for direct and indirect serialization.
116  */
117 template <typename Ordinal, typename T, typename Serializer,
118           bool direct = Serializer::supportsDirectSerialization>
119 class ValueTypeDeserializationBufferImp {};
120 
121 /** \brief Encapsulate how an array of non-const serialized objects with value
122  * sematics stored in a <tt>char[]</tt> array is deserialized to a
123  * <tt>T[]</tt> array and then serialized back again.
124  *
125  * Default version templated on bool indicating whether direct serialization
126  * is supported.  The default version is empty with specializations below
127  * for direct and indirect serialization.
128  */
129 template <typename Ordinal, typename T, typename Serializer,
130           bool direct = Serializer::supportsDirectSerialization>
131 class ConstValueTypeDeserializationBufferImp {};
132 
133 /** \brief Encapsulate how an array of non-const objects with value sematics
134  * is serialized into a <tt>char[]</tt> array.
135  *
136  * Specialization for direct serialization.
137  */
138 template <typename Ordinal, typename T, typename Serializer>
139 class ValueTypeSerializationBufferImp<Ordinal,T,Serializer,true> {
140 public:
141   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
142   ValueTypeSerializationBufferImp(
143     const Ordinal count, T buffer[],
144     const RCP<const Serializer>& serializer
145     );
146   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
147    * original <tt>T[]</tt> buffer.
148    */
149   ~ValueTypeSerializationBufferImp();
150   /** \brief . */
151   char* getCharBuffer() const;
152   /** \brief . */
153   Ordinal getBytes() const;
154   /** \brief . */
155   const ArrayView<char> getCharBufferView() const;
156 private:
157   Ordinal    count_;
158   T          *buffer_;
159   Ordinal    bytes_;
160   char       *charBuffer_;
161   RCP<const Serializer> serializer_;
162   // Not defined and not to be called
163   ValueTypeSerializationBufferImp();
164   ValueTypeSerializationBufferImp(const ValueTypeSerializationBufferImp&);
165   ValueTypeSerializationBufferImp& operator=(const ValueTypeSerializationBufferImp&);
166 };
167 
168 /** \brief Encapsulate how an array of const objects with value sematics is
169  * serialized into a <tt>const char[]</tt> array.
170  *
171  * Specialization for direct serialization.
172  */
173 template <typename Ordinal, typename T, typename Serializer>
174 class ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,true> {
175 public:
176   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
177   ConstValueTypeSerializationBufferImp(
178     const Ordinal count, const T buffer[],
179     const RCP<const Serializer>& serializer
180     );
181   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
182    * original <tt>T[]</tt> buffer.
183    */
184   ~ConstValueTypeSerializationBufferImp();
185   /** \brief . */
186   const char* getCharBuffer() const;
187   /** \brief . */
188   Ordinal getBytes() const;
189   /** \brief . */
190   const ArrayView<const char> getCharBufferView() const;
191 private:
192   Ordinal    count_;
193   const T    *buffer_;
194   Ordinal    bytes_;
195   const char *charBuffer_;
196   RCP<const Serializer> serializer_;
197   // Not defined and not to be called
198   ConstValueTypeSerializationBufferImp();
199   ConstValueTypeSerializationBufferImp(const ConstValueTypeSerializationBufferImp&);
200   ConstValueTypeSerializationBufferImp& operator=(const ConstValueTypeSerializationBufferImp&);
201 };
202 
203 /** \brief Encapsulate how an array of non-const serialized objects with value
204  * sematics stored in a <tt>char[]</tt> array is deserialized to a
205  * <tt>T[]</tt> array and then serialized back again.
206  *
207  * Specialization for direct serialization.
208  */
209 template <typename Ordinal, typename T, typename Serializer>
210 class ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true> {
211 public:
212   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
213   ValueTypeDeserializationBufferImp(
214     const Ordinal bytes, char charBuffer[],
215     const RCP<const Serializer>& serializer
216     );
217   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
218    * original <tt>T[]</tt> buffer.
219    */
220   ~ValueTypeDeserializationBufferImp();
221   /** \brief . */
222   T* getBuffer() const;
223   /** \brief . */
224   Ordinal getCount() const;
225 private:
226   Ordinal    bytes_;
227   char       *charBuffer_;
228   Ordinal    count_;
229   T          *buffer_;
230   RCP<const Serializer> serializer_;
231   // Not defined and not to be called
232   ValueTypeDeserializationBufferImp();
233   ValueTypeDeserializationBufferImp(const ValueTypeDeserializationBufferImp&);
234   ValueTypeDeserializationBufferImp& operator=(const ValueTypeDeserializationBufferImp&);
235 };
236 
237 /** \brief Encapsulate how an array of non-const serialized objects with value
238  * sematics stored in a <tt>char[]</tt> array is deserialized to a
239  * <tt>T[]</tt> array and then serialized back again.
240  *
241  * Specialization for direct serialization.
242  */
243 template <typename Ordinal, typename T, typename Serializer>
244 class ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true> {
245 public:
246   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
247   ConstValueTypeDeserializationBufferImp(
248     const Ordinal bytes, const char charBuffer[],
249     const RCP<const Serializer>& serializer
250     );
251   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
252    * original <tt>T[]</tt> buffer.
253    */
254   ~ConstValueTypeDeserializationBufferImp();
255   /** \brief . */
256   const T* getBuffer() const;
257   /** \brief . */
258   Ordinal getCount() const;
259 private:
260   Ordinal    bytes_;
261   const char *charBuffer_;
262   Ordinal    count_;
263   const T    *buffer_;
264   RCP<const Serializer> serializer_;
265   // Not defined and not to be called
266   ConstValueTypeDeserializationBufferImp();
267   ConstValueTypeDeserializationBufferImp(const ConstValueTypeDeserializationBufferImp&);
268   ConstValueTypeDeserializationBufferImp& operator=(const ConstValueTypeDeserializationBufferImp&);
269 };
270 
271 /** \brief Encapsulate how an array of non-const objects with value sematics
272  * is serialized into a <tt>char[]</tt> array.
273  *
274  * Specialization for indirect serialization
275  */
276 template <typename Ordinal, typename T, typename Serializer>
277 class ValueTypeSerializationBufferImp<Ordinal,T,Serializer,false> {
278 public:
279   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
280   ValueTypeSerializationBufferImp(
281     const Ordinal count, T buffer[],
282     const RCP<const Serializer>& serializer
283     );
284   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
285    * original <tt>T[]</tt> buffer.
286    */
287   ~ValueTypeSerializationBufferImp();
288   /** \brief . */
289   char* getCharBuffer() const;
290   /** \brief . */
291   Ordinal getBytes() const;
292   /** \brief . */
293   const ArrayView<char> getCharBufferView() const;
294 private:
295   Ordinal    count_;
296   T          *buffer_;
297   Ordinal    bytes_;
298   mutable Array<char> charBuffer_;
299   RCP<const Serializer> serializer_;
300   // Not defined and not to be called
301   ValueTypeSerializationBufferImp();
302   ValueTypeSerializationBufferImp(const ValueTypeSerializationBufferImp&);
303   ValueTypeSerializationBufferImp& operator=(const ValueTypeSerializationBufferImp&);
304 };
305 
306 /** \brief Encapsulate how an array of const objects with value sematics is
307  * serialized into a <tt>const char[]</tt> array.
308  *
309  * Specialization for indirect serialization
310  */
311 template <typename Ordinal, typename T, typename Serializer>
312 class ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,false> {
313 public:
314   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
315   ConstValueTypeSerializationBufferImp(
316     const Ordinal count, const T buffer[],
317     const RCP<const Serializer>& serializer
318     );
319   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
320    * original <tt>T[]</tt> buffer.
321    */
322   ~ConstValueTypeSerializationBufferImp();
323   /** \brief . */
324   const char* getCharBuffer() const;
325   /** \brief . */
326   Ordinal getBytes() const;
327   /** \brief . */
328   const ArrayView<const char> getCharBufferView() const;
329 private:
330   Ordinal    count_;
331   const T    *buffer_;
332   Ordinal    bytes_;
333   Array<char> charBuffer_;
334   RCP<const Serializer> serializer_;
335   // Not defined and not to be called
336   ConstValueTypeSerializationBufferImp();
337   ConstValueTypeSerializationBufferImp(const ConstValueTypeSerializationBufferImp&);
338   ConstValueTypeSerializationBufferImp& operator=(const ConstValueTypeSerializationBufferImp&);
339 };
340 
341 /** \brief Encapsulate how an array of non-const serialized objects with value
342  * sematics stored in a <tt>char[]</tt> array is deserialized to a
343  * <tt>T[]</tt> array and then serialized back again.
344  *
345  * Specialization for indirect serialization
346  */
347 template <typename Ordinal, typename T, typename Serializer>
348 class ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false> {
349 public:
350   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
351   ValueTypeDeserializationBufferImp(
352     const Ordinal bytes, char charBuffer[],
353     const RCP<const Serializer>& serializer
354     );
355   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
356    * original <tt>T[]</tt> buffer.
357    */
358   ~ValueTypeDeserializationBufferImp();
359   /** \brief . */
360   T* getBuffer() const;
361   /** \brief . */
362   Ordinal getCount() const;
363 private:
364   Ordinal    bytes_;
365   char       *charBuffer_;
366   Ordinal    count_;
367   mutable Array<T>   buffer_;
368   RCP<const Serializer> serializer_;
369   // Not defined and not to be called
370   ValueTypeDeserializationBufferImp();
371   ValueTypeDeserializationBufferImp(const ValueTypeDeserializationBufferImp&);
372   ValueTypeDeserializationBufferImp& operator=(const ValueTypeDeserializationBufferImp&);
373 };
374 
375 /** \brief Encapsulate how an array of non-const serialized objects with value
376  * sematics stored in a <tt>char[]</tt> array is deserialized to a
377  * <tt>T[]</tt> array and then serialized back again.
378  *
379  * Specialization for indirect serialization
380  */
381 template <typename Ordinal, typename T, typename Serializer>
382 class ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false> {
383 public:
384   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
385   ConstValueTypeDeserializationBufferImp(
386     const Ordinal bytes, const char charBuffer[],
387     const RCP<const Serializer>& serializer
388     );
389   /** \brief Deserialize from the interal <tt>char[]</tt> buffer back to the
390    * original <tt>T[]</tt> buffer.
391    */
392   ~ConstValueTypeDeserializationBufferImp();
393   /** \brief . */
394   const T* getBuffer() const;
395   /** \brief . */
396   Ordinal getCount() const;
397 private:
398   Ordinal    bytes_;
399   const char *charBuffer_;
400   Ordinal    count_;
401   Array<T>   buffer_;
402   RCP<const Serializer> serializer_;
403   // Not defined and not to be called
404   ConstValueTypeDeserializationBufferImp();
405   ConstValueTypeDeserializationBufferImp(const ConstValueTypeDeserializationBufferImp&);
406   ConstValueTypeDeserializationBufferImp& operator=(const ConstValueTypeDeserializationBufferImp&);
407 };
408 
409 
410 /** \brief Encapsulate how an array of non-const objects with value sematics
411  * is serialized into a <tt>char[]</tt> array.
412  */
413 template <typename Ordinal, typename T,
414           typename Serializer = typename DefaultSerializer<Ordinal,T>::DefaultSerializerType>
415 class ValueTypeSerializationBuffer :
416     public ValueTypeSerializationBufferImp<Ordinal,T,Serializer> {
417 public:
418   typedef ValueTypeSerializationBufferImp<Ordinal,T,Serializer> Base;
419   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ValueTypeSerializationBuffer(const Ordinal count,T buffer[],const RCP<const Serializer> & serializer)420   ValueTypeSerializationBuffer(
421     const Ordinal count, T buffer[],
422     const RCP<const Serializer>& serializer
423     ) : Base(count,buffer,serializer) {}
424 };
425 
426 /** \brief Encapsulate how an array of const objects with value sematics is
427  * serialized into a <tt>const char[]</tt> array.
428  */
429 template <typename Ordinal, typename T,
430           typename Serializer = typename DefaultSerializer<Ordinal,T>::DefaultSerializerType>
431 class ConstValueTypeSerializationBuffer :
432     public ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer> {
433 public:
434   typedef ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer> Base;
435   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ConstValueTypeSerializationBuffer(const Ordinal count,const T buffer[],const RCP<const Serializer> & serializer)436   ConstValueTypeSerializationBuffer(
437     const Ordinal count, const T buffer[],
438     const RCP<const Serializer>& serializer
439     ) : Base(count,buffer,serializer) {}
440 };
441 
442 /** \brief Encapsulate how an array of non-const serialized objects with value
443  * sematics stored in a <tt>char[]</tt> array is deserialized to a
444  * <tt>T[]</tt> array and then serialized back again.
445  */
446 template <typename Ordinal, typename T,
447           typename Serializer = typename DefaultSerializer<Ordinal,T>::DefaultSerializerType>
448 class ValueTypeDeserializationBuffer :
449     public ValueTypeDeserializationBufferImp<Ordinal,T,Serializer> {
450 public:
451   typedef ValueTypeDeserializationBufferImp<Ordinal,T,Serializer> Base;
452   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ValueTypeDeserializationBuffer(const Ordinal bytes,char charBuffer[],const RCP<const Serializer> & serializer)453   ValueTypeDeserializationBuffer(
454     const Ordinal bytes, char charBuffer[],
455     const RCP<const Serializer>& serializer
456     ) : Base(bytes,charBuffer,serializer) {}
457 };
458 
459 /** \brief Encapsulate how an array of non-const serialized objects with value
460  * sematics stored in a <tt>char[]</tt> array is deserialized to a
461  * <tt>T[]</tt> array and then serialized back again.
462  */
463 template <typename Ordinal, typename T,
464           typename Serializer = typename DefaultSerializer<Ordinal,T>::DefaultSerializerType>
465 class ConstValueTypeDeserializationBuffer :
466     public ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer> {
467 public:
468   typedef ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer> Base;
469   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ConstValueTypeDeserializationBuffer(const Ordinal bytes,const char charBuffer[],const RCP<const Serializer> & serializer)470   ConstValueTypeDeserializationBuffer(
471     const Ordinal bytes, const char charBuffer[],
472     const RCP<const Serializer>& serializer
473     ) : Base(bytes,charBuffer,serializer) {}
474 };
475 
476 /** \brief Encapsulate how an array of non-const objects with value sematics
477  * is serialized into a <tt>char[]</tt> array.
478  *
479  * Specialization for the default serializer object type with a default
480  * argument for the serializer object parameter.
481  */
482 template <typename Ordinal, typename T>
483 class ValueTypeSerializationBuffer<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> :
484     public ValueTypeSerializationBufferImp<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> {
485 public:
486   typedef DefaultSerializer<Ordinal,T> DS;  // work around for parsing bug in gcc 4.1-4.2
487   typedef typename DS::DefaultSerializerType Serializer;
488   typedef ValueTypeSerializationBufferImp<Ordinal,T,Serializer> Base;
489   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ValueTypeSerializationBuffer(const Ordinal count,T buffer[],const RCP<const Serializer> & serializer=DS::getDefaultSerializerRCP ())490   ValueTypeSerializationBuffer(
491     const Ordinal count, T buffer[],
492     const RCP<const Serializer>& serializer = DS::getDefaultSerializerRCP()
493     ) : Base(count,buffer,serializer) {}
494 };
495 
496 /** \brief Encapsulate how an array of const objects with value sematics is
497  * serialized into a <tt>const char[]</tt> array.
498  *
499  * Specialization for the default serializer object type with a default
500  * argument for the serializer object parameter.
501  */
502 template <typename Ordinal, typename T>
503 class ConstValueTypeSerializationBuffer<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> :
504     public ConstValueTypeSerializationBufferImp<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> {
505 public:
506   typedef DefaultSerializer<Ordinal,T> DS;  // work around for parsing bug in gcc 4.1-4.2
507   typedef typename DS::DefaultSerializerType Serializer;
508   typedef ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer> Base;
509   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ConstValueTypeSerializationBuffer(const Ordinal count,const T buffer[],const RCP<const Serializer> & serializer=DS::getDefaultSerializerRCP ())510   ConstValueTypeSerializationBuffer(
511     const Ordinal count, const T buffer[],
512     const RCP<const Serializer>& serializer = DS::getDefaultSerializerRCP()
513     ) : Base(count,buffer,serializer) {}
514 };
515 
516 /** \brief Encapsulate how an array of non-const serialized objects with value
517  * sematics stored in a <tt>char[]</tt> array is deserialized to a
518  * <tt>T[]</tt> array and then serialized back again.
519  *
520  * Specialization for the default serializer object type with a default
521  * argument for the serializer object parameter.
522  */
523 template <typename Ordinal, typename T>
524 class ValueTypeDeserializationBuffer<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> :
525     public ValueTypeDeserializationBufferImp<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> {
526 public:
527   typedef DefaultSerializer<Ordinal,T> DS;  // work around for parsing bug in gcc 4.1-4.2
528   typedef typename DS::DefaultSerializerType Serializer;
529   typedef ValueTypeDeserializationBufferImp<Ordinal,T,Serializer> Base;
530   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ValueTypeDeserializationBuffer(const Ordinal bytes,char charBuffer[],const RCP<const Serializer> & serializer=DS::getDefaultSerializerRCP ())531   ValueTypeDeserializationBuffer(
532     const Ordinal bytes, char charBuffer[],
533     const RCP<const Serializer>& serializer = DS::getDefaultSerializerRCP()
534     ) : Base(bytes,charBuffer,serializer) {}
535 };
536 
537 /** \brief Encapsulate how an array of non-const serialized objects with value
538  * sematics stored in a <tt>char[]</tt> array is deserialized to a
539  * <tt>T[]</tt> array and then serialized back again.
540  *
541  * Specialization for the default serializer object type with a default
542  * argument for the serializer object parameter.
543  */
544 template <typename Ordinal, typename T>
545 class ConstValueTypeDeserializationBuffer<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> :
546     public ConstValueTypeDeserializationBufferImp<Ordinal,T,typename DefaultSerializer<Ordinal,T>::DefaultSerializerType> {
547 public:
548   typedef DefaultSerializer<Ordinal,T> DS;  // work around for parsing bug in gcc 4.1-4.2
549   typedef typename DS::DefaultSerializerType Serializer;
550   typedef ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer> Base;
551   /** \brief Serialize to an internally stored <tt>char[]</tt> buffer. */
ConstValueTypeDeserializationBuffer(const Ordinal bytes,const char charBuffer[],const RCP<const Serializer> & serializer=DS::getDefaultSerializerRCP ())552   ConstValueTypeDeserializationBuffer(
553     const Ordinal bytes, const char charBuffer[],
554     const RCP<const Serializer>& serializer = DS::getDefaultSerializerRCP()
555     ) : Base(bytes,charBuffer,serializer) {}
556 };
557 
558 // /////////////////////////////////////
559 // Template implementations for direct serialization
560 
561 //
562 // ValueTypeSerializationBufferImp
563 //
564 
565 template <typename Ordinal, typename T, typename Serializer>
566 ValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
ValueTypeSerializationBufferImp(const Ordinal count,T buffer[],const RCP<const Serializer> & serializer)567 ValueTypeSerializationBufferImp(
568   const Ordinal count, T buffer[], const RCP<const Serializer>& serializer
569   )
570   :count_(count), buffer_(buffer), serializer_(serializer)
571 {
572   bytes_ = serializer_->fromCountToDirectBytes(count_);
573   charBuffer_ = serializer_->convertToCharPtr(buffer_);
574 }
575 
576 template <typename Ordinal, typename T, typename Serializer>
577 ValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
~ValueTypeSerializationBufferImp()578 ~ValueTypeSerializationBufferImp()
579 {
580   // There is nothing to do since the type uses direct serialization!
581 }
582 
583 template <typename Ordinal, typename T, typename Serializer>
584 char* ValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
getCharBuffer() const585 getCharBuffer() const
586 {
587   return charBuffer_;
588 }
589 
590 template <typename Ordinal, typename T, typename Serializer>
591 Ordinal ValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
592 getBytes() const
593 {
594   return bytes_;
595 }
596 
597 
598 template <typename Ordinal, typename T, typename Serializer>
599 const ArrayView<char>
600 ValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
getCharBufferView() const601 getCharBufferView() const
602 {
603   return arrayView(charBuffer_, bytes_);
604 }
605 
606 
607 //
608 // ConstValueTypeSerializationBufferImp
609 //
610 
611 template <typename Ordinal, typename T, typename Serializer>
612 ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
ConstValueTypeSerializationBufferImp(const Ordinal count,const T buffer[],const RCP<const Serializer> & serializer)613 ConstValueTypeSerializationBufferImp(
614   const Ordinal count, const T buffer[], const RCP<const Serializer>& serializer
615   )
616   :count_(count), buffer_(buffer), serializer_(serializer)
617 {
618   bytes_ = serializer_->fromCountToDirectBytes(count_);
619   charBuffer_ = serializer_->convertToCharPtr(buffer_);
620 }
621 
622 template <typename Ordinal, typename T, typename Serializer>
623 ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
~ConstValueTypeSerializationBufferImp()624 ~ConstValueTypeSerializationBufferImp()
625 {
626   // There is nothing to do since the type uses direct serialization!
627 }
628 
629 template <typename Ordinal, typename T, typename Serializer>
630 const char* ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
getCharBuffer() const631 getCharBuffer() const
632 {
633   return charBuffer_;
634 }
635 
636 template <typename Ordinal, typename T, typename Serializer>
637 Ordinal ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
638 getBytes() const
639 {
640   return bytes_;
641 }
642 
643 template <typename Ordinal, typename T, typename Serializer>
644 const ArrayView<const char>
645 ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,true>::
getCharBufferView() const646 getCharBufferView() const
647 {
648   return arrayView(charBuffer_, bytes_);
649 }
650 
651 //
652 // ValueTypeDeserializationBufferImp
653 //
654 
655 template <typename Ordinal, typename T, typename Serializer>
656 ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
ValueTypeDeserializationBufferImp(const Ordinal bytes,char charBuffer[],const RCP<const Serializer> & serializer)657 ValueTypeDeserializationBufferImp(
658   const Ordinal bytes, char charBuffer[], const RCP<const Serializer>& serializer
659   )
660   :bytes_(bytes), charBuffer_(charBuffer), serializer_(serializer)
661 {
662   count_ = serializer_->fromDirectBytesToCount(bytes_);
663   buffer_ = serializer_->convertFromCharPtr(charBuffer_);
664 }
665 
666 template <typename Ordinal, typename T, typename Serializer>
667 ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
~ValueTypeDeserializationBufferImp()668 ~ValueTypeDeserializationBufferImp()
669 {
670   // There is nothing to do since the type uses direct serialization!
671 }
672 
673 template <typename Ordinal, typename T, typename Serializer>
674 T* ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
675 getBuffer() const
676 {
677   return buffer_;
678 }
679 
680 template <typename Ordinal, typename T, typename Serializer>
681 Ordinal ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
682 getCount() const
683 {
684   return count_;
685 }
686 
687 //
688 // ConstValueTypeDeserializationBufferImp
689 //
690 
691 template <typename Ordinal, typename T, typename Serializer>
692 ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
ConstValueTypeDeserializationBufferImp(const Ordinal bytes,const char charBuffer[],const RCP<const Serializer> & serializer)693 ConstValueTypeDeserializationBufferImp(
694   const Ordinal bytes, const char charBuffer[], const RCP<const Serializer>& serializer
695   )
696   :bytes_(bytes), charBuffer_(charBuffer), serializer_(serializer)
697 {
698   count_ = serializer_->fromDirectBytesToCount(bytes_);
699   buffer_ = serializer_->convertFromCharPtr(charBuffer_);
700 }
701 
702 template <typename Ordinal, typename T, typename Serializer>
703 ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
~ConstValueTypeDeserializationBufferImp()704 ~ConstValueTypeDeserializationBufferImp()
705 {
706   // There is nothing to do since the type uses direct serialization!
707 }
708 
709 template <typename Ordinal, typename T, typename Serializer>
710 const T* ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
getBuffer() const711 getBuffer() const
712 {
713   return buffer_;
714 }
715 
716 template <typename Ordinal, typename T, typename Serializer>
717 Ordinal ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,true>::
718 getCount() const
719 {
720   return count_;
721 }
722 
723 
724 // /////////////////////////////////////
725 // Template implementations for indirect specializations
726 
727 //
728 // ValueTypeSerializationBufferImp
729 //
730 
731 template <typename Ordinal, typename T, typename Serializer>
732 ValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
ValueTypeSerializationBufferImp(const Ordinal count,T buffer[],const RCP<const Serializer> & serializer)733 ValueTypeSerializationBufferImp(
734   const Ordinal count, T buffer[], const RCP<const Serializer>& serializer
735   )
736   :count_(count), buffer_(buffer), serializer_(serializer)
737 {
738   bytes_ = serializer_->fromCountToIndirectBytes(count_, buffer_);
739   charBuffer_.resize(bytes_);
740   serializer_->serialize(count_, buffer_, bytes_, &charBuffer_[0]);
741 }
742 
743 template <typename Ordinal, typename T, typename Serializer>
744 ValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
~ValueTypeSerializationBufferImp()745 ~ValueTypeSerializationBufferImp()
746 {
747   serializer_->deserialize(bytes_, &charBuffer_[0], count_, buffer_);
748 }
749 
750 template <typename Ordinal, typename T, typename Serializer>
751 char* ValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
getCharBuffer() const752 getCharBuffer() const
753 {
754   return &charBuffer_[0];
755 }
756 
757 template <typename Ordinal, typename T, typename Serializer>
758 Ordinal ValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
759 getBytes() const
760 {
761   return bytes_;
762 }
763 
764 template <typename Ordinal, typename T, typename Serializer>
765 const ArrayView<char>
766 ValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
getCharBufferView() const767 getCharBufferView() const
768 {
769   return charBuffer_.view(0, bytes_);
770 }
771 
772 
773 //
774 // ConstValueTypeSerializationBufferImp
775 //
776 
777 template <typename Ordinal, typename T, typename Serializer>
778 ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
ConstValueTypeSerializationBufferImp(const Ordinal count,const T buffer[],const RCP<const Serializer> & serializer)779 ConstValueTypeSerializationBufferImp(
780   const Ordinal count, const T buffer[], const RCP<const Serializer>& serializer
781   )
782   :count_(count), buffer_(buffer), serializer_(serializer)
783 {
784   bytes_ = serializer_->fromCountToIndirectBytes(count_, buffer_);
785   charBuffer_.resize(bytes_);
786   serializer_->serialize(count_, buffer_, bytes_, &charBuffer_[0]);
787 }
788 
789 template <typename Ordinal, typename T, typename Serializer>
790 ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
~ConstValueTypeSerializationBufferImp()791 ~ConstValueTypeSerializationBufferImp()
792 {
793 }
794 
795 template <typename Ordinal, typename T, typename Serializer>
796 const char* ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
getCharBuffer() const797 getCharBuffer() const
798 {
799   return &charBuffer_[0];
800 }
801 
802 template <typename Ordinal, typename T, typename Serializer>
803 Ordinal ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
804 getBytes() const
805 {
806   return bytes_;
807 }
808 
809 template <typename Ordinal, typename T, typename Serializer>
810 const ArrayView<const char>
811 ConstValueTypeSerializationBufferImp<Ordinal,T,Serializer,false>::
getCharBufferView() const812 getCharBufferView() const
813 {
814   return charBuffer_.view(0, bytes_);
815 }
816 
817 //
818 // ValueTypeDeserializationBufferImp
819 //
820 
821 template <typename Ordinal, typename T, typename Serializer>
822 ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
ValueTypeDeserializationBufferImp(const Ordinal bytes,char charBuffer[],const RCP<const Serializer> & serializer)823 ValueTypeDeserializationBufferImp(
824   const Ordinal bytes, char charBuffer[], const RCP<const Serializer>& serializer
825   )
826   :bytes_(bytes), charBuffer_(charBuffer), serializer_(serializer)
827 {
828   count_ = serializer_->fromIndirectBytesToCount(bytes_, charBuffer_);
829   buffer_.resize(count_);
830   serializer_->deserialize(bytes_, charBuffer_, count_, &buffer_[0]);
831 }
832 
833 template <typename Ordinal, typename T, typename Serializer>
834 ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
~ValueTypeDeserializationBufferImp()835 ~ValueTypeDeserializationBufferImp()
836 {
837   serializer_->serialize(count_, &buffer_[0], bytes_, charBuffer_);
838 }
839 
840 template <typename Ordinal, typename T, typename Serializer>
841 T* ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
842 getBuffer() const
843 {
844   return &buffer_[0];
845 }
846 
847 template <typename Ordinal, typename T, typename Serializer>
848 Ordinal ValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
849 getCount() const
850 {
851   return count_;
852 }
853 
854 //
855 // ConstValueTypeDeserializationBufferImp
856 //
857 
858 template <typename Ordinal, typename T, typename Serializer>
859 ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
ConstValueTypeDeserializationBufferImp(const Ordinal bytes,const char charBuffer[],const RCP<const Serializer> & serializer)860 ConstValueTypeDeserializationBufferImp(
861   const Ordinal bytes, const char charBuffer[], const RCP<const Serializer>& serializer
862   )
863   :bytes_(bytes), charBuffer_(charBuffer), serializer_(serializer)
864 {
865   count_ = serializer_->fromIndirectBytesToCount(bytes_, charBuffer_);
866   buffer_.resize(count_);
867   serializer_->deserialize(bytes_, charBuffer_, count_, &buffer_[0]);
868 }
869 
870 template <typename Ordinal, typename T, typename Serializer>
871 ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
~ConstValueTypeDeserializationBufferImp()872 ~ConstValueTypeDeserializationBufferImp()
873 {
874 }
875 
876 template <typename Ordinal, typename T, typename Serializer>
877 const T* ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
getBuffer() const878 getBuffer() const
879 {
880   return &buffer_[0];
881 }
882 
883 template <typename Ordinal, typename T, typename Serializer>
884 Ordinal ConstValueTypeDeserializationBufferImp<Ordinal,T,Serializer,false>::
885 getCount() const
886 {
887   return count_;
888 }
889 
890 } // namespace Teuchos
891 
892 #endif // TEUCHOS_SERIALIZATION_TRAITS_HELPERS_HPP
893