Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-05-18 08:29:46

0001 /*-
0002  * Copyright (c) 2009, 2020 Oracle and/or its affiliates.  All rights reserved.
0003  *
0004  * See the file LICENSE for license information.
0005  *
0006  * $Id$
0007  */
0008 
0009 #ifndef _DB_STL_KDPAIR_H
0010 #define _DB_STL_KDPAIR_H
0011 
0012 #include <iostream>
0013 
0014 #include "dbstl_common.h"
0015 #include "dbstl_dbt.h"
0016 #include "dbstl_exception.h"
0017 #include "dbstl_base_iterator.h"
0018 #include "dbstl_utility.h"
0019 
0020 START_NS(dbstl)
0021 
0022 using std::istream;
0023 using std::ostream;
0024 using std::basic_ostream;
0025 using std::basic_istream;
0026 
0027 template <Typename ddt>
0028 class db_base_iterator;
0029 template <Typename ddt>
0030 class ElementHolder;
0031 
0032 /** \ingroup dbstl_helper_classes
0033 \defgroup Element_wrappers ElementRef and ElementHolder wrappers.
0034 An ElementRef and ElementHolder object represents the reference to the 
0035 data element referenced by an iterator. Each iterator 
0036 object has an ElementRef or ElementHolder object that
0037 stores the data element that the iterator points to.
0038 
0039 The ElementHolder class is used to store primitive types into STL containers.
0040 
0041 The ElementRef class is used to store other types into STL containers.
0042 
0043 The ElementRef and ElementHolder classes have identical interfaces, and are
0044 treated the same by other STL classes. Since the ElementRef class inherits
0045 from the template data class, all methods have a _DB_STL_ prefix to avoid name
0046 clashes.
0047 
0048 An ElementRef or ElementHolder class corresponds to a single iterator instance.
0049 An Element object is generally owned by an iterator object. The ownership
0050 relationship is swapped in some specific situations, specifically for the 
0051 dereference and array index operator.
0052 @{
0053 */
0054 /// ElementRef element wrapper for classes and structures.
0055 /// \sa ElementHolder
0056 template <Typename ddt>
0057 class _exported ElementRef : public ddt
0058 {
0059 public:
0060     typedef ElementRef<ddt> self;
0061     typedef ddt base;
0062     typedef db_base_iterator<ddt> iterator_type;
0063     typedef ddt content_type; // Used by assoc classes.
0064 
0065 private:
0066     // The iterator pointing the data element stored in this object.
0067     iterator_type *_DB_STL_itr_;
0068 
0069     // Whether or not to delete itr on destruction, by default it is
0070     // false because this object is supposed to live in the lifetime of
0071     // its _DB_STL_itr_ owner. But there is one exception: in
0072     // db_vector<>::operator[]/front/back and db_map<>::operator[]
0073     // functions, an ElementRef<T> object has to be
0074     // returned instead of its reference, thus the
0075     // returned ElementRef<> has to live longer than its _DB_STL_itr_,
0076     // thus we new an iterator, and call _DB_STL_SetDelItr() method, 
0077     // setting this member to true,
0078     // to tell this object that it should delete the
0079     // _DB_STL_itr_ iterator on destruction, and duplicate the _DB_STL_itr_
0080     // iterator on copy construction. Although
0081     // std::vector<> returns reference rather than value, this is not a
0082     // problem because the returned ElementRef<> will duplicate cursor and
0083     // still points to the same key/data pair.
0084     //
0085     mutable bool _DB_STL_delete_itr_;
0086 
0087 public:
0088     ////////////////////////////////////////////////////////////////////
0089     //
0090     // Begin constructors and destructor.
0091     //
0092     /// \name Constructors and destructor.
0093     //@{
0094     /// Destructor.
0095     ~ElementRef() {
0096         if (_DB_STL_delete_itr_) {
0097             // Prevent recursive destruction.
0098             _DB_STL_delete_itr_ = false;
0099             _DB_STL_itr_->delete_me();
0100         }
0101     }
0102 
0103     /// Constructor.
0104     /// If the pitr parameter is NULL or the default value is used, the
0105     /// object created is a simple wrapper and not connected to a container.
0106     /// If a valid iterator parameter is passed in, the wrapped element will
0107     /// be associated with the matching key/data pair in the underlying
0108     /// container.
0109     /// \param pitr The iterator owning this object.
0110     explicit ElementRef(iterator_type *pitr = NULL)
0111     {
0112         _DB_STL_delete_itr_ = false;
0113         _DB_STL_itr_ = pitr;
0114     }
0115 
0116     /// Constructor.
0117     /// Initializes an ElementRef wrapper without an iterator. It can only
0118     /// be used to wrap a data element in memory, it can't access an
0119     /// unerlying database. 
0120     /// \param dt The base class object to initialize this object.
0121     ElementRef(const ddt &dt) : ddt(dt)
0122     {
0123         _DB_STL_delete_itr_ = false;
0124         _DB_STL_itr_ = NULL;
0125     }
0126 
0127     /// Copy constructor.
0128     /// The constructor takes a "deep" copy. The created object will be 
0129     /// identical to, but independent from the original object.
0130     /// \param other The object to clone from.
0131     ElementRef(const self &other) : ddt(other)
0132     {
0133         // Duplicate iterator if this object lives longer than
0134         // _DB_STL_itr_.
0135         _DB_STL_delete_itr_ = other._DB_STL_delete_itr_;
0136         if (_DB_STL_delete_itr_) {
0137             // Avoid recursive duplicate iterator calls.
0138             other._DB_STL_delete_itr_ = false;
0139             _DB_STL_itr_ = other._DB_STL_itr_->dup_itr();
0140             other._DB_STL_delete_itr_ = true;
0141         } else
0142             _DB_STL_itr_ = other._DB_STL_itr_;
0143     }
0144     //@}
0145     ////////////////////////////////////////////////////////////////////
0146 
0147     /// \name Assignment operators.
0148     /// The assignment operators are used to store right-values into the
0149     /// wrapped object, and also to store values into an underlying 
0150     /// container.
0151     //@{
0152     /// Assignment Operator.
0153     /// \param dt2 The data value to assign with.
0154     /// \return The object dt2's reference.
0155     inline const ddt& operator=(const ddt& dt2)
0156     {
0157         *((ddt*)this) = dt2;
0158         if (_DB_STL_itr_ != NULL) {
0159             if (!_DB_STL_itr_->is_set_iterator())
0160                 _DB_STL_itr_->replace_current(dt2);
0161             else
0162                 _DB_STL_itr_->replace_current_key(dt2);
0163         }
0164         return dt2;
0165     }
0166 
0167     /// Assignment Operator.
0168     /// \param me The object to assign with.
0169     /// \return The object me's reference.
0170     inline const self& operator=(const self& me)
0171     {
0172         ASSIGNMENT_PREDCOND(me)
0173         *((ddt*)this) = (ddt)me;
0174         if (_DB_STL_itr_ != NULL) {
0175             // This object is the reference of an valid data
0176             // element, so we must keep it that way, we don't
0177             // use me's iterator here.
0178             if (!_DB_STL_itr_->is_set_iterator())
0179                 _DB_STL_itr_->replace_current(
0180                     me._DB_STL_value());
0181             else
0182                 _DB_STL_itr_->replace_current_key(
0183                     me._DB_STL_value());
0184         } else if (me._DB_STL_delete_itr_) {
0185             // Duplicate an iterator from me.
0186             _DB_STL_delete_itr_ = true;
0187             me._DB_STL_delete_itr_ = false;
0188             _DB_STL_itr_ = me._DB_STL_itr_->dup_itr();
0189             me._DB_STL_delete_itr_ = true;
0190         }
0191 
0192         return me;
0193     }
0194     //@}
0195 
0196     /// Function to store the data element.
0197     /// The user needs to call this method after modifying the underlying
0198     /// object, so that the version stored in the container can be updated.
0199     /// 
0200     /// When db_base_iterator's directdb_get_ member is true, this function
0201     /// must be called after modifying the data member and before any
0202     /// subsequent container iterator dereference operations. If this step
0203     /// is not carried out any changes will be lost.
0204     ///
0205     /// If the data element is changed via ElementHolder<>::operator=(), 
0206     /// you don't need to call this function.
0207     inline void _DB_STL_StoreElement()
0208     {
0209         assert(_DB_STL_itr_ != NULL);
0210         _DB_STL_itr_->replace_current(*this);
0211     }
0212 
0213     /// Returns the data element this wrapper object wraps.
0214     inline const ddt& _DB_STL_value() const
0215     {
0216         return *((ddt*)this);
0217     }
0218 
0219     /// Returns the data element this wrapper object wraps.
0220     inline ddt& _DB_STL_value()
0221     {
0222         return *((ddt*)this);
0223     }
0224 
0225 #ifndef DOXYGEN_CANNOT_SEE_THIS
0226     ////////////////////////////////////////////////////////////////////
0227     //
0228     // The following methods are not part of the official public API,
0229     // but can't be declared as protected, since it is not possible
0230     // to declare template-specialised classes as friends.
0231     //
0232 
0233     // Call this function to tell this object that it should delete the
0234     // _DB_STL_itr_ iterator because that iterator was allocated in
0235     // the heap. Methods like db_vector/db_map<>::operator[] should call
0236     // this function.
0237     inline void _DB_STL_SetDelItr()
0238     {
0239         _DB_STL_delete_itr_ = true;
0240     }
0241 
0242     // Only copy data into this object, do not store into database.
0243     inline void _DB_STL_CopyData(const self&dt2)
0244     {
0245         *((ddt*)this) = (ddt)dt2;
0246     }
0247 
0248     inline void _DB_STL_CopyData(const ddt&dt2)
0249     {
0250         *((ddt*)this) = dt2;
0251     }
0252 
0253     // Following functions are prefixed with _DB_STL_ to avoid
0254     // potential name clash with ddt members.
0255     //
0256     inline iterator_type* _DB_STL_GetIterator() const
0257     {
0258            return _DB_STL_itr_;
0259     }
0260 
0261     inline int _DB_STL_GetData(ddt& d) const
0262     {
0263         d = *((ddt*)this);
0264         return 0;
0265     }
0266 
0267     inline void _DB_STL_SetIterator(iterator_type*pitr)
0268     {
0269         _DB_STL_itr_ = pitr;
0270     }
0271 
0272     inline void _DB_STL_SetData(const ddt&d)
0273     {
0274         *(ddt*)this = d;
0275     }
0276     ////////////////////////////////////////////////////////////////////
0277 
0278 }; // ElementRef<>
0279 template<typename T>
0280 class DbstlSeqWriter;
0281 #else
0282 };
0283 #endif // DOXYGEN_CANNOT_SEE_THIS
0284 
0285 
0286 // The ElementHolder class must have an identical public interface to 
0287 // the ElementRef class.
0288 /// A wrapper class for primitive types. It has identical usage and public 
0289 /// interface to the ElementRef class.
0290 /// \sa ElementRef. 
0291 template <typename ptype>
0292 class _exported ElementHolder
0293 {
0294 protected:
0295     typedef ElementHolder<ptype> self;
0296 
0297 
0298     inline void _DB_STL_put_new_value_to_db()
0299     {
0300         if (_DB_STL_itr_ != NULL) {
0301             if (!_DB_STL_itr_->is_set_iterator())
0302                 _DB_STL_itr_->replace_current(dbstl_my_value_);
0303             else
0304                 _DB_STL_itr_->replace_current_key(
0305                     dbstl_my_value_);
0306         }
0307     }
0308 
0309     inline void _DB_STL_put_new_value_to_db(const self &me)
0310     {
0311         if (_DB_STL_itr_ != NULL) {
0312             if (!_DB_STL_itr_->is_set_iterator())
0313                 _DB_STL_itr_->replace_current(dbstl_my_value_);
0314             else
0315                 _DB_STL_itr_->replace_current_key(
0316                     dbstl_my_value_);
0317         } else if (me._DB_STL_delete_itr_) {
0318             // Duplicate an iterator from me.
0319             _DB_STL_delete_itr_ = true;
0320             me._DB_STL_delete_itr_ = false;
0321             _DB_STL_itr_ = me._DB_STL_itr_->dup_itr();
0322             me._DB_STL_delete_itr_ = true;
0323         }
0324     }
0325 
0326 
0327 
0328 public:
0329     typedef ptype type1;
0330     typedef db_base_iterator<ptype> iterator_type;
0331     typedef ptype content_type;
0332 
0333     ////////////////////////////////////////////////////////////////////
0334     //
0335     // Begin constructors and destructor.
0336     //
0337     /// \name Constructors and destructor.
0338     //@{
0339     /// Constructor.
0340     /// If the pitr parameter is NULL or the default value is used, the
0341     /// object created is a simple wrapper and not connected to a container.
0342     /// If a valid iterator parameter is passed in, the wrapped element will
0343     /// be associated with the matching key/data pair in the underlying
0344     /// container.
0345     /// \param pitr The iterator owning this object.
0346     explicit inline ElementHolder(iterator_type* pitr = NULL)
0347     {
0348         _DB_STL_delete_itr_ = false;
0349         _DB_STL_itr_ = pitr;
0350         dbstl_str_buf_ = NULL;
0351         dbstl_str_buf_len_ = 0;
0352         memset(&dbstl_my_value_, 0, sizeof(dbstl_my_value_));
0353     }
0354 
0355     /// Constructor.
0356     /// Initializes an ElementRef wrapper without an iterator. It can only
0357     /// be used to wrap a data element in memory, it can't access an
0358     /// unerlying database. 
0359     /// \param dt The base class object to initialize this object.
0360     inline ElementHolder(const ptype&dt)
0361     {
0362         dbstl_str_buf_ = NULL;
0363         dbstl_str_buf_len_ = 0;
0364         _DB_STL_delete_itr_ = false;
0365         _DB_STL_itr_ = NULL;
0366         _DB_STL_CopyData_int(dt);
0367     }
0368 
0369     /// Copy constructor.
0370     /// The constructor takes a "deep" copy. The created object will be 
0371     /// identical to, but independent from the original object.
0372     /// \param other The object to clone from.
0373     inline ElementHolder(const self& other)
0374     {
0375         dbstl_str_buf_ = NULL;
0376         dbstl_str_buf_len_ = 0;
0377         _DB_STL_delete_itr_ = other._DB_STL_delete_itr_;
0378         _DB_STL_CopyData(other);
0379 
0380         // Duplicate iterator if this object lives longer than
0381         // _DB_STL_itr_.
0382         _DB_STL_delete_itr_ = other._DB_STL_delete_itr_;
0383         if (_DB_STL_delete_itr_) {
0384             // Avoid recursive duplicate iterator calls.
0385             other._DB_STL_delete_itr_ = false;
0386             _DB_STL_itr_ = other._DB_STL_itr_->dup_itr();
0387             other._DB_STL_delete_itr_ = true;
0388         } else
0389             _DB_STL_itr_ = other._DB_STL_itr_;
0390     }
0391 
0392     /// Destructor.
0393     ~ElementHolder() {
0394         if (_DB_STL_delete_itr_) {
0395             _DB_STL_delete_itr_ = false;
0396             _DB_STL_itr_->delete_me();
0397         }
0398         if (dbstl_str_buf_) {
0399             free(dbstl_str_buf_);
0400             dbstl_str_buf_ = NULL;
0401         }
0402     }
0403     //@}
0404     ////////////////////////////////////////////////////////////////////
0405 
0406     /// This operator is a type converter. Where an automatic type 
0407     /// conversion is needed, this function is called to convert this 
0408     /// object into the primitive type it wraps.
0409     operator ptype () const
0410     {
0411         return dbstl_my_value_;
0412     }
0413 
0414     // ElementHolder is a wrapper for primitive types, and backed by db,
0415     // so we need to override all assignment operations to store updated
0416     // value to database. We don't need to implement other operators for
0417     // primitive types because we have a convert operator which can
0418     // automatically convert to primitive type and use its C++ built in
0419     // operator.
0420     //
0421     /** \name Math operators.
0422     ElementHolder class templates also have all C/C++ self mutating 
0423     operators for numeric primitive types, including:
0424     +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=, ++, --
0425     These operators should not be used when ddt is a sequence pointer type
0426     like char* or wchar_t* or T*, otherwise the behavior is undefined. 
0427     These methods exist only to override default bahavior to store the 
0428     new updated value, otherwise, the type convert operator could have 
0429     done all the job.
0430     As you know, some of them are not applicable to float or double types 
0431     or ElementHolder wrapper types for float/double types. 
0432     These operators not only modifies the cached data element, but also 
0433     stores new value to database if it associates a database key/data pair.
0434     @{
0435     */
0436     template <Typename T2>
0437     const self& operator +=(const ElementHolder<T2> &p2)
0438     {
0439         dbstl_my_value_ += p2.dbstl_my_value_;
0440         _DB_STL_put_new_value_to_db(p2);
0441         return *this;
0442     }
0443 
0444     template <Typename T2>
0445     const self& operator -=(const ElementHolder<T2> &p2)
0446     {
0447         dbstl_my_value_ -= p2.dbstl_my_value_;
0448         _DB_STL_put_new_value_to_db(p2);
0449         return *this;
0450     }
0451     template <Typename T2>
0452     const self& operator *=(const ElementHolder<T2> &p2)
0453     {
0454         dbstl_my_value_ *= p2.dbstl_my_value_;
0455         _DB_STL_put_new_value_to_db(p2);
0456         return *this;
0457     }
0458     template <Typename T2>
0459     const self& operator /=(const ElementHolder<T2> &p2)
0460     {
0461         dbstl_my_value_ /= p2.dbstl_my_value_;
0462         _DB_STL_put_new_value_to_db(p2);
0463         return *this;
0464     }
0465     template <Typename T2>
0466     const self& operator %=(const ElementHolder<T2> &p2)
0467     {
0468         dbstl_my_value_ %= p2.dbstl_my_value_;
0469         _DB_STL_put_new_value_to_db(p2);
0470         return *this;
0471     }
0472 
0473     template <Typename T2>
0474     const self& operator &=(const ElementHolder<T2> &p2)
0475     {
0476         dbstl_my_value_ &= p2.dbstl_my_value_;
0477         _DB_STL_put_new_value_to_db(p2);
0478         return *this;
0479     }
0480     template <Typename T2>
0481     const self& operator |=(const ElementHolder<T2> &p2)
0482     {
0483         dbstl_my_value_ |= p2.dbstl_my_value_;
0484         _DB_STL_put_new_value_to_db(p2);
0485         return *this;
0486     }
0487     template <Typename T2>
0488     const self& operator ^=(const ElementHolder<T2> &p2)
0489     {
0490         dbstl_my_value_ ^= p2.dbstl_my_value_;
0491         _DB_STL_put_new_value_to_db(p2);
0492         return *this;
0493     }
0494 
0495     const self& operator >>=(size_t n)
0496     {
0497         dbstl_my_value_ >>= n;
0498         _DB_STL_put_new_value_to_db();
0499         return *this;
0500     }
0501 
0502     const self& operator <<=(size_t n)
0503     {
0504         dbstl_my_value_ <<= n;
0505         _DB_STL_put_new_value_to_db();
0506         return *this;
0507     }
0508 
0509     const self& operator ^=(const self &p2)
0510     {
0511         dbstl_my_value_ ^= p2.dbstl_my_value_;
0512         _DB_STL_put_new_value_to_db();
0513         return *this;
0514     }
0515 
0516     const self& operator &=(const self &p2)
0517     {
0518         dbstl_my_value_ &= p2.dbstl_my_value_;
0519         _DB_STL_put_new_value_to_db();
0520         return *this;
0521     }
0522 
0523     const self& operator |=(const self &p2)
0524     {
0525         dbstl_my_value_ |= p2.dbstl_my_value_;
0526         _DB_STL_put_new_value_to_db();
0527         return *this;
0528     }
0529 
0530     const self& operator %=(const self &p2)
0531     {
0532         dbstl_my_value_ %= p2.dbstl_my_value_;
0533         _DB_STL_put_new_value_to_db();
0534         return *this;
0535     }
0536 
0537     const self& operator +=(const self &p2)
0538     {
0539         dbstl_my_value_ += p2.dbstl_my_value_;
0540         _DB_STL_put_new_value_to_db();
0541         return *this;
0542     }
0543     const self& operator -=(const self &p2)
0544     {
0545         dbstl_my_value_ -= p2.dbstl_my_value_;
0546         _DB_STL_put_new_value_to_db();
0547         return *this;
0548     }
0549     const self& operator /=(const self &p2)
0550     {
0551         dbstl_my_value_ /= p2.dbstl_my_value_;
0552         _DB_STL_put_new_value_to_db();
0553         return *this;
0554     }
0555     const self& operator *=(const self &p2)
0556     {
0557         dbstl_my_value_ *= p2.dbstl_my_value_;
0558         _DB_STL_put_new_value_to_db();
0559         return *this;
0560     }
0561 
0562     self& operator++()
0563     {
0564         dbstl_my_value_++;
0565         _DB_STL_put_new_value_to_db();
0566         return *this;
0567     }
0568 
0569     self operator++(int)
0570     {
0571         self obj(*this);
0572         dbstl_my_value_++;
0573         _DB_STL_put_new_value_to_db();
0574         return obj;
0575     }
0576 
0577     self& operator--()
0578     {
0579         dbstl_my_value_--;
0580         _DB_STL_put_new_value_to_db();
0581         return *this;
0582     }
0583 
0584     self operator--(int)
0585     {
0586         self obj(*this);
0587         dbstl_my_value_--;
0588         _DB_STL_put_new_value_to_db();
0589         return obj;
0590     }
0591 
0592     inline const ptype& operator=(const ptype& dt2)
0593     {
0594         _DB_STL_CopyData_int(dt2);
0595         _DB_STL_put_new_value_to_db();
0596         return dt2;
0597     }
0598 
0599     inline const self& operator=(const self& dt2)
0600     {
0601         ASSIGNMENT_PREDCOND(dt2)
0602         _DB_STL_CopyData(dt2);
0603         _DB_STL_put_new_value_to_db(dt2);
0604         return dt2;
0605     }
0606     //@}
0607     
0608     /// Returns the data element this wrapper object wraps;
0609     inline const ptype& _DB_STL_value() const
0610     {
0611         return dbstl_my_value_;
0612     }
0613 
0614     /// Returns the data element this wrapper object wraps;
0615     inline ptype&_DB_STL_value()
0616     {
0617         return dbstl_my_value_;
0618     }
0619     
0620     /// Function to store the data element.
0621     /// The user needs to call this method after modifying the underlying
0622     /// object, so that the version stored in the container can be updated.
0623     /// 
0624     /// When db_base_iterator's directdb_get_ member is true, this function
0625     /// must be called after modifying the data member and before any
0626     /// subsequent container iterator dereference operations. If this step
0627     /// is not carried out any changes will be lost.
0628     ///
0629     /// If the data element is changed via ElementHolder<>::operator=(), 
0630     /// you don't need to call this function.
0631     inline void _DB_STL_StoreElement()
0632     {
0633         assert(_DB_STL_itr_ != NULL);
0634         _DB_STL_itr_->replace_current(dbstl_my_value_);
0635     }
0636 
0637 #ifndef DOXYGEN_CANNOT_SEE_THIS
0638     ////////////////////////////////////////////////////////////////////
0639     //
0640     // The following methods are not part of the official public API,
0641     // but can't be declared as protected, since it is not possible
0642     // to declare template-specialised classes as friends.
0643     //
0644     inline void _DB_STL_CopyData(const self&dt2)
0645     {
0646         _DB_STL_CopyData_int(dt2.dbstl_my_value_);
0647     }
0648 
0649     template<Typename T>
0650     inline void _DB_STL_CopyData_int(const T&src)
0651     {
0652         dbstl_my_value_ = src;
0653     }
0654 
0655     // Try to catch all types of pointers.
0656     template<Typename T>
0657     inline void _DB_STL_CopyData_int(T* const &src)
0658     {
0659         DbstlSeqWriter<T>::copy_to_holder((ElementHolder<T *> *)this, 
0660             (T *)src);  
0661     }
0662 
0663     template<Typename T>
0664     inline void _DB_STL_CopyData_int(const T* const &src)
0665     {
0666         DbstlSeqWriter<T>::copy_to_holder((ElementHolder<T *> *)this, 
0667             (T *)src);  
0668     }
0669 
0670     template<Typename T>
0671     inline void _DB_STL_CopyData_int(T* &src)
0672     {
0673         DbstlSeqWriter<T>::copy_to_holder((ElementHolder<T *> *)this, 
0674             (T *)src);  
0675     }
0676 
0677     template<Typename T>
0678     inline void _DB_STL_CopyData_int(const T*&src)
0679     {
0680         DbstlSeqWriter<T>::copy_to_holder((ElementHolder<T *> *)this, 
0681             (T *)src);  
0682     }
0683 
0684     inline iterator_type* _DB_STL_GetIterator() const
0685     {
0686            return _DB_STL_itr_;
0687     }
0688 
0689     inline int _DB_STL_GetData(ptype& d) const
0690     {
0691         d = dbstl_my_value_;
0692         return 0;
0693     }
0694 
0695     inline void _DB_STL_SetIterator(iterator_type*pitr)
0696     {
0697         _DB_STL_itr_ = pitr;
0698     }
0699 
0700     inline void _DB_STL_SetData(const ptype&d)
0701     {
0702         _DB_STL_CopyData_int(d);
0703     }
0704 
0705     inline void _DB_STL_SetDelItr()
0706     {
0707         _DB_STL_delete_itr_ = true;
0708     }
0709 
0710     // The two member has to be public for DbstlSeqWriter to access, 
0711     // but can't be accessed by user. 
0712     size_t dbstl_str_buf_len_;
0713     void *dbstl_str_buf_; // Stores a sequence, used when ptype is T*
0714 
0715     iterator_type *_DB_STL_itr_;
0716     ptype dbstl_my_value_;
0717     mutable bool _DB_STL_delete_itr_;
0718 };
0719 #else
0720 };
0721 #endif // DOXYGEN_CANNOT_SEE_THIS
0722 //@} // Element_wrappers
0723 //@} //dbstl_helper_classes
0724 
0725 // These operators help reading from and writing to iostreams, if the wrapped
0726 // data type has iostream operators.
0727 template<Typename _CharT, Typename _Traits, Typename ddt>
0728 basic_istream<_CharT,_Traits>&
0729 operator>>( basic_istream<_CharT,_Traits> & in, ElementRef<ddt>&p)
0730 {
0731     in>>(ddt)p;
0732     return in;
0733 }
0734 
0735 template<Typename _CharT, Typename _Traits, Typename ddt>
0736 basic_ostream<_CharT,_Traits>&
0737 operator<<( basic_ostream<_CharT,_Traits> & out,
0738     const ElementRef<ddt>&p)
0739 {
0740     out<<(ddt)p;
0741     return out;
0742 }
0743 
0744 template<Typename _CharT, Typename _Traits, Typename ddt>
0745 basic_istream<_CharT,_Traits>&
0746 operator>>( basic_istream<_CharT,_Traits> & in, ElementHolder<ddt>&p)
0747 {
0748     in>>p._DB_STL_value();
0749     return in;
0750 }
0751 
0752 template<Typename _CharT, Typename _Traits, Typename ddt>
0753 basic_ostream<_CharT,_Traits>&
0754 operator<<( basic_ostream<_CharT,_Traits> & out,
0755     const ElementHolder<ddt>&p)
0756 {
0757     out<<p._DB_STL_value();
0758     return out;
0759 }
0760 
0761 template<typename T>
0762 class _exported DbstlSeqWriter
0763 {
0764 public:
0765     typedef ElementHolder<T *> HolderType;
0766     static void copy_to_holder(HolderType *holder, T *src)
0767     {
0768         size_t i, slen, sql;
0769 
0770         if (src == NULL) {
0771             free(holder->dbstl_str_buf_);
0772             holder->dbstl_str_buf_ = NULL;
0773             holder->dbstl_my_value_ = NULL;
0774             return;
0775         }
0776         if (holder->dbstl_str_buf_len_ > DBSTL_MAX_DATA_BUF_LEN) {
0777             free(holder->dbstl_str_buf_);
0778             holder->dbstl_str_buf_ = NULL;
0779         }
0780 
0781         typedef DbstlElemTraits<T> DM;
0782         typename DM::SequenceCopyFunct seqcpy =
0783             DM::instance()->get_sequence_copy_function();
0784         typename DM::SequenceLenFunct seqlen =
0785             DM::instance()->get_sequence_len_function();
0786         typename DM::ElemSizeFunct elemszf = 
0787             DM::instance()->get_size_function();
0788 
0789         assert(seqcpy != NULL && seqlen != NULL);
0790         sql = seqlen(src);
0791         if (elemszf == NULL)
0792             slen = sizeof(T) * (sql + 1);
0793         else
0794             // We don't add the terminating object if it has one.
0795             // So the registered functions should take care of it.
0796             for (slen = 0, i = 0; i < sql; i++)
0797                 slen += elemszf(src[i]);
0798 
0799         if (slen > holder->dbstl_str_buf_len_)
0800             holder->dbstl_str_buf_ = DbstlReAlloc(
0801                 holder->dbstl_str_buf_, 
0802                 holder->dbstl_str_buf_len_ = slen);
0803 
0804         seqcpy((T*)holder->dbstl_str_buf_, src, sql);
0805         holder->dbstl_my_value_ = (T*)holder->dbstl_str_buf_;
0806     }
0807 };
0808 
0809 template<>
0810 class _exported DbstlSeqWriter<char>
0811 {
0812 public:
0813     typedef ElementHolder<char *> HolderType;
0814     static void copy_to_holder(HolderType *holder, char *src)
0815     {
0816         size_t slen;
0817 
0818         if (src == NULL) {
0819             free(holder->dbstl_str_buf_);
0820             holder->dbstl_str_buf_ = NULL;
0821             holder->dbstl_my_value_ = NULL;
0822             return;
0823         }
0824         if (holder->dbstl_str_buf_len_ > DBSTL_MAX_DATA_BUF_LEN) {
0825             free(holder->dbstl_str_buf_);
0826             holder->dbstl_str_buf_ = NULL;
0827         }
0828 
0829         slen = sizeof(char) * (strlen(src) + 1);
0830         if (slen > holder->dbstl_str_buf_len_) {
0831             (u_int32_t)(holder->dbstl_str_buf_len_ = slen);
0832             holder->dbstl_str_buf_ = DbstlReAlloc(
0833                 holder->dbstl_str_buf_, 
0834                 slen);
0835         }
0836 
0837         strcpy((char*)holder->dbstl_str_buf_, src);
0838         holder->dbstl_my_value_ = (char*)holder->dbstl_str_buf_;
0839 
0840     }
0841 };
0842 
0843 template<>
0844 class _exported DbstlSeqWriter<wchar_t>
0845 {
0846 public:
0847     typedef ElementHolder<wchar_t *> HolderType;
0848     static void copy_to_holder(HolderType *holder, wchar_t *src)
0849     {
0850         size_t slen;
0851 
0852         if (src == NULL) {
0853             free(holder->dbstl_str_buf_);
0854             holder->dbstl_str_buf_ = NULL;
0855             holder->dbstl_my_value_ = NULL;
0856             return;
0857         }
0858         if (holder->dbstl_str_buf_len_ > DBSTL_MAX_DATA_BUF_LEN) {
0859             free(holder->dbstl_str_buf_);
0860             holder->dbstl_str_buf_ = NULL;
0861         }
0862 
0863         slen = sizeof(wchar_t) * (wcslen(src) + 1);
0864         if (slen > holder->dbstl_str_buf_len_) {
0865             holder->dbstl_str_buf_len_ = slen;
0866             holder->dbstl_str_buf_ = DbstlReAlloc(
0867                 holder->dbstl_str_buf_, 
0868                 slen);
0869         }
0870 
0871         wcscpy((wchar_t*)holder->dbstl_str_buf_, src);
0872         holder->dbstl_my_value_ = (wchar_t*)holder->dbstl_str_buf_;
0873     }
0874 };
0875 END_NS
0876 
0877 #endif// !_DB_STL_KDPAIR_H