GME  13
CommonStl.h
Go to the documentation of this file.
00001 
00002 #ifndef MGA_COMMONSTL_H
00003 #define MGA_COMMONSTL_H
00004 
00005 #include <vector>
00006 #include <string>
00007 #include <hash_map>
00008 
00009 #ifndef MGA_COMMONSMART_H
00010 #include "CommonSmart.h"
00011 #endif
00012 
00013 // --------------------------- string
00014 
00015 // we use "const string &" for [in] and "string &" for [in, out]
00016 
00017 // these THROW exceptions
00018 
00019 /* needed for MS STL
00020 inline void CopyTo(const std::string::const_iterator i, int l, BSTR * b){}
00021 inline void CopyTo(const std::string::const_iterator i, int l, VARIANT *v){}
00022 inline void CopyTo(const std::string::const_iterator i, int l, CComBstrObj &a){}
00023 inline void CopyTo(const std::string::const_iterator i, int l, CComVariant &a){}
00024 inline void CopyTo(BSTR b, std::string::iterator i, int l) {}
00025 inline void CopyTo(VARIANT &v, std::string::iterator i, int l) {}
00026 */
00027 inline void CopyTo(const std::string &s, BSTR *b) { CopyTo( s.c_str(), s.length(), b); }
00028 inline void CopyTo(const std::string &s, VARIANT *v) { CopyTo(s.c_str(), s.length(), v); }
00029 inline void CopyTo(const std::string &s, CComBstrObj &a) { CopyTo(s.c_str(), s.length(), a); }
00030 inline void CopyTo(const std::string &s, CComVariant &a) { CopyTo(s.c_str(), s.length(), a); }
00031 
00032 inline void CopyTo(BSTR b, std::string &s)
00033 {
00034         int l = GetCharLength(b);
00035         char *tmp = (char*)malloc(l);
00036         if (tmp == NULL)
00037                 COMTHROW(E_OUTOFMEMORY);
00038         CopyTo(b, tmp, l);
00039         s.assign(tmp, l);
00040         free(tmp);
00041 }
00042 
00043 inline void CopyTo(VARIANT &v, std::string &s)
00044 {
00045         int l = GetCharLength(v);
00046         char *tmp = (char*)malloc(l);
00047         if (tmp == NULL)
00048                 COMTHROW(E_OUTOFMEMORY);
00049         CopyTo(v, tmp, l);
00050         s.assign(tmp, l);
00051         free(tmp);
00052 }
00053 
00054 void vFormat(std::string &s, const char *format, va_list args);
00055 void vFormat(std::wstring &s, const wchar_t *format, va_list args);
00056 
00057 inline void Format(std::string &s, const char *format, ...)
00058 {
00059         va_list args;
00060         va_start(args, format);
00061 
00062         vFormat(s, format, args);
00063 }
00064 
00065 inline void Format(std::wstring &s, const wchar_t *format, ...)
00066 {
00067         va_list args;
00068         va_start(args, format);
00069 
00070         vFormat(s, format, args);
00071 }
00072 
00073 typedef wchar_t* bstr_iterator;
00074 typedef const wchar_t* bstr_const_iterator;
00075 
00076 inline bstr_const_iterator begin(BSTR p) { return reinterpret_cast<wchar_t*>(p); }
00077 inline bstr_const_iterator end(BSTR p) { return reinterpret_cast<wchar_t*>(p) ? (reinterpret_cast<wchar_t*>(p) + SysStringLen(p)) : 0; }
00078 
00079 inline void CopyTo(bstr_const_iterator i, bstr_const_iterator e, CComBstrObj &b)
00080 {
00081         ASSERT( i <= e );
00082         BSTR tmpb = SysAllocStringLen(i, e - i);
00083         if (tmpb == NULL)
00084                 COMTHROW(E_OUTOFMEMORY);
00085 
00086         b.Attach(tmpb);
00087 }
00088 
00089 // --------------------------- bindata
00090 
00091 typedef std::vector<unsigned char> bindata;
00092 
00093 inline void CopyTo(const bindata &b, VARIANT *p) 
00094 {
00095         if(b.empty())
00096         {
00097                 unsigned char* pnull=NULL;
00098                 CopyTo(pnull,pnull, p);
00099         }
00100         else
00101         {
00102                 CopyTo(&b[0], (&b[0]) + b.size(), p); 
00103         }
00104 }
00105 inline void CopyTo(const bindata &b, CComVariant &a) { CopyTo(&b[0], (&b[0]) + b.size(), a); }
00106 
00107 inline void CopyTo(VARIANT &v, bindata &b)
00108 {
00109         if( v.vt == (VT_I4 | VT_ARRAY) )
00110         {
00111                 b.resize(sizeof(long) * GetArrayLength(v));
00112                 CopyTo(v, (long*)&b[0], (long*)((&b[0]) + b.size()) );
00113         }
00114         else
00115         {
00116                 if(GetArrayLength(v)==0)
00117                 {
00118                         b.clear();
00119                 }
00120                 else
00121                 {
00122                         b.resize(GetArrayLength(v));
00123                         CopyTo(v, &b[0], (&b[0]) + b.size());
00124                 }
00125         }
00126 }
00127 
00128 inline void MoveTo(SAFEARRAY *p, std::vector<CComBstrObj> &bstrobjs)
00129 {
00130         ASSERT( p != NULL );
00131 
00132         bstrobjs.resize(GetArrayLength(p));
00133         MoveTo(p, &bstrobjs[0], (&bstrobjs[0]) + bstrobjs.size());
00134 }
00135 
00136 inline void MoveTo(std::vector<CComBstrObj> &bstrobjs, SAFEARRAY **p)
00137 {
00138         ASSERT( p != NULL && *p == NULL );
00139 
00140         MoveTo(&bstrobjs[0], (&bstrobjs[0]) + bstrobjs.size(), p);
00141 }
00142 
00143 inline void CopyTo(const std::vector<CComBstrObj> &bstrobjs, SAFEARRAY **p)
00144 {
00145         ASSERT( p != NULL && *p == NULL );
00146 
00147         CopyTo(&bstrobjs[0], (&bstrobjs[0]) + bstrobjs.size(), p);
00148 }
00149 
00150 inline void CopyTo(const std::vector<GUID> &guids, SAFEARRAY **p)
00151 {
00152         ASSERT( p != NULL && *p == NULL );
00153 
00154         if(guids.empty())
00155         {
00156                 GUID* pnull=NULL;
00157                 CopyTo(pnull,pnull,p);
00158         }
00159         else
00160         {
00161                 CopyTo(&guids[0], (&guids[0]) + guids.size(), p);
00162         }
00163 }
00164 
00165 // --------------------------- STL function objects
00166 
00167 template <class T>
00168 struct ptr_compare : public stdext::hash_compare<T>
00169 {
00170         size_t operator()(const T* p) const { return (size_t) p; }
00171         bool operator()(const T *a, const T *b) const { return a < b; }
00172 
00173         // both hashing and comparing must be implemented here
00174 };
00175 
00176 // --------------------------- Iterator
00177 
00178 #ifdef _DEBUG
00179 
00180 template<class CONTAINER>
00181 inline bool IsValidIterator(const CONTAINER &container, typename CONTAINER::const_iterator i)
00182 {
00183         CONTAINER::const_iterator b = container.begin();
00184         CONTAINER::const_iterator e = container.end();
00185 
00186         while( b != e )
00187         {
00188                 if( b == i )
00189                         return true;
00190                 ++b;
00191         }
00192 
00193         return false;
00194 }
00195 
00196 #endif
00197 
00198 template<class CONTAINER>
00199 inline int limited_size(const CONTAINER &container, int limit)
00200 {
00201         ASSERT( limit >= 1 );
00202         int counter = limit;
00203 
00204         CONTAINER::const_iterator i = container.begin();
00205         CONTAINER::const_iterator e = container.end();
00206         while( i != e && --counter > 0 )
00207                 ++i;
00208 
00209         ASSERT( ( (int) container.size() < limit ? (int) container.size() : limit) == (limit - counter) );
00210         return limit - counter;
00211 }
00212 
00213 // --------------------------- Collection
00214 
00215 template<class INTERFACE>
00216 class CComObjPtrVector : public std::vector< CComObjPtr<INTERFACE> >
00217 {
00218 };
00219 
00220 template<class ELEM>
00221 void CopyTo( TYPENAME_ELEM2COLL(ELEM) *p, std::vector< CComObjPtr<ELEM> > &q)
00222 {
00223         ASSERT( p != NULL );
00224         ASSERT( &q != NULL );
00225 
00226         q.clear();
00227 
00228         long count = 0;
00229         COMTHROW( p->get_Count(&count) );
00230         ASSERT( count >= 0 );
00231 
00232         if(count > 0)
00233         {
00234                 //q.insert(q.begin(), count, CComObjPtr<ELEM>());
00235                 q.resize(count);
00236 
00237                 COMTHROW( p->GetAll(count, (ELEM**)&q[0]) );
00238         }
00239 }
00240 
00241 template<class ELEM>
00242 class PutOutCollObj; // forward declaration for the template class 
00243 
00244 
00245 // this template function will be befriended with the PutOutCollObj class, in VS.NET 2003 sucha friend needs to be declared before the class declaration
00246 template<class ELEM>
00247 PutOutCollObj<ELEM> PutOut( std::vector< CComObjPtr<ELEM> > & coll_vector);
00248 
00249 
00250 template<class ELEM>
00251 class PutOutCollObj
00252 {
00253 public:
00254         typedef ELEM elem_interface;
00255         typedef TYPENAME_ELEM2COLL(ELEM) coll_interface;
00256         
00257         typedef std::vector< CComObjPtr<elem_interface> > vector_type;
00258 
00259         operator coll_interface** () { return PutOut(coll_ptr); }
00260 
00261         ~PutOutCollObj()
00262         {
00263                 // we need this because COM methods might
00264                 // not fill in the [out] parameter
00265 
00266                 if( coll_ptr != NULL )
00267                         CopyTo(coll_ptr, coll_vector);
00268         }
00269         
00270 private:
00271         PutOutCollObj(vector_type &v) : coll_vector(v) { }
00272 
00273         friend PutOutCollObj<ELEM> PutOut<ELEM>( std::vector< CComObjPtr<ELEM> > &coll_vector);
00274 
00275         // to prevent misuse
00276         PutOutCollObj();
00277         PutOutCollObj(const PutOutCollObj<ELEM> &a);
00278 
00279 public:
00280         CComObjPtr<coll_interface> coll_ptr;
00281         vector_type &coll_vector;
00282 };
00283 
00284 // this template function (friend of PutOutCollObj) needs to be forward declared!
00285 template<class ELEM>
00286 PutOutCollObj<ELEM> PutOut( std::vector< CComObjPtr<ELEM> > & coll_vector)
00287 {
00288         return PutOutCollObj<ELEM>( coll_vector);
00289 }
00290 
00291 #endif//MGA_COMMONSTL_H