![]() |
| | #31 | |
| Registered User Join Date: May 2008 Location: Paris
Posts: 236
| Quote:
| |
| MarkZWEERS is offline | |
| | #32 |
| MENTAL DETECTOR Join Date: Apr 2006 Location: United States
Posts: 3,295
| This seems like a non-argument. After all myobj == "something" is still valid using a non-member equality operator; you're not forced out of your habit. There isn't a logical problem with "something" == myobj either. |
| whiteflags is offline | |
| | #33 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| But in any case, the non-member operators are giving me problem, just as the templates are. The linker is error happy today. Update on this nasty problem: The global += operators are at fault, but I don't know why. Inside the namespace Strings or not, it won't compile. Template function: Code: template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
rlhs.AppendStr(strData);
return rlhs;
}
Code: test += L"This is a test"; class Strings::CTmplStringBase<wchar_t,class Strings::StrTraits<wchar_t> > & __cdecl Strings::operator+=(class Strings::CTmplStringBase<wchar_t,class Strings::StrTraits<wchar_t> > &,wchar_t const *)" is undefined.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
| | #34 | ||
| Registered User Join Date: May 2008 Location: Paris
Posts: 236
| Quote:
Quote:
Maybe the problem is that the operator '+=' does not exist. You might think it does, but only its template exists. What if you try specializing the template function with the type of 'test' ? (I might be wrong on this) Further, you might consider using 1) only one template argument for the operator, which then calls a function in a template class. Simple reason: function templates cannot have (yet) default arguments, while template classes can. or, 2) don't use the trait as template parameter. Simply parametrize the trait by the first parameter and use the type in the trait as the return type. Code: template<typename T>
CTmplStringBase<typename Traits<T>::myIdentifier>& //return type
operator += ( CTmplStringBase<typename Traits<T>::myIdentifier>& rlhs, const T* strData) { // blah}
Last edited by MarkZWEERS; 05-10-2008 at 09:28 AM. | ||
| MarkZWEERS is offline | |
| | #35 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| Code: template<> CTmplStringBase< wchar_t, Strings::StrTraits<wchar_t> >& operator += (CTmplStringBase< wchar_t, Strings::StrTraits<wchar_t> >& rlhs, const wchar_t* strData)
{
//rlhs.AppendStr(strData);
return rlhs;
}
This seems over my head -_- I'm guessing that these are wrong: Code: friend CTmplStringBase& operator += (CTmplStringBase& rlhs, const T* strData); friend CTmplStringBase& operator += (CTmplStringBase& rlhs, const T cData); friend CTmplStringBase& operator += (CTmplStringBase& rlhs, uint64_t nData); friend CTmplStringBase& operator += (CTmplStringBase& rlhs, int64_t nData); friend CTmplStringBase& operator += (CTmplStringBase& rlhs, long nData); If not specified, the code won't compile (compile error). And if they do exist, it will give linking error - or in other words, they seem to refer to a function that does not exist.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
Last edited by Elysia; 05-10-2008 at 09:30 AM. | |
| Elysia is offline | |
| | #36 | ||
| Registered User Join Date: May 2008 Location: Paris
Posts: 236
| Quote:
Quote:
| ||
| MarkZWEERS is offline | |
| | #37 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| Yes, of course. One of them is posted above, but I still get linking errors about that one and all the others. It has really come to this... This operator, defined as global is found and used: Code: template<typename T> CTmplStringBase< T, Strings::StrTraits<T> >& operator += (CTmplStringBase< T, Strings::StrTraits<T> >& rlhs, const T* strData)
{
rlhs.AppendStr(strData);
return rlhs;
}
So, the problem is how to declare it as a friend inside the class, since it so obviously won't work. This: Code: friend CTmplStringBase< T, Strings::StrTraits<T> >& operator += (CTmplStringBase< T, Strings::StrTraits<T> >& rlhs, const T* strData); Any ideas on how to do this? Without making the whole operator(s) inline?
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
| | #38 |
| Registered User Join Date: May 2008 Location: Paris
Posts: 236
| Haha the error is nice: Code: template<typename T> CTmplStringBase<T>::CTmplStringBase(const T* strData)
{
*this = strData;
}
Further, I really really think you should not derive from your structs, because 1) it does not satisfy at all the Liskov substitution principle (just learned, but very useful) 2) it isn't a trait, and if it was so, traits are always template parameters. You'd better have a composition: make a private/protected object of it in your string class. http://www.ubookcase.com/book/Addiso...3586/ch34.html it is really worth looking at this chapter. Please find attached what I have made (very simplified) from your code. |
| MarkZWEERS is offline | |
| | #39 | ||
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| Quote:
But does it matter if it's inherited, just placed as an object or the members just made static so I can access them as a namespace? I did the latter, because it seems more efficient (I only need one instance of every member of the trait class). Here's in the newest code I'm trying with.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
Last edited by Elysia; 05-10-2008 at 10:40 AM. | ||
| Elysia is offline | |
| | #40 | |
| Registered User Join Date: May 2008 Location: Paris
Posts: 236
| well, it made THE difference for the very simple test files I've attached above... Code: #include "markStringEx.h"
#include "markStringExImpl.h"
int main()
{
CTmplStringBase<int> example1;
CTmplStringBase<int> example2( 10);
CTmplStringBase<int> example3( example2); // gave _linker_ error
return 0;
}
Quote:
| |
| MarkZWEERS is offline | |
| | #41 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| Didn't for me, it didn't. But the problem is the friend operators. Especially +=. I just can't get them declared as friends without causing a linking errors.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
| | #42 | |
| Registered User Join Date: May 2008 Location: Paris
Posts: 236
| Quote:
Can you attach a simplified library with only one friend function which causes the error? | |
| MarkZWEERS is offline | |
| | #43 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| VS's default compiler is what I use. 2008 edition, so it's top of the line. I'll attach the dumbed down class. Just remove all the comments if you want to shrink it in size. Construct an object, then add a string literal +=, and you will get either a linking error or ambiguous error (I left two += operators there, you can check them).
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| |
| Elysia is offline | |
| | #44 |
| Registered User Join Date: Jan 2008
Posts: 638
| This code... has so very much wrong with it. The code... the concepts... ;_; Eventually I just decided to post the code as fixed rather than waste time telling you everything, but I highly suggest you read everything with extreme care: unless I missed something every single change is crucial to successful compilation. You also should probably get a good stingy C++ compiler. Obviously whatever you are using isn't informing you of all the problems that it should be telling you about. I hope you have a differencing program installed. Soma Code: //#if defined(_AFXEXT) && !defined(STRINGEXIMPL_H)
//#error "Dll code must include StringExImpl.h"
//#endif
#ifndef STRINGEX_H__FILE__
#define STRINGEX_H__FILE__
//#include "boost\operators.hpp"
namespace Strings
{
template<typename T, typename Traits> class CTmplStringBase;
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, const T* strData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, const T cData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, uint64_t nData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, int64_t nData);
template<typename T, typename Traits> CTmplStringBase<T,Traits>& operator += (CTmplStringBase<T,Traits>& rlhs, long nData);
template<typename T, typename Traits> bool operator == (CTmplStringBase<T,Traits>& rlhs, const T* strData);
template<typename T, typename Traits> bool operator == (CTmplStringBase<T,Traits>& rlhs, const T cData);
template<typename T, typename Traits> bool operator != (CTmplStringBase<T,Traits>& rlhs, const T* strData);
template<typename T, typename Traits> bool operator != (CTmplStringBase<T,Traits>& rlhs, const T cData);
template<typename T> class StrTraits
{
//protected:
public:
typedef int (fnc_tprintf_s)(T* buffer, size_t sizeOfBuffer, const T* format, ...);
typedef int (fnc_tvprintf_s)(T* buffer, size_t sizeOfBuffer, const T* format, va_list argptr);
typedef int (fnc_tcscmp)(const T* string1, const T* string2);
typedef int (fnc_tvcprintf)(const T* format, va_list argptr);
static const T* UINT64_T_IDENTIFIER;
static const T* INT64_T_IDENTIFIER;
static const T* LONG_IDENTIFIER;
static uint32_t GetLength(const T* strData); // { return strlen(strData); }
static fnc_tprintf_s* GetFormatFunction(const T*);
static fnc_tvprintf_s* GetVFormatFunction(const T*);
static fnc_tvcprintf* GetVFormatCountFunction(const T*);
static fnc_tcscmp* GetCompareFunction(const T*);
};
//template<typename T> uint32_t StrTraits<T>::GetLength(const T* strData) const { return strlen(strData); }
template<typename T, typename Traits> class CTmplStringBase:
//private StrTraits<T>,
public boost::addable<CTmplStringBase<T, Traits>, const T*>,
public boost::addable<CTmplStringBase<T, Traits>, const T>,
public boost::addable<CTmplStringBase<T, Traits>, uint64_t>,
public boost::addable<CTmplStringBase<T, Traits>, int64_t>,
public boost::addable<CTmplStringBase<T, Traits>, long>,
public boost::addable< CTmplStringBase<T, Traits> >
#ifdef _MFC_VER
, public boost::addable< CTmplStringBase<T, Traits>, const CStringT< T, StrTraitMFC_DLL<T> > >
#endif
{
public:
CTmplStringBase();
CTmplStringBase(const CTmplStringBase& rSrc);
#ifdef _MFC_VER
CTmplStringBase(const CStringT< T, StrTraitMFC_DLL<T> >& strSrc);
#endif
CTmplStringBase(const T* strData);
CTmplStringBase(const T cData);
CTmplStringBase(uint64_t nData);
CTmplStringBase(int64_t nData);
CTmplStringBase(long nData);
~CTmplStringBase();
CTmplStringBase& operator = (const T* strData);
CTmplStringBase& operator = (const T cData);
CTmplStringBase& operator = (uint64_t nData);
CTmplStringBase& operator = (int64_t nData);
CTmplStringBase& operator = (long nData);
CTmplStringBase& operator = (const CTmplStringBase& rSrc);
#ifdef _MFC_VER
CTmplStringBase& operator = (const CStringT< T, StrTraitMFC_DLL<T> >& rSrc);
#endif
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, const T* strData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, const T cData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, uint64_t nData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, int64_t nData);
friend CTmplStringBase<T,Traits>& operator += <> (CTmplStringBase<T,Traits>& rlhs, long nData);
friend bool operator == <> (CTmplStringBase<T,Traits>& rlhs, const T* strData);
friend bool operator == <> (CTmplStringBase<T,Traits>& rlhs, const T cData);
friend bool operator != <> (CTmplStringBase<T,Traits>& rlhs, const T* strData);
friend bool operator != <> (CTmplStringBase<T,Traits>& rlhs, const T cData);
operator const T* () const;
void Replace(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith);
CTmplStringBase Right(uint32_t nCount) const;
void Delete(uint32_t nStartFrom, uint32_t nCount = 0);
uint32_t GetLength() const;
T* GetBuffer(uint32_t nMinSize);
void ReleaseBuffer();
void Truncate(uint32_t nNewSize);
int32_t Find(const T* strFind, uint32_t nBeginAt = 0) const;
int32_t Find(const T cFind, uint32_t nBeginAt = 0) const;
CTmplStringBase Mid(uint32_t nStart, uint32_t nCount = 0) const;
void Format(const T* strFormat, ...);
void AppendFormat(const T* strFormat, ...);
void Empty();
private:
void Init();
int32_t ReplaceInternal(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith, bool bReplace);
void FormatInternal(const T* strFormat, va_list arg);
void CopyStr(const T* strData);
void AppendStr(const T* strData);
void CopyStrLowLevel(T* strDst, uint32_t nDstSize, const T* strSrc, T** pUnusedPtr) const;
void PrepareBuffer(uint32_t nNeededSize);
template<typename Type> CTmplStringBase& Assign(Type& Data);
template<typename Type> CTmplStringBase& AppendNum(Type& Data, const T* strFormat);
T* m_pData;
T* m_pUnusedStart;
uint32_t m_nSize; // Number of elements in m_pData
static const uint32_t nDefaultSize = 10;
};
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T* strData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T cData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, uint64_t nData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, int64_t nData);
//template<typename T> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, long nData);
//template<typename T> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T* strData);
//template<typename T> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T cData);
//template<typename T> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T* strData);
//template<typename T> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T cData);
//#ifndef STRINGEXIMPL_H
// template<> class __declspec(dllimport) CTmplStringBase<wchar_t>;
// template<> class __declspec(dllimport) CTmplStringBase<char>;
// template<> class __declspec(dllimport) StrTraits<wchar_t>;
// template<> class __declspec(dllimport) StrTraits<char>;
// template<> class __declspec(dllimport) Strings::StrTraits<char>;
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, const char* strData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, const char cData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, uint64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, int64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<char>& operator += (CTmplStringBase<char>& rlhs, long nData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<char>& rlhs, const char* strData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<char>& rlhs, const char cData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<char>& rlhs, const char* strData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<char>& rlhs, const char cData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, const wchar_t* strData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, const wchar_t cData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, uint64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, int64_t nData);
// template<> __declspec(dllimport) CTmplStringBase<wchar_t>& operator += (CTmplStringBase<wchar_t>& rlhs, long nData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<wchar_t>& rlhs, const wchar_t* strData);
// template<> __declspec(dllimport) bool operator == (CTmplStringBase<wchar_t>& rlhs, const wchar_t cData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<wchar_t>& rlhs, const wchar_t* strData);
// template<> __declspec(dllimport) bool operator != (CTmplStringBase<wchar_t>& rlhs, const wchar_t cData);
//#endif
typedef CTmplStringBase< char, StrTraits<char> > CStringExA;
typedef CTmplStringBase< wchar_t, StrTraits<wchar_t> > CStringExW;
typedef CTmplStringBase< TCHAR, StrTraits<TCHAR> > CStringEx;
//}
//#include "StringExImpl.h"
//#ifndef STRINGEXIMPL_H
//#define STRINGEXIMPL_H
//#include "StringEx.h"
//# include "UnsafeCast.h"
//namespace Strings
//{
//template<typename T> uint32_t StrTraits<T>::GetLength(const T* strData) const { ASSERT(FALSE); return 0; }
template<> const char* StrTraits<char>::UINT64_T_IDENTIFIER = "%I64u";
template<> const char* StrTraits<char>::INT64_T_IDENTIFIER = "%I64i";
template<> const char* StrTraits<char>::LONG_IDENTIFIER = "%li";
template<> const wchar_t* StrTraits<wchar_t>::UINT64_T_IDENTIFIER = L"%I64u";
template<> const wchar_t* StrTraits<wchar_t>::INT64_T_IDENTIFIER = L"%I64i";
template<> const wchar_t* StrTraits<wchar_t>::LONG_IDENTIFIER = L"%li";
template<> uint32_t StrTraits<char>::GetLength(const char* strData) { return strlen(strData); }
template<> uint32_t StrTraits<wchar_t>::GetLength(const wchar_t* strData) { return wcslen(strData); }
template<> StrTraits<char>::fnc_tprintf_s* StrTraits<char>::GetFormatFunction(const char*) { return &sprintf_s; }
template<> StrTraits<wchar_t>::fnc_tprintf_s* StrTraits<wchar_t>::GetFormatFunction(const wchar_t*) { return &swprintf_s; }
template<> StrTraits<char>::fnc_tvprintf_s* StrTraits<char>::GetVFormatFunction(const char*) { return &vsprintf_s; }
template<> StrTraits<wchar_t>::fnc_tvprintf_s* StrTraits<wchar_t>::GetVFormatFunction(const wchar_t*) { return &vswprintf_s; }
template<> StrTraits<char>::fnc_tvcprintf* StrTraits<char>::GetVFormatCountFunction(const char*) { return &_vscprintf; }
template<> StrTraits<wchar_t>::fnc_tvcprintf* StrTraits<wchar_t>::GetVFormatCountFunction(const wchar_t*) { return &_vscwprintf; }
template<> StrTraits<char>::fnc_tcscmp* StrTraits<char>::GetCompareFunction(const char*) { return &strcmp; }
template<> StrTraits<wchar_t>::fnc_tcscmp* StrTraits<wchar_t>::GetCompareFunction(const wchar_t*) { return &wcscmp; }
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase()
{
Init();
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const CTmplStringBase<T, Traits>& rSrc)
{
Init();
*this = rSrc;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const T* strData)
{
Init();
*this = strData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const T cData)
{
Init();
*this = cData;
}
#ifdef _MFC_VER
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(const CStringT< T, StrTraitMFC_DLL<T> >& strSrc)
{
Init();
CopyStr(strSrc);
}
#endif
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(uint64_t nData)
{
Init();
*this = nData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(int64_t nData)
{
Init();
*this = nData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::CTmplStringBase(long nData)
{
Init();
*this = nData;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::~CTmplStringBase()
{
delete [] m_pData;
m_nSize = 0;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const T* strData)
{
return Assign(strData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const T cData)
{
return Assign(cData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (long nData)
{
return Assign(nData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (uint64_t nData)
{
return Assign(nData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (int64_t nData)
{
return Assign(nData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const CTmplStringBase& rSrc)
{
CopyStr(rSrc.m_pData);
return *this;
}
#ifdef _MFC_VER
template<typename T, typename Traits> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::operator = (const CStringT< T, StrTraitMFC_DLL<T> >& rSrc)
{
return Assign(rSrc);
}
#endif
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
rlhs.AppendStr(strData);
return rlhs;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, const T cData)
{
rlhs.PrepareBuffer(1);
*rlhs.m_pUnusedStart++ = cData;
*rlhs.m_pUnusedStart = 0;
return rlhs;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, uint64_t nData)
{
return rlhs.AppendNum(nData, CTmplStringBase<T, Traits>::UINT64_T_IDENTIFIER);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, int64_t nData)
{
return rlhs.AppendNum(nData, CTmplStringBase<T, Traits>::INT64_T_IDENTIFIER);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>& operator += (CTmplStringBase<T, Traits>& rlhs, long nData)
{
return rlhs.AppendNum(nData, CTmplStringBase<T, Traits>::LONG_IDENTIFIER);
}
template<typename T, typename Traits> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
typename CTmplStringBase<T, Traits>::fnc_tcscmp* Compare = rlhs.GetCompareFunction(strData);
return (Compare(rlhs.m_pData, strData) == 0);
}
template<typename T, typename Traits> bool operator == (CTmplStringBase<T, Traits>& rlhs, const T cData)
{
return (cData == rlhs.m_pData[0]);
}
template<typename T, typename Traits> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T* strData)
{
return !(rlhs == strData);
}
template<typename T, typename Traits> bool operator != (CTmplStringBase<T, Traits>& rlhs, const T cData)
{
return !(rlhs == cData);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits>::operator const T* () const
{
return m_pData;
}
//template<typename T, typename Traits> const T* CTmplStringBase<T, Traits>::GetString() const
//{
// return m_pData;
//}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Replace(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith)
{
int32_t nNeededSize = ReplaceInternal(strReplaceWhat, strReplaceWith, false);
if (nNeededSize > 0) PrepareBuffer(nNeededSize);
ReplaceInternal(strReplaceWhat, strReplaceWith, true);
}
template<typename T, typename Traits> CTmplStringBase<T, Traits> CTmplStringBase<T, Traits>::Right(uint32_t nCount) const
{
CTmplStringBase<T, Traits> strTemp;
unsigned int nSize = ((unsigned int)(m_pUnusedStart - nCount + 1));
T* pBuffer = strTemp.GetBuffer(nSize);
CopyStrLowLevel(pBuffer, nSize, m_pUnusedStart - nCount, NULL);
strTemp.ReleaseBuffer();
return strTemp;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Delete(uint32_t nStartFrom, uint32_t nCount)
{
if (nCount == 0)
{
m_pData[nStartFrom] = 0;
m_pUnusedStart = &m_pData[nStartFrom];
return;
}
unsigned int nBufferSize = (m_pData + m_nSize) - (m_pData + nStartFrom);
memmove_s(m_pData + nStartFrom, nBufferSize, m_pData + nStartFrom + nCount, nBufferSize);
m_pUnusedStart -= nCount;
}
template<typename T, typename Traits> uint32_t CTmplStringBase<T, Traits>::GetLength() const
{
return m_pUnusedStart - m_pData;
}
template<typename T, typename Traits> T* CTmplStringBase<T, Traits>::GetBuffer(uint32_t nMinSize)
{
PrepareBuffer(nMinSize);
return m_pData;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::ReleaseBuffer()
{
m_pUnusedStart = m_pData + StrTraits<T>::GetLength(m_pData);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Truncate(uint32_t nNewSize)
{
m_pData[nNewSize] = 0;
m_pUnusedStart = &m_pData[nNewSize];
}
template<typename T, typename Traits> int32_t CTmplStringBase<T, Traits>::Find(const T* strFind, uint32_t nBeginAt) const
{
const T* pStart = m_pData + nBeginAt;
const T* pEnd = m_pData + GetLength();
const T* p = pStart;
uint32_t nFindLength = StrTraits<T>::GetLength(strFind);
while (pStart < pEnd)
{
if (uint32_t(pEnd - pStart) < nFindLength) return -1;
if (*p == *strFind)
{
bool bMatch = true;
for (uint32_t i = 1; i < nFindLength; i++)
{
if (p[i] != strFind[i])
{
bMatch = false;
break;
}
}
if (bMatch) return (p - m_pData);
}
p++;
}
return -1;
}
template<typename T, typename Traits> int32_t CTmplStringBase<T, Traits>::Find(const T cFind, uint32_t nBeginAt) const
{
CTmplStringBase<T, Traits> strTemp = cFind;
return Find(strTemp, nBeginAt);
}
template<typename T, typename Traits> int32_t CTmplStringBase<T, Traits>::ReplaceInternal(const CTmplStringBase& strReplaceWhat, const CTmplStringBase& strReplaceWith, bool bReplace)
{
const T* m_pDataEnd = m_pUnusedStart;
const T* pBufferEnd = m_pData + m_nSize;
uint32_t nReplaceWhatSize = StrTraits<T>::GetLength(strReplaceWhat);
uint32_t nReplaceWithSize = StrTraits<T>::GetLength(strReplaceWith);
int32_t nNeededSize = 0;
int32_t nIndex = 0;
while ( (nIndex = Find(strReplaceWhat, nIndex)) > -1 )
{
if (nIndex >= 0)
{
T* p = m_pData + nIndex;
int32_t nAdjustSize = (nReplaceWhatSize - nReplaceWithSize);
if (!bReplace)
{
nNeededSize += nAdjustSize;
nIndex++;
continue;
}
// Move data so we can copy new data into place:
// This is a test --> This is a test
T* pCopyDataStart = p + nReplaceWithSize;
unsigned int nDataToCopy = m_pDataEnd - pCopyDataStart;
if (nDataToCopy > 0) CopyStrLowLevel(pCopyDataStart, nDataToCopy, pCopyDataStart, NULL);
// Copy new data into place, overwriting old data with new:
// This is a test --> This is an test
// Hint: There is always 0 beyond the end of the data, so out buffer is actually
CopyStrLowLevel(p, pBufferEnd - p, strReplaceWith, NULL);
}
nIndex++;
}
if (bReplace)
m_pUnusedStart = m_pData + StrTraits<T>::GetLength(m_pData);
return nNeededSize;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::FormatInternal(const T* strFormat, va_list arg)
{
typename Traits::fnc_tvprintf_s* vformat_s = Traits::GetVFormatFunction(strFormat);
typename Traits::fnc_tvcprintf* vformat_count = Traits::GetVFormatCountFunction(strFormat);
uint32_t nSizeNeeded = vformat_count(strFormat, arg);
uint32_t nUsedSize = GetLength();
uint32_t nTotalSize = nUsedSize + nSizeNeeded;
PrepareBuffer(nTotalSize);
vformat_s(m_pUnusedStart, m_nSize - GetLength(), strFormat, arg);
m_pUnusedStart = m_pData + StrTraits<T>::GetLength(m_pData);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Init()
{
m_nSize = nDefaultSize;
m_pUnusedStart = m_pData = new T[m_nSize];
*m_pData = 0;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::CopyStrLowLevel(T* strDst, uint32_t nDstSize, const T* strSrc, T** pUnusedPtr) const
{
uint32_t nSize = StrTraits<T>::GetLength(strSrc) + 1;
memcpy_s(strDst, nDstSize * sizeof(T), strSrc, nSize * sizeof(T));
if (pUnusedPtr) *pUnusedPtr += (nSize - 1);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::CopyStr(const T* strData)
{
PrepareBuffer( GetLength() + 1 + StrTraits<T>::GetLength(strData) );
CopyStrLowLevel(m_pData, m_nSize, strData, &m_pUnusedStart);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::AppendStr(const T* strData)
{
PrepareBuffer( GetLength() + 1 + StrTraits<T>::GetLength(strData) );
CopyStrLowLevel(m_pUnusedStart, m_nSize, strData, &m_pUnusedStart);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::PrepareBuffer(uint32_t nNeededSize)
{
if (m_nSize - GetLength() < nNeededSize)
{
uint32_t nNewSize = m_nSize + nNeededSize * 2 + nDefaultSize;
T* pTemp = new T[nNewSize];
T* pUnusedTemp = pTemp;
CopyStrLowLevel(pTemp, nNewSize, m_pData, &pUnusedTemp);
this->~CTmplStringBase();
m_pData = pTemp;
m_nSize = nNewSize;
m_pUnusedStart = pUnusedTemp;
}
}
template<typename T, typename Traits> template<typename Type> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::Assign(Type& Data)
{
//m_pUnusedStart = m_pData;
Empty();
*this += Data;
return *this;
}
template<typename T, typename Traits> template<typename Type> CTmplStringBase<T, Traits>& CTmplStringBase<T, Traits>::AppendNum(Type& Data, const T* strFormat)
{
T temp[21];
typename CTmplStringBase<T, Traits>::fnc_tprintf_s* tprintf_s = GetFormatFunction(temp);
tprintf_s(temp, sizeof(temp) / sizeof(T), strFormat, Data);
PrepareBuffer( StrTraits<T>::GetLength(temp) );
AppendStr(temp);
return *this;
}
template<typename T, typename Traits> CTmplStringBase<T, Traits> CTmplStringBase<T, Traits>::Mid(uint32_t nStart, uint32_t nCount) const
{
CTmplStringBase<T, Traits> strTemp;
uint32_t nSize = nCount;
if (nSize == 0)
nCount = nSize = m_pUnusedStart - (m_pData + nStart);
nSize++;
T* pBuffer = strTemp.GetBuffer(nSize);
memcpy_s(pBuffer, nSize * sizeof(T), m_pData + nStart, nCount * sizeof(T));
pBuffer[nSize - 1] = 0;
strTemp.ReleaseBuffer();
return strTemp;
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Format(const T* strFormat, ...)
{
Empty();
va_list arg;
va_start(arg, strFormat);
FormatInternal(strFormat, arg);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::AppendFormat(const T* strFormat, ...)
{
va_list arg;
va_start(arg, strFormat);
FormatInternal(strFormat, arg);
}
template<typename T, typename Traits> void CTmplStringBase<T, Traits>::Empty()
{
m_pUnusedStart = m_pData;
*m_pData = 0;
}
}
//#endif // STRINGEXIMPL_H
#endif // STRINGEX_H
|
| phantomotap is offline | |
| | #45 | ||||
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,783
| Quote:
Quote:
Quote:
But the code compiles! Wonderful! I just need to compare the code and see changes were made and why.
__________________ Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System I dedicated my life to helping others. This is only a small sample of what they said: "Thanks Elysia. You're a programming master! How the hell do you know every thing?" Quoted... at least once. Quote:
| ||||
| Elysia is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Code Review for upcoming contest | Darryl | Contests Board | 2 | 02-28-2006 02:39 PM |
| Problem : Threads WILL NOT DIE!! | hanhao | C++ Programming | 2 | 04-16-2004 01:37 PM |
| True ASM vs. Fake ASM ???? | DavidP | A Brief History of Cprogramming.com | 7 | 04-02-2003 04:28 AM |
| Interface Question | smog890 | C Programming | 11 | 06-03-2002 05:06 PM |
| Who will map the scan code (inserted by VKD_Force_keys) to virtual key code? | Unregistered | Windows Programming | 0 | 02-21-2002 06:05 PM |