18#pragma comment(user,"T-Coverage Disable")
25#define _REGEX_TRACE0(S) TRACE0(S)
26#define _REGEX_TRACE1(S,P1) TRACE1(S, P1)
27#define _REGEX_TRACE2(S,P1,P2) TRACE2(S,P1,P2)
28#define _REGEX_TRACE3(S,P1,P2,P3) TRACE3(S,P1,P2,P3)
30#define _REGEX_TRACE0(S)
31#define _REGEX_TRACE1(S,P1)
32#define _REGEX_TRACE2(S,P1,P2)
33#define _REGEX_TRACE3(S,P1,P2,P3)
161template<
typename TYP,
typename ITE = const TYP*>
182 class CAbstractChecker
192 TPairIterator(ITE s = ITE(), ITE e = ITE(),
bool r =
false)
193 : top(s), end(e), boValidEnd(r)
212 TStaticParam(
void) : end(ITE()), tempEnd(ITE()), option(0)
215 size_t GetSize(
void)
const
217 return groupIterators.
GetSize();
219 TPairIterator At(INDEX index)
const
221 const TPairIterator& ii = groupIterators.
At(index);
222 TPairIterator r((index == 0 && outsizeEnd != ITE()) ? outsizeEnd : ii.top);
223 r.SetEnd(ii.boValidEnd ? ii.end : tempEnd);
230 loop ( i, GetSize() )
232 const TPairIterator& ii = At(i);
245 TParam(ITE c, ITE t, ITE e, TStaticParam* p) : cur(c), top(t), pt(p)
249 pt->outsizeEnd = ITE();
252 bool IsTerminate(
void)
const
254 return (cur == pt->end) ? true : (*cur == 0);
257 size_t GetWord(WORD& _ch)
259 if ( IsTerminate() ){
return INVALID_SIZE; }
264 ASSERT(
sizeof(TYP) == 1 );
266 if ( IsTerminate() ){
return INVALID_SIZE; }
267 c =
static_cast<WORD
>(((c & 0xFF) << 8) | ((*cur) & 0xFF));
273 void StepCur(
size_t l)
275 if ( l != INVALID_SIZE )
279 ASSERTLIB( cur != pt->end );
285 bool EqualChar(TYP c1, TYP c2)
289 if ( c1 >=
'A' && c1 <=
'Z' ) { c1 |= 0x20; }
290 if ( c2 >=
'A' && c2 <=
'Z' ) { c2 |= 0x20; }
296 virtual ~CAbstractChecker(
void){}
303 virtual size_t Check(TParam ip)
const = 0;
317 class CEqualChar :
public CAbstractChecker
322 CEqualChar(WORD c) : m_char(c)
326 virtual size_t Check(TParam ip)
const
328 _REGEX_TRACE1(
"正規表現 比較 ; EqualChar [0x%X]\n", m_char );
330 size_t l = ip.GetWord(c);
331 if ( l == INVALID_SIZE ){
return INVALID_SIZE; }
332 bool r = ip.EqualChar(
static_cast<TYP
>(c),
static_cast<TYP
>(m_char));
333 return r ? l : INVALID_SIZE;
341 class CRangeChar :
public CAbstractChecker
348 CRangeChar(WORD top, WORD bottom,
bool boIsReverse =
false)
349 : m_top(top), m_bottom(bottom), m_reverse(boIsReverse)
351 if ( m_top > m_bottom ) {
Swap(m_top, m_bottom); }
354 virtual size_t Check(TParam ip)
const
356 _REGEX_TRACE3(
"正規表現 比較 ; RangeChar ['%c' - '%c' (%d)]\n", m_top, m_bottom, m_reverse );
358 size_t l = ip.GetWord(c);
359 if ( l == INVALID_SIZE ){
return INVALID_SIZE; }
362 if ( (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') )
365 return ((c < (m_top|0x20) || c > (m_bottom|0x20)) ^ m_reverse) ? INVALID_SIZE : l;
368 return ((c < m_top || c > m_bottom) ^ m_reverse) ? INVALID_SIZE : l;
374 class CAnythingChar :
public CAbstractChecker
378 virtual size_t Check(TParam ip)
const
380 _REGEX_TRACE0(
"正規表現 比較 ; AnythingChar\n" );
387 class CTop :
public CAbstractChecker
391 virtual size_t Check(TParam ip)
const
393 _REGEX_TRACE0(
"正規表現 比較 ; Top\n" );
394 return (ip.cur == ip.top) ? 0 : INVALID_SIZE;
400 class CEnd :
public CAbstractChecker
404 virtual size_t Check(TParam ip)
const
406 _REGEX_TRACE0(
"正規表現 比較 ; End\n" );
407 return ip.IsTerminate() ? 0 : INVALID_SIZE;
413 class CFrontWord :
public CAbstractChecker
417 CFrontWord(INDEX i) : m_index(i)
421 virtual size_t Check(TParam ip)
const
423 _REGEX_TRACE1(
"正規表現 比較 ; FrontWord (index = %d)\n", m_index );
424 if ( ip.pt->groupIterators.GetSize() <= m_index )
428 const TPairIterator& ii = ip.pt->groupIterators.At(m_index);
430 ITE ie = ii.boValidEnd ? ii.end : ip.pt->tempEnd;
439 if ( *is == 0 ) {
break; }
440 if ( ip.cur == ip.pt->end ) {
return INVALID_SIZE; }
441 if ( ! ip.EqualChar(*is++, *ip.cur++) ){
return INVALID_SIZE; }
454 class CGroupChecker :
public CAbstractChecker
469 CCheckerPtr m_checker;
472 CGroupChecker(CCheckerPtr cp, EType y = ET_RefGroup) : m_checker(cp), m_type(y)
474 ASSERTLIB( y != ET_Non );
477 virtual size_t Check(TParam ip)
const
479 _REGEX_TRACE1(
"正規表現 比較 ; GroupChecker (%d)\n", m_type );
480 if ( m_type == ET_RefGroup )
482 INDEX insertIndex = ip.pt->groupIterators.GetSize();
483 ip.pt->groupIterators.Add(TPairIterator(ip.cur, ip.pt->end));
484 size_t l = m_checker->Check(ip);
485 if ( l != INVALID_SIZE )
488 ip.pt->groupIterators.Ref(insertIndex).SetEnd(ip.cur);
492 size_t l = m_checker->Check(ip);
502 l = (l != INVALID_SIZE) ? 0 : INVALID_SIZE;
505 l = (l == INVALID_SIZE) ? 0 : INVALID_SIZE;
509 if ( ip.pt->outsizeEnd != ITE() )
515 if ( l != INVALID_SIZE )
518 ip.pt->outsizeEnd = ip.cur;
520 if ( m_type == ET_BeforeNeq )
522 l = (l == INVALID_SIZE) ? 0 : INVALID_SIZE;
537 class CFindChecker :
public CAbstractChecker
539 CCheckerPtr m_loopChecker;
540 CCheckerPtr m_markChecker;
546 CFindChecker(CCheckerPtr loopChk,
int min,
int max,
bool mini)
547 : m_loopChecker(loopChk), m_min(min), m_max(max), m_isMini(mini)
550 void SetMarkChecker(CCheckerPtr cp)
552 ASSERTLIB(
this != cp.operator->() );
556 virtual size_t Check(TParam ip)
const
559 ITE bakIte = ip.pt->tempEnd;
560 size_t ns = ip.pt->groupIterators.
GetSize();
561 ip.pt->tempEnd = ip.cur;
562 if ( m_markChecker.IsNull() )
564 _REGEX_TRACE2(
"正規表現 比較 ; FindChecker(%d 〜 %d) 「ENDかMAXまで」\n", m_min, m_max);
565 INDEX findingIndex = 0;
569 if ( m_max >= 0 && foundCount == m_max ) {
break; }
570 if ( m_isMini && m_min <= foundCount ) {
break; }
571 size_t l = m_loopChecker->Check(ip);
572 if ( ns < ip.pt->groupIterators.
GetSize() )
574 if ( l != INVALID_SIZE )
576 bakGrpItes = ip.pt->groupIterators;
578 ip.pt->groupIterators.
SetSize(ns);
580 if ( l == INVALID_SIZE ) {
break; }
582 ip.pt->tempEnd = ip.cur;
586 ip.pt->tempEnd = bakIte;
589 ip.pt->groupIterators = bakGrpItes;
591 return (foundCount < m_min) ? INVALID_SIZE : findingIndex;
593 _REGEX_TRACE2(
"正規表現 比較 ; FindChecker(%d 〜 %d) 「次一致」\n", m_min, m_max);
594 INDEX findingIndex = 0;
595 INDEX foundIndex = INVALID_INDEX;
597 while ( ! ip.IsTerminate() )
599 if ( foundCount >= m_min )
601 size_t l = m_markChecker->Check(ip);
602 if ( l != INVALID_SIZE )
604 foundIndex = findingIndex;
605 if ( m_isMini ) {
break; }
607 ns = ip.pt->groupIterators.GetSize();
609 if ( m_max >= 0 && foundCount == m_max ) {
break; }
610 size_t l = m_loopChecker->Check(ip);
611 if ( ns < ip.pt->groupIterators.
GetSize() )
613 if ( l != INVALID_SIZE )
615 bakGrpItes = ip.pt->groupIterators;
617 ip.pt->groupIterators.
SetSize(ns);
619 if ( l == INVALID_SIZE ) {
break; }
621 ip.pt->tempEnd = ip.cur;
625 ip.pt->tempEnd = bakIte;
628 ip.pt->groupIterators = bakGrpItes;
630 return (foundCount < m_min) ? INVALID_SIZE : foundIndex;
637 class CAnyChecker :
public CAbstractChecker
640 CCheckerPtrsVector m_checkers;
643 virtual bool IsMeaningless(
void)
const
645 return m_checkers.
GetSize() == 1;
648 virtual CCheckerPtr& Top(
void)
650 return m_checkers[0];
653 virtual void Add(CCheckerPtr chk)
658 virtual size_t Check(TParam ip)
const
660 _REGEX_TRACE1(
"正規表現 比較 ; AnyChecker(%d)\n", m_checkers.GetSize() );
661 size_t r = INVALID_SIZE;
662 loop ( i, m_checkers.GetSize() )
664 size_t l = m_checkers[i]->Check(ip);
665 if ( l != INVALID_SIZE )
667 if ( r == INVALID_SIZE ) { r = 0; }
668 if ( r < l ) { r = l; }
678 class CNotAnyChecker :
public CAnyChecker
682 virtual bool IsMeaningless(
void)
const
687 virtual size_t Check(TParam ip)
const
689 _REGEX_TRACE1(
"正規表現 比較 ; NotAnyChecker(%d)\n", m_checkers.GetSize() );
690 if ( ip.IsTerminate() ){
return INVALID_SIZE; }
691 loop ( i, m_checkers.GetSize() )
693 size_t l = m_checkers[i]->Check(ip);
694 if ( l != INVALID_SIZE ) {
return INVALID_SIZE; }
704 class CBesidesChecker :
public CAnyChecker
708 virtual size_t Check(TParam ip)
const
710 _REGEX_TRACE1(
"正規表現 比較 ; BesidesChecker(%d)\n", m_checkers.GetSize() );
711 size_t r = INVALID_SIZE;
712 loop ( i, m_checkers.GetSize() )
714 size_t l = m_checkers[i]->Check(ip);
715 if ( l == INVALID_SIZE ) {
return INVALID_SIZE; }
716 if ( r == INVALID_SIZE )
732 class CLineChecker :
public CAnyChecker
736 virtual size_t Check(TParam ip)
const
738 _REGEX_TRACE1(
"正規表現 比較 ; LineChecker(%d)\n", m_checkers.GetSize() );
739 ASSERTLIB( m_checkers.GetSize() != 0 );
741 loop ( i, m_checkers.GetSize() )
743 size_t l = m_checkers[i]->Check(ip);
744 if ( l == INVALID_SIZE ) {
return INVALID_SIZE; }
758 CFindChecker* m_pLastFindChecker;
762 void m_RemoveAll(
void)
766 m_pLastFindChecker = NULL;
772 bool m_SubNum(
int& _r,
const WORD*& _lpsz)
775 const WORD* P =_lpsz;
776 while( *P >=
'0' && *P <=
'9' )
778 if ( _r < 0 ) { _r = 0; }
795 bool m_SubCnt(
int& _min,
int& _max,
const WORD*& _lpsz)
797 const WORD* P =_lpsz;
801 if ( m_SubNum(r, P) )
812 if ( m_SubNum(r, P) )
831 CCheckerPtr m_ChkChecker(CAnyChecker* P)
833 if ( P->IsMeaningless() )
835 CCheckerPtr c = P->Top();
852 bool m_Sub(CCheckerPtr& _checker,
const WORD*& _lpsz,
bool isAny)
854 CFindChecker* pLastFindChecker = m_pLastFindChecker;
855 m_pLastFindChecker = NULL;
856 CAnyChecker* pCheckers = NULL;
857 const WORD* P = _lpsz;
863 pCheckers =
new CNotAnyChecker();
867 pCheckers =
new CAnyChecker();
872 pCheckers =
new CLineChecker();
874 bool isError =
false;
881 CGroupChecker::EType groupType = CGroupChecker::ET_Non;
882 CFindChecker* pLastFind = NULL;
890 chk =
new CAnythingChar();
893 groupType = CGroupChecker::ET_RefGroup;
898 groupType = CGroupChecker::ET_NoRefGroup;
901 else if ( P[1] ==
'=' )
903 groupType = CGroupChecker::ET_AfterEqu;
906 else if ( P[1] ==
'!' )
908 groupType = CGroupChecker::ET_AfterNeq;
911 else if ( P[1] ==
'<' && P[2] ==
'=' )
913 groupType = CGroupChecker::ET_BeforeEqu;
916 else if ( P[1] ==
'<' && P[2] ==
'!' )
918 groupType = CGroupChecker::ET_BeforeNeq;
922 if ( ! m_Sub(chk, P,
false) || *P !=
')' )
924 groupType = CGroupChecker::ET_Non;
929 pLastFind = m_pLastFindChecker;
930 m_pLastFindChecker = NULL;
933 _checker = m_ChkChecker(pCheckers);
934 if ( pLastFindChecker != NULL )
936 pLastFindChecker->SetMarkChecker(_checker);
942 CFindChecker* pCkBack = m_pLastFindChecker;
943 m_pLastFindChecker = NULL;
945 if ( m_Sub(cp, P,
false) && (*P == 0 || *P ==
')') )
947 m_pLastFindChecker = pCkBack;
948 CAnyChecker* a =
new CAnyChecker();
949 a->Add(m_ChkChecker(pCheckers));
952 if ( pLastFindChecker != NULL )
954 pLastFindChecker->SetMarkChecker(_checker);
978 if ( isError ) {
break; }
985 if ( isFirst && isAny )
989 else if ( ! m_Sub(chk, P,
true) || *P !=
']' )
996 pLastFind = m_pLastFindChecker;
997 m_pLastFindChecker = NULL;
1001 if ( isFirst && isAny )
1005 _checker = m_ChkChecker(pCheckers);
1006 if ( pLastFindChecker != NULL )
1008 pLastFindChecker->SetMarkChecker(_checker);
1013 _checker = m_ChkChecker(pCheckers);
1014 if ( pLastFindChecker != NULL )
1016 pLastFindChecker->SetMarkChecker(_checker);
1021 if ( isAny && *P ==
'&' )
1024 CFindChecker* pCkBack = m_pLastFindChecker;
1025 m_pLastFindChecker = NULL;
1027 if ( m_Sub(cp, P,
false) && *P ==
']' )
1029 m_pLastFindChecker = pCkBack;
1030 CAnyChecker* a =
new CBesidesChecker();
1031 a->Add(m_ChkChecker(pCheckers));
1034 if ( pLastFindChecker != NULL )
1036 pLastFindChecker->SetMarkChecker(_checker);
1045 ASSERTLIB( chk.IsNull() );
1051 chk =
new CRangeChar(
'0',
'9', (c ==
'D'));
1056 CAnyChecker* pAny = (c ==
's') ?
new CAnyChecker() :
new CNotAnyChecker();
1057 const char ap[] = {
' ',
'\t',
'\n',
'\x0B',
'\f',
'\r' };
1058 loop ( i, countof(ap) )
1060 pAny->Add(
new CEqualChar(ap[i]));
1068 CAnyChecker* pAny = (c ==
'w') ?
new CAnyChecker() :
new CNotAnyChecker();
1069 pAny->Add(
new CRangeChar(
'a',
'z'));
1070 pAny->Add(
new CRangeChar(
'A',
'Z'));
1071 pAny->Add(
new CRangeChar(
'0',
'9'));
1072 pAny->Add(
new CEqualChar(
'_'));
1081 c =
static_cast<WORD
>(r);
1086 if ( c >=
'0' && c <=
'9' )
1088 chk =
new CFrontWord(c -
'0');
1098 if ( isError ) {
break; }
1112 d =
static_cast<WORD
>(r);
1119 chk =
new CRangeChar(c, d);
1123 chk =
new CEqualChar(c);
1126 if ( isError ) {
break; }
1128 if ( ! chk.IsNull() )
1130 if ( rangeChar != 0 )
1154 if ( ! m_SubCnt(min, max, P) )
1165 bool isMini =
false;
1171 if ( groupType != CGroupChecker::ET_Non )
1173 chk =
new CGroupChecker(chk, groupType);
1174 groupType = CGroupChecker::ET_Non;
1176 pLastFind =
new CFindChecker(chk, min, max, isMini);
1180 if ( ! chk.IsNull() )
1182 if ( groupType != CGroupChecker::ET_Non )
1184 chk =
new CGroupChecker(chk, groupType);
1185 groupType = CGroupChecker::ET_Non;
1187 if ( m_pLastFindChecker != NULL )
1189 m_pLastFindChecker->SetMarkChecker(chk);
1191 m_pLastFindChecker = pLastFind;
1193 pCheckers->Add(chk);
1211 size_t m_MatchSize(
typename CAbstractChecker::TParam ip,
CVectorT<
CStrT<TYP> >* pGroupStr)
const
1213 if ( m_root.IsNull() )
1215 return INVALID_SIZE;
1217 size_t l = m_root->Check(ip);
1218 if ( ip.pt->outsizeEnd != ITE() )
1222 if ( pGroupStr != NULL )
1224 *pGroupStr = ip.pt->ToStrings();
1262 if ( ! m_Sub(chk, P,
false) )
1272 m_root =
new CGroupChecker(chk);
1289 CAbstractChecker::TStaticParam sp;
1290 sp.option = m_option;
1291 CAbstractChecker::TParam ip(is, is, ie, &sp);
1292 return m_MatchSize(ip, pGroupStr);
1307 CAbstractChecker::TStaticParam sp;
1308 sp.option = m_option;
1309 CAbstractChecker::TParam ip(is, is, ie, &sp);
1310 size_t l = m_MatchSize(ip, pGroupStr);
1311 if ( l == INVALID_SIZE )
1316 return ip.IsTerminate();
1344 CAbstractChecker::TStaticParam sp;
1345 sp.option = m_option;
1346 CAbstractChecker::TParam ip(is, is, ie, &sp);
1348 if ( ! m_root.IsNull() )
1350 while ( ! ip.IsTerminate() )
1353 sp.groupIterators.RemoveAll();
1354 sp.outsizeEnd = ITE();
1358 if ( sp.outsizeEnd != ITE() )
1360 while ( is != ip.cur )
1364 while ( is != sp.outsizeEnd )
1371 if ( pGroupStr != NULL )
1373 *pGroupStr = ip.pt->ToStrings();
1377 if ( sp.outsizeEnd != ITE() )
1379 while ( ip.cur != sp.outsizeEnd )
1396 if ( pGroupStr != NULL )
1398 *pGroupStr = ip.pt->ToStrings();
1426 while ( limit <= 0 ||
static_cast<int>(vs.
GetSize()) < limit - 1 )
1447 for ( INDEX i = vs.
GetSize() - 1; i > 0; i-- )
1449 if ( ! vs[i].IsEmpty() )
1510 : m_foundIndex(0), m_index(0), m_pRegEx(P), m_is(is), m_ie(ie)
1522 return m_pRegEx != NULL;
1533 if ( m_pRegEx != NULL )
1535 m_strDst += m_foundString;
1536 m_foundString.
Empty();
1552 return m_pRegEx != NULL;
1569 while ( *lpsz != 0 )
1576 else if ( *lpsz !=
'\\' )
1584 if ( c >=
'0' && c <=
'9' )
1587 if ( m_foundGroupStr.
GetSize() > i )
1589 s += m_foundGroupStr[i];
1609 return m_foundString;
1628 return m_foundGroupStr;
1637 return m_foundIndex;
1686 friend class CRegularExpressionTest;
1696#pragma comment(user,"T-Coverage Enable")
1703前方参照を行う正規表現グループには、左から右方向に左丸括弧を数えることによって、
1704番号が付けられます。たとえば、表現 ((A)(B(C))) は、次の 4 つのグループに分類さ
1711グループ 0 は、常に表現全体を表します。
1726電話番号 \d{1,4}?-\d{1,4}?-\d{1,4}
1727生年月日 \d{4}-\d{2}-\d{2}
1728メールアドレス [!#-9A-~]+@[a-z0-9-_]+\.+[a-z0-9-_]+\.+[a-z0-9-]
1733前述した通り、 ブラケットに囲まれている中ではほとんどのメタキャラ
1734クタはその特殊な意味を失います。 したがって、 [^(foo)]bar という
1735正規表現もまた、「fooではない文字列に続いてbarという文字列が続くもの」
1736 ではありません。「fでもoでも(でも)でもない文字に続いて barという
1737 文字列が続いたもの」 です。 []の内側では、文字列や(より小さな)
1738 正規表現要素をまとめるというカッコの 特別な意味は失われてしまうと
1749複数行モード *
'^' と
'$' が各行の始まりと終わりにマッチするようになります。
1750.が改行にもマッチするモード *
'.' が改行文字にもマッチするようにします。
1751大文字と小文字を同一視モード * 大文字と小文字を区別しないようにします。
#define loop(VAR, CNT)
loop構文.
const CVectorT< CStrT< TYP > > & GetFoundGroupString(void) const
[取得] マッチしたグループ文字列取得.
bool Replace(const TYP *lpsz)
[置換] 置き換え.
CStrT< TYP > GetString(void) const
[取得] 置換結果文字列取得.
CStrT< TYP > GetFoundString(void) const
[取得] マッチした文字列取得.
bool IsFinding(void) const
[確認] 検索確認
INDEX GetFoundIndex(void) const
[取得] マッチした位置取得.
CFinder(const CRegularExpressionT *P=NULL, ITE is=ITE(), ITE ie=ITE())
コンストラクタ
size_t GetFoundSize(void) const
[取得] マッチした文字列長取得.
bool SetPattern(const TYP *lpsz)
[設定] パターン設定.
CFinder GetFinder(ITE is, ITE ie=ITE()) const
[取得] ファインダー取得.
TFindResult Find(ITE is, ITE ie=ITE(), CVectorT< CStrT< TYP > > *pGroupStr=NULL) const
[検索] 検索
CVectorT< CStrT< TYP > > Split(ITE is, ITE ie=ITE(), int limit=0) const
[取得] 分割.
bool Matches(ITE is, ITE ie=ITE(), CVectorT< CStrT< TYP > > *pGroupStr=NULL) const
[比較] 全体マッチ
CRegularExpressionT(void)
コンストラクタ
CStrT< TYP > ReplaceAll(const TYP *lpsz, ITE is, ITE ie=ITE()) const
[置換] 置き換え.
void SetOption(DWORD dw)
[設定] オプション設定.
@ IGNORECASE
「欧文の大文字と小文字を区別しない」オプション
size_t LookingAt(ITE is, ITE ie=ITE(), CVectorT< CStrT< TYP > > *pGroupStr=NULL) const
[比較] 先頭マッチ
size_t GetLength(void) const
[取得] 文字列長
static CStrT FromIterator(ITE is, ITE ie=ITE(), size_t max=INVALID_SIZE)
[代入] イテレータ代入.
virtual size_t GetSize(void) const
[取得] サイズ取得
virtual bool Remove(INDEX index)
[削除] 要素一つ削除.
virtual const TYP & At(INDEX index) const
[取得] 要素の参照取得.
virtual bool SetSize(size_t size)
[操作] サイズ指定
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
int GetCharSize(char c)
[取得] 文字のサイズ(ASCII/SJIS用)
CWordVector StringToWordVector(LPCSTR lpszAscii)
[変換] ASCII文字列→文字単位配列
int EscCharToInt(const TYP *&_lpsz)
[変換] エスケープ文字表記変換
void Swap(T &t1, T &t2)
[変換] スワッパー.
bool IsEmpty(void) const
[確認] 要素の有無確認.