Created
April 16, 2024 18:30
-
-
Save gekka/363103a8ac8d53f9458ceb9bacad719f to your computer and use it in GitHub Desktop.
Unicodeを書記素で切り出せるCStringを試す
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// pch.h: プリコンパイル済みヘッダー ファイルです。 | |
// 次のファイルは、その後のビルドのビルド パフォーマンスを向上させるため 1 回だけコンパイルされます。 | |
// コード補完や多くのコード参照機能などの IntelliSense パフォーマンスにも影響します。 | |
// ただし、ここに一覧表示されているファイルは、ビルド間でいずれかが更新されると、すべてが再コンパイルされます。 | |
// 頻繁に更新するファイルをここに追加しないでください。追加すると、パフォーマンス上の利点がなくなります。 | |
#ifndef PCH_H | |
#define PCH_H | |
#define CString CStringDef | |
// プリコンパイルするヘッダーをここに追加します | |
#include "framework.h" | |
#include <icu.h> | |
#pragma comment(lib, "icu.lib") | |
#undef CString | |
template< typename BaseType, class StringTraits > | |
class CStringExT : public ATL::CStringT<BaseType, StringTraits> { | |
using CStringT::CStringT; | |
private: | |
int32_t GraphemeLength(UBreakIterator* pIterator) | |
{ | |
LPCWSTR p = GetBuffer(); | |
int32_t count = 0; | |
int32_t temp; | |
while (UBRK_DONE != (temp = ubrk_next(pIterator))) { | |
count++; | |
if (p[temp] == L'\0') | |
{//末尾を超えて列挙してしまうバグがある? | |
//break; | |
} | |
} | |
return count; | |
}; | |
public: | |
int32_t GraphemeLength() | |
{ | |
CStringDef d; | |
d.GetBuffer(); | |
LPCWSTR p = GetBuffer(); | |
UErrorCode errcode; | |
UBreakIterator* pIterator = ubrk_open(UBRK_CHARACTER, ULOC_JAPAN, (UChar const*)p, -1, &errcode); | |
uint32_t count = GraphemeLength(pIterator); | |
return count; | |
}; | |
CStringExT GraphemeMid(int32_t iFirst, int32_t nCount) | |
{ | |
LPCWSTR p = GetBuffer(); | |
UErrorCode errcode; | |
UBreakIterator* pIterator = ubrk_open(UBRK_CHARACTER, ULOC_JAPAN, (UChar const*)p, -1, &errcode); | |
ubrk_first(pIterator); | |
int32_t start = skipGrapheme(pIterator, iFirst, p); | |
int32_t end = skipGrapheme(pIterator, nCount, p); | |
ubrk_close(pIterator); | |
return CStringT::Mid(start, end - start); | |
}; | |
CStringExT GraphemeMid(int32_t iFirst) | |
{ | |
LPCWSTR p = GetBuffer(); | |
UErrorCode errcode; | |
UBreakIterator* pIterator = ubrk_open(UBRK_CHARACTER, ULOC_JAPAN, (UChar const*)p, -1, &errcode); | |
ubrk_first(pIterator); | |
int32_t start = skipGrapheme(pIterator, iFirst, p); | |
ubrk_close(pIterator); | |
return CStringT::Mid(start); | |
}; | |
CStringExT GraphemeLeft(int32_t count) { | |
LPCWSTR p = GetBuffer(); | |
UErrorCode errcode; | |
UBreakIterator* pIterator = ubrk_open(UBRK_CHARACTER, ULOC_JAPAN, (UChar const*)p, -1, &errcode); | |
int32_t start = ubrk_first(pIterator); | |
int32_t end = skipGrapheme(pIterator, count, p); | |
ubrk_close(pIterator); | |
return CStringT::Mid(start, end - start); | |
}; | |
CStringExT GraphemeRight(int32_t count) | |
{ | |
CString ret; | |
LPCWSTR p = GetBuffer(); | |
UErrorCode errcode; | |
UBreakIterator* pIterator = ubrk_open(UBRK_CHARACTER, ULOC_JAPAN, (UChar const*)p, -1, &errcode); | |
int index = ubrk_first(pIterator); | |
int len = GraphemeLength(pIterator); | |
int skipCount = len - count; | |
if (skipCount <= 0) | |
{ | |
ret = CStringExT(p); | |
} | |
else | |
{ | |
ubrk_first(pIterator); | |
int start = skipGrapheme(pIterator, skipCount, p); | |
ret = CStringExT(p + start); | |
} | |
ubrk_close(pIterator); | |
return ret; | |
}; | |
#if OVERRIDE_CSTRING_DEFAULT_METHODS | |
CStringExT Mid(int iFirst) | |
{ | |
//return CStringDef::Mid(iFirst); | |
return GraphemeMid(iFirst); | |
} | |
CStringExT Mid(int iFirst, int nCount) | |
{ | |
//return CStringDef::Mid(iFirst,nCount); | |
return GraphemeMid(iFirst, nCount); | |
} | |
CStringExT Left(int nCount) | |
{ | |
//return CStringDef::Left(nCount); | |
return GraphemeLeft(nCount); | |
} | |
CStringExT Right(int nCount) | |
{ | |
//return CStringDef::Right(nCount); | |
return GraphemeRight(nCount); | |
} | |
#endif | |
private: | |
static int32_t skipGrapheme(UBreakIterator* pIterator, int32_t count, LPCWSTR const p = nullptr) | |
{ | |
uint32_t index = ubrk_current(pIterator); | |
while (count--) | |
{ | |
int32_t end = ubrk_next(pIterator); | |
if (end == UBRK_DONE) | |
{ | |
break; | |
} | |
index = end; | |
if (p != nullptr && p[end] == L'\0') | |
{//末尾を超えて列挙してしまうバグがある? | |
break; | |
} | |
} | |
return index; | |
}; | |
}; | |
typedef CStringExT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; | |
#endif //PCH_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment