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_DBT_H
0010 #define _DB_STL_DBT_H
0011 
0012 #include <assert.h>
0013 #include <string>
0014 
0015 #include "dbstl_common.h"
0016 #include "dbstl_exception.h"
0017 #include "dbstl_utility.h"
0018 
0019 //////////////////////////////////////////////////////////////////////////
0020 //////////////////////////////////////////////////////////////////////////
0021 //
0022 // DataItem class template definition
0023 //
0024 // 1. DataItem is a Dbt wrapper, it provides both typed data to/from memory
0025 // chunk mapping as well as iostream support. Note that iostream functionality
0026 // is not yet implemented.
0027 // 2. DataItem is used inside dbstl to provide consistent Dbt object memory
0028 // management.
0029 // 3. DataItem is not only capable of mapping fixed size objects, but also
0030 // varying length objects and objects not located in a consecutive chunk of
0031 // memory, with the condition that user configures the required methods in
0032 // DbstlElemTraits.
0033 // 4. DataItem can not be a class template because inside it, the "member
0034 // function template override" support is needed.
0035 //
0036 START_NS(dbstl)
0037 
0038 using std::string;
0039 #ifdef HAVE_WSTRING
0040 using std::wstring;
0041 #endif
0042 
0043 class DataItem
0044 {
0045 private:
0046     typedef DataItem self;
0047 
0048     ////////////////////////////////////////////////////////////////////
0049     ////////////////////////////////////////////////////////////////////
0050     //
0051     // DataItem memory management
0052     //
0053     // The dbt_ member is the current dbt, data is stored in the dbt's 
0054     // referenced memory, it may
0055     // deep copy from constructor and from other Dbt, depending on
0056     // the constructors "onstack" parameter --- if true, this object
0057     // is only used as a stack object inside a function,
0058     // so do shallow copy; otherwise do deep copy.
0059     // There is always a DB_DBT_USERMEM flag set to the dbt,
0060     // its ulen data member stores the length of referenced memory,
0061     // its size data member stores the actual size of data;
0062     // If onstack is true, its dlen is INVALID_DLEN, and freemem()
0063     // will not free such memory because this object only reference
0064     // other object's memory, its the referenced object's responsibility
0065     // to free their memory.
0066     //
0067     // A DataItem object is not used everywhere, so it is impossible for
0068     // such an object to have two kinds of usages as above at the same
0069     // time, so we are safe doing so.
0070     Dbt dbt_;
0071 
0072     // Free dbt_'s referenced memory if that memory is allocated in heap
0073     // and owned by dbt_.
0074     inline void freemem()
0075     {
0076         void *buf = dbt_.get_data();
0077 
0078         if (buf != NULL && (dbt_.get_flags() & DB_DBT_USERMEM) != 0
0079             && dbt_.get_dlen() != INVALID_DLEN)
0080             free(buf);
0081         memset(&dbt_, 0, sizeof(dbt_));
0082     }
0083 
0084 public:
0085 
0086     // Deep copy, because dbt2.data pointed memory may be short lived.
0087     inline void set_dbt(const DbstlDbt&dbt2, bool onstack)
0088     {
0089         void *buf;
0090         u_int32_t s1, s2;
0091         DBT *pdbt2, *pdbt;
0092            
0093         pdbt2 = (DBT *)&dbt2;
0094         pdbt = (DBT *)&dbt_;
0095 
0096         if (!onstack) {
0097             buf = pdbt->data;
0098             s1 = pdbt->ulen;
0099             s2 = pdbt2->size;
0100             if(s2 > s1) {
0101                 buf = DbstlReAlloc(buf, s2);
0102                 pdbt->size = s2;
0103                 pdbt->data = buf;
0104                 pdbt->ulen = s2;
0105                 pdbt->flags |= DB_DBT_USERMEM;
0106             } else
0107                 pdbt->size = s2;
0108             memcpy(buf, pdbt2->data, s2);
0109         } else {
0110             freemem();
0111             dbt_ = (const Dbt)dbt2;
0112             pdbt->dlen = (INVALID_DLEN);
0113         }
0114     }
0115 
0116     // Deep copy, because dbt2.data pointed memory may be short lived.
0117     inline void set_dbt(const Dbt&dbt2, bool onstack)
0118     {
0119         void *buf;
0120         u_int32_t s1, s2;
0121         DBT *pdbt2, *pdbt;
0122            
0123         pdbt2 = (DBT *)&dbt2;
0124         pdbt = (DBT *)&dbt_;
0125 
0126         if (!onstack) {
0127             buf = pdbt->data;
0128             s1 = pdbt->ulen;
0129             s2 = pdbt2->size;
0130             if(s2 > s1) {
0131                 buf = DbstlReAlloc(buf, s2);
0132                 pdbt->size = s2;
0133                 pdbt->data = buf;
0134                 pdbt->ulen = s2;
0135                 pdbt->flags |= DB_DBT_USERMEM;
0136             } else
0137                 pdbt->size = s2;
0138             memcpy(buf, pdbt2->data, s2);
0139         } else {
0140             freemem();
0141             dbt_ = dbt2;
0142             pdbt->dlen = (INVALID_DLEN);
0143         }
0144     }
0145 
0146     inline void set_dbt(const DBT&dbt2, bool onstack)
0147     {
0148         void *buf;
0149         u_int32_t s1, s2;
0150         DBT *pdbt = (DBT *)&dbt_;
0151 
0152         if (!onstack) {
0153             buf = pdbt->data;
0154             s1 = pdbt->ulen;
0155             s2 = dbt2.size;
0156             if(s2 > s1) {
0157                 buf = DbstlReAlloc(buf, s2);
0158                 pdbt->size = s2;
0159                 pdbt->data = buf;
0160                 pdbt->ulen = s2;
0161                 pdbt->flags |= DB_DBT_USERMEM;
0162             } else
0163                 pdbt->size = s2;
0164             memcpy(buf, dbt2.data, s2);
0165         } else {
0166             freemem();
0167             // The following is right because Dbt derives from
0168             // DBT with no extra members or any virtual functions.
0169             memcpy(&dbt_, &dbt2, sizeof(dbt2));
0170             pdbt->dlen = INVALID_DLEN;
0171         }
0172     }
0173 
0174     // Return to the initial state.
0175     inline void reset()
0176     {
0177         void *buf = dbt_.get_data();
0178         if (buf) {
0179             memset(buf, 0, dbt_.get_ulen());
0180             dbt_.set_size(0);
0181         }
0182     }
0183 
0184     inline Dbt& get_dbt()
0185     {
0186         return dbt_;
0187     }
0188 
0189     // Return data of this object. If no data return -1, if it has data
0190     // return 0.
0191     //
0192     // !!!XXX Note that the type parameter T can only be in this function
0193     // because "template type parameter overload" applies only to a
0194     // functions template argument list, rather than that of classes.
0195     // If you put the "template<Typename T>" to this class's declaration,
0196     // making it a class template, then when T is any of Dbt, DBT, or
0197     // DataItem<T>, there will be two copies of this function. One will be
0198     // this function's instantiated version, the other one is one of the
0199     // three functions defined below.
0200     //
0201     template <Typename T>
0202     inline int get_data(T& data) const
0203     {
0204         int ret;
0205         typedef DbstlElemTraits<T> EM;
0206         typename EM::ElemRstoreFunct restore;
0207         void *pdata = NULL;
0208 
0209         if ((pdata = dbt_.get_data()) != NULL) {
0210             if ((restore = EM::instance()->
0211                 get_restore_function()) != NULL)
0212                 restore(data, pdata);
0213             else
0214                 data = *((T*)pdata);
0215             ret = 0;
0216         } else
0217             ret = -1;
0218         return ret;
0219     }
0220 
0221     ////////////////////////////////////////////////////////////////////
0222     //
0223     // Begin functions supporting direct naked string storage.
0224     //
0225     // Always store the data, rather than the container object.
0226     //
0227     // The returned string lives no longer than the next iterator
0228     // movement call.
0229     //
0230     inline int get_data(char*& data) const
0231     {
0232         data = (char*)dbt_.get_data();
0233         return 0;
0234     }
0235 
0236     inline int get_data(string &data) const
0237     {
0238         data = (string::pointer) dbt_.get_data();
0239         return 0;
0240     }
0241 
0242     inline int get_data(wchar_t*& data) const
0243     {
0244         data = (wchar_t*)dbt_.get_data();
0245         return 0;
0246     }
0247 
0248 #ifdef HAVE_WSTRING
0249     inline int get_data(wstring &data) const
0250     {
0251         data = (wstring::pointer) dbt_.get_data();
0252         return 0;
0253     }
0254 #endif
0255 
0256     ////////////////////////////////////////////////////////////////////
0257 
0258     // Supporting storing arbitrary type of sequence.
0259     template <Typename T>
0260     inline int get_data(T*& data) const
0261     {
0262         data = (T*)dbt_.get_data();
0263         return 0;
0264     }
0265 
0266     inline int get_data(DataItem& data) const
0267     {
0268         int ret;
0269 
0270         if (dbt_.get_data()) {
0271             data.set_dbt(dbt_, false);
0272             ret = 0;
0273         } else
0274             ret = -1;
0275         return ret;
0276     }
0277 
0278     ////////////////////////////////////////////////////////////////////
0279     //
0280     // Begin functions supporting Dbt storage.
0281     //
0282     // This member function allows storing a Dbt type, so that user can
0283     // store the varying length data into Dbt.
0284     //
0285     // This method is required to copy a data element's bytes to another 
0286     // Dbt object, used inside by dbstl.
0287     // If there is no data return -1, if it has data return 0.
0288     //
0289     inline int get_data(Dbt& data) const
0290     {
0291         int ret;
0292         void *addr;
0293         u_int32_t sz;
0294         DBT *pdbt = (DBT *)&dbt_, *pdata = (DBT *)&data;
0295 
0296         if (pdbt->data) {
0297             addr = pdata->data;
0298             sz = pdbt->size;
0299             if (pdata->ulen < sz) {
0300                 pdata->data = DbstlReAlloc(addr, sz);
0301                 pdata->size = sz;
0302                 pdata->ulen = sz;
0303                 pdata->flags |= DB_DBT_USERMEM;
0304             } else
0305                 pdata->size = sz;
0306             memcpy(pdata->data, pdbt->data, sz);
0307             ret = 0;
0308         } else
0309             ret = -1;
0310         return ret;
0311     }
0312 
0313     inline int get_data(DBT& data) const
0314     {
0315         int ret;
0316         void*addr;
0317         u_int32_t sz;
0318 
0319         if (dbt_.get_data()) {
0320             addr = data.data;
0321             if (data.ulen < (sz = dbt_.get_size())) {
0322                 data.data = DbstlReAlloc(addr, sz);
0323                 // User need to free this memory
0324                 data.flags = data.flags | DB_DBT_USERMEM;
0325                 data.size = sz;
0326                 data.ulen = sz;
0327             } else
0328                 data.size = sz;
0329             memcpy(data.data, dbt_.get_data(), sz);
0330             ret = 0;
0331         } else
0332             ret = -1;
0333         return ret;
0334     }
0335 
0336     inline int get_data(DbstlDbt& data) const
0337     {
0338         int ret;
0339         void *addr;
0340         u_int32_t sz;
0341         DBT *pdbt = (DBT *)&dbt_, *pdata = (DBT *)&data;
0342 
0343         if (pdbt->data) {
0344             addr = pdata->data;
0345             sz = pdbt->size;
0346             if (pdata->ulen < sz) {
0347                 pdata->data = DbstlReAlloc(addr, sz);
0348                 pdata->size = sz;
0349                 pdata->ulen = sz;
0350                 pdata->flags |= DB_DBT_USERMEM;
0351             } else
0352                 pdata->size = sz;
0353             memcpy(pdata->data, pdbt->data, sz);
0354             ret = 0;
0355         } else
0356             ret = -1;
0357         return ret;
0358     }
0359 
0360     ////////////////////////////////////////////////////////////////////
0361 
0362     // Deep copy in assignment and copy constructor.
0363     inline const DbstlDbt& operator=(const DbstlDbt& t2)
0364     {
0365         set_dbt(t2, false);
0366         return t2;
0367     }
0368 
0369     // Deep copy in assignment and copy constructor.
0370     inline const Dbt& operator=(const Dbt& t2)
0371     {
0372         set_dbt(t2, false);
0373         return t2;
0374     }
0375 
0376     // Deep copy in assignment and copy constructor.
0377     inline const DBT& operator=(const DBT& t2)
0378     {
0379         set_dbt(t2, false);
0380         return t2;
0381     }
0382 
0383     // Deep copy in assignment and copy constructor.
0384     template <Typename T>
0385     inline const T& operator = (const T&dt)
0386     {
0387 
0388         make_dbt(dt, false);
0389         return dt;
0390     }
0391 
0392     // Generic way of storing an object or variable. Note that DataItem
0393     // is not a class template but a class with function templates.
0394     // Variable t locates on a consecutive chunk of memory, and objects 
0395     // of T have the same size. 
0396     //
0397     template <Typename T>
0398     void make_dbt(const T& dt, bool onstack)
0399     {
0400         typedef DbstlElemTraits<T> EM;
0401         u_int32_t sz;
0402         typename EM::ElemSizeFunct sizef;
0403         typename EM::ElemCopyFunct copyf;
0404         DBT *pdbt = (DBT *)&dbt_;
0405 
0406         if ((sizef = EM::instance()->get_size_function()) != NULL)
0407             sz = sizef(dt);
0408         else
0409             sz = sizeof(dt);
0410 
0411         copyf = EM::instance()->get_copy_function();
0412 
0413         if (onstack &&  copyf == NULL) {
0414             freemem();
0415             pdbt->data = ((void*)&dt);
0416             // We have to set DB_DBT_USERMEM for DB_THREAD to work.
0417             pdbt->flags = (DB_DBT_USERMEM);
0418             pdbt->size = (sz);
0419             pdbt->ulen = (sz);
0420             // This is a flag that this memory can't be freed
0421             // because it is on stack.
0422             pdbt->dlen = (INVALID_DLEN);
0423             return;
0424         }
0425 
0426         // Not on stack, allocate enough space and "copy" the object
0427         // using shall copy or customized copy.
0428         if (pdbt->ulen < sz) {
0429             pdbt->data = (DbstlReAlloc(pdbt->data, sz));
0430             assert(pdbt->data != NULL);
0431             pdbt->size = (sz);
0432             pdbt->ulen = (sz);
0433             pdbt->flags = (DB_DBT_USERMEM);
0434         } else
0435             pdbt->size = (sz);
0436 
0437         if (copyf != NULL)
0438             copyf(pdbt->data, dt);
0439         else
0440             memcpy(pdbt->data, &dt, sz);
0441     }
0442 
0443     inline const char*&operator = (const char*&dt)
0444     {
0445         make_dbt(dt, false);
0446         return dt;
0447     }
0448 
0449     inline const wchar_t*&operator = (const wchar_t*&dt)
0450     {
0451         make_dbt(dt, false);
0452         return dt;
0453     }
0454 
0455     inline const string &operator=(const string &dt)
0456     {
0457         make_dbt(dt, false);
0458         return dt;
0459     }
0460 
0461 #ifdef HAVE_WSTRING
0462     inline const wstring &operator=(const wstring &dt)
0463     {
0464         make_dbt(dt, false);
0465         return dt;
0466     }
0467 #endif
0468 
0469     template <Typename T>
0470     inline const T*&operator = (const T*&dt)
0471     {
0472         make_dbt(dt, false);
0473         return dt;
0474     }
0475 
0476     inline const self& operator=(const self&dbt1)
0477     {
0478         ASSIGNMENT_PREDCOND(dbt1)
0479         this->set_dbt(dbt1.dbt_, false);
0480         return dbt1;
0481     }
0482 
0483     // Deep copy.
0484     inline DataItem(const self&dbt1)
0485     {
0486         set_dbt(dbt1.dbt_, false);
0487     }
0488 
0489 
0490     inline DataItem(u_int32_t sz)
0491     {
0492         void *buf;
0493         DBT *pdbt = (DBT *)&dbt_;
0494 
0495         buf = NULL;
0496         buf = DbstlMalloc(sz);
0497         memset(buf, 0, sz);
0498         pdbt->size = sz;
0499         pdbt->ulen = sz;
0500         pdbt->data = buf;
0501         pdbt->flags = DB_DBT_USERMEM;
0502     }
0503 
0504     // Deep copy. The onstack parameter means whether the object referenced
0505     // by this DataItem is on used with a function call where this DataItem
0506     // object is used. If so, we don't deep copy the object, simply refer
0507     // to its memory location. The meaining is the same for this parameter
0508     // in constructors that follow.
0509     inline DataItem(const Dbt&dbt2, bool onstack)
0510     {
0511         set_dbt(dbt2, onstack);
0512     }
0513     
0514     inline DataItem(const DbstlDbt&dbt2, bool onstack)
0515     {
0516         set_dbt(dbt2, onstack);
0517     }
0518     
0519     inline DataItem(const DBT&dbt2, bool onstack)
0520     {
0521         set_dbt(dbt2, onstack);
0522     }
0523 
0524     // Deep copy. There is a partial specialization for char*/wchar_t*/
0525     // string/wstring.
0526     template<Typename T>
0527     inline DataItem(const T& dt, bool onstack)
0528     {
0529         make_dbt(dt, onstack);
0530     }
0531 
0532     inline ~DataItem(void)
0533     {
0534         freemem();
0535     }
0536 
0537 protected:
0538 
0539     // Store a char*/wchar_t* string. Need four versions for char*
0540     // and wchar_t* respectively to catch all
0541     // possibilities otherwise the most generic one will be called.
0542     // Note that the two const decorator matters when doing type
0543     // matching.
0544     inline void make_dbt_chars(const char *t, bool onstack)
0545     {
0546         DBT *d = (DBT *)&dbt_;
0547         u_int32_t sz;
0548         sz = ((t == NULL) ? 
0549             sizeof(char) : 
0550             (u_int32_t)((strlen(t) + 1) * sizeof(char)));
0551         if (!onstack) {
0552             if (d->ulen < sz) {
0553                 d->flags |= DB_DBT_USERMEM;
0554                 d->data = DbstlReAlloc(d->data, sz);
0555                 d->ulen = sz;
0556             }
0557             d->size = sz;
0558             if (t != NULL)
0559                 strcpy((char*)d->data, t);
0560             else
0561                 memset(d->data, '\0', sizeof(char));
0562         } else {
0563             freemem();
0564             d->data = ((t == NULL) ? (void *)"" : (void *)t);
0565             d->size = sz;
0566             d->ulen = sz;
0567             d->flags = (DB_DBT_USERMEM);
0568             d->dlen = (INVALID_DLEN);
0569         }
0570     }
0571 
0572     inline void make_dbt_wchars(const wchar_t *t, bool onstack)
0573     {
0574         DBT *d = (DBT *)&dbt_;
0575         u_int32_t sz;
0576         sz = ((t == NULL) ? 
0577             sizeof(wchar_t) : 
0578             (u_int32_t)((wcslen(t) + 1) * sizeof(wchar_t)));
0579         if (!onstack) {                 
0580             if (d->ulen < sz) {
0581                 d->flags |= DB_DBT_USERMEM;
0582                 d->data = DbstlReAlloc(d->data, sz);
0583                 d->ulen = sz;
0584             }
0585             d->size = sz;
0586             if (t != NULL)
0587                 wcscpy((wchar_t*)d->data, t);
0588             else
0589                 memset(d->data, L'\0', sizeof(wchar_t));
0590         } else {
0591             freemem();
0592             d->data = ((t == NULL) ? (void *)L"" : (void *)t);
0593             d->size = sz;
0594             d->ulen = sz;
0595             d->flags = (DB_DBT_USERMEM);
0596             d->dlen = (INVALID_DLEN);
0597         }
0598     }
0599 
0600     inline void make_dbt(const char*& t, bool onstack)
0601     {
0602         make_dbt_chars(t, onstack);
0603     }
0604 
0605     inline void make_dbt(const char* const& t, bool onstack)
0606     {
0607         make_dbt_chars(t, onstack);
0608     }
0609 
0610     inline void make_dbt(char*& t, bool onstack)
0611     {
0612         make_dbt_chars(t, onstack);
0613     }
0614 
0615     inline void make_dbt(char* const& t, bool onstack)
0616     {
0617         make_dbt_chars(t, onstack);
0618     }
0619 
0620     inline void make_dbt(const string& t, bool onstack)
0621     {
0622         make_dbt_chars(t.c_str(), onstack);
0623     }
0624 
0625     inline void make_dbt(const wchar_t*& t, bool onstack)
0626     {
0627         make_dbt_wchars(t, onstack);
0628     }
0629 
0630     inline void make_dbt(const wchar_t* const& t, bool onstack)
0631     {
0632         make_dbt_wchars(t, onstack);
0633     }
0634 
0635     inline void make_dbt(wchar_t*& t, bool onstack)
0636     {
0637         make_dbt_wchars(t, onstack);
0638     }
0639 
0640     inline void make_dbt(wchar_t* const& t, bool onstack)
0641     {
0642         make_dbt_wchars(t, onstack);
0643     }
0644 
0645 #ifdef HAVE_WSTRING
0646     inline void make_dbt(const wstring& t, bool onstack)
0647     {
0648         make_dbt_wchars(t.c_str(), onstack);
0649     }
0650 #endif
0651 
0652     template <Typename T>
0653     void make_dbt_internal(const T*t, bool onstack)
0654     {
0655         typedef DbstlElemTraits<T> EM;
0656         u_int32_t i, sz, totalsz, sql;
0657         DBT *pdbt = (DBT *)&dbt_;
0658         typename EM::ElemSizeFunct szf = NULL;
0659         typename EM::SequenceLenFunct seqlenf = NULL;
0660         typename EM::SequenceCopyFunct seqcopyf = NULL;
0661 
0662         szf = EM::instance()->get_size_function();
0663         seqlenf = EM::instance()->get_sequence_len_function();
0664         seqcopyf = EM::instance()->get_sequence_copy_function();
0665 
0666         assert(seqlenf != NULL);
0667         sql = sz = (u_int32_t)seqlenf(t);
0668         if (szf)
0669             for (i = 0, totalsz = 0; i < sz; i++)
0670                 totalsz += szf(t[i]);
0671         else
0672             totalsz = sz * sizeof(T);
0673 
0674         sz = totalsz;
0675 
0676         if (onstack && seqcopyf == NULL) {
0677             freemem();
0678             pdbt->data = (void *)t;
0679             pdbt->size = sz;
0680             pdbt->ulen = sz;
0681             pdbt->flags = DB_DBT_USERMEM;
0682             pdbt->dlen = INVALID_DLEN; // onstack flag;
0683         } else {
0684             // ulen stores the real length of the pointed memory.
0685             if (pdbt->ulen < sz) {
0686                 pdbt->data = DbstlReAlloc(pdbt->data, sz);
0687                 pdbt->ulen = sz;
0688                 pdbt->flags |= DB_DBT_USERMEM;
0689             }
0690             pdbt->size = sz;
0691 
0692             EM::instance()->copy((T *)pdbt->data, t, sql);
0693         }
0694     }
0695 
0696     // Store a sequence of base type T. Need four versions to catch all
0697     // possibilities otherwise the most generic one will be called.
0698     template <Typename T>
0699     inline void make_dbt(const T*const&tt, bool onstack)
0700     {
0701         make_dbt_internal((const T*)tt, onstack);
0702     }
0703     template <Typename T>
0704     inline void make_dbt(T*const&tt, bool onstack)
0705     {
0706         make_dbt_internal((const T*)tt, onstack);
0707     }
0708     template <Typename T>
0709     inline void make_dbt(T*&tt, bool onstack)
0710     {
0711         make_dbt_internal((const T*)tt, onstack);
0712     }
0713     template <Typename T>
0714     inline void make_dbt(const T*&tt, bool onstack)
0715     {
0716         make_dbt_internal((const T*)tt, onstack);
0717     }
0718 
0719 
0720 public:
0721     inline DataItem(const char*& t, bool onstack)
0722     {
0723         make_dbt_chars(t, onstack);
0724     }
0725 
0726     inline DataItem(const char* const& t, bool onstack)
0727     {
0728         make_dbt_chars(t, onstack);
0729     }
0730 
0731     inline DataItem(char*& t, bool onstack)
0732     {
0733         make_dbt_chars(t, onstack);
0734     }
0735 
0736     inline DataItem(char* const& t, bool onstack)
0737     {
0738         make_dbt_chars(t, onstack);
0739     }
0740 
0741     inline DataItem(const string& t, bool onstack)
0742     {
0743         make_dbt_chars(t.c_str(), onstack);
0744     }
0745 
0746     inline DataItem(const wchar_t*& t, bool onstack)
0747     {
0748         make_dbt_wchars(t, onstack);
0749     }
0750 
0751     inline DataItem(const wchar_t* const& t, bool onstack)
0752     {
0753         make_dbt_wchars(t, onstack);
0754     }
0755 
0756     inline DataItem(wchar_t*& t, bool onstack)
0757     {
0758         make_dbt_wchars(t, onstack);
0759     }
0760 
0761     inline DataItem(wchar_t* const& t, bool onstack)
0762     {
0763         make_dbt_wchars(t, onstack);
0764     }
0765 
0766 #ifdef HAVE_WSTRING
0767     inline DataItem(const wstring& t, bool onstack)
0768     {
0769         make_dbt_wchars(t.c_str(), onstack);
0770     }
0771 #endif
0772     template<Typename T>
0773     inline DataItem(T*&tt, bool onstack)
0774     {
0775         make_dbt_internal((const T*)tt, onstack);
0776     }
0777 
0778     template<Typename T>
0779     inline DataItem(const T*&tt, bool onstack)
0780     {
0781         make_dbt_internal((const T*)tt, onstack);
0782     }
0783 
0784     template<Typename T>
0785     inline DataItem(T*const&tt, bool onstack)
0786     {
0787         make_dbt_internal((const T*)tt, onstack);
0788     }
0789 
0790     template<Typename T>
0791     inline DataItem(const T*const&tt, bool onstack)
0792     {
0793         make_dbt_internal((const T*)tt, onstack);
0794     }
0795 
0796 
0797 }; // DataItem<>
0798 
0799 bool operator==(const Dbt&d1, const Dbt&d2);
0800 bool operator==(const DBT&d1, const DBT&d2);
0801 END_NS
0802 
0803 #endif // !_DB_STL_DBT_H