2002-10-29 01:27:26 +00:00
|
|
|
/*
|
|
|
|
**********************************************************************
|
|
|
|
* Copyright (c) 2002, International Business Machines
|
|
|
|
* Corporation and others. All Rights Reserved.
|
|
|
|
**********************************************************************
|
|
|
|
**********************************************************************
|
|
|
|
*/
|
|
|
|
#ifndef _NORMPERF_H
|
|
|
|
#define _NORMPERF_H
|
|
|
|
|
|
|
|
#include "uperf.h"
|
|
|
|
#include "unicode/unorm.h"
|
|
|
|
#include "unicode/ustring.h"
|
|
|
|
|
|
|
|
// Stubs for Windows API functions when building on UNIXes.
|
|
|
|
//
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
|
|
|
|
// do nothing
|
|
|
|
#else
|
|
|
|
#define _UNICODE
|
|
|
|
typedef int DWORD;
|
|
|
|
inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define DEST_BUFFER_CAPACITY 6000
|
2003-02-18 21:15:09 +00:00
|
|
|
typedef int32_t (*NormFn)(const UChar* src,int32_t srcLen, UChar* dest,int32_t dstLen, int32_t options, UErrorCode* status);
|
|
|
|
typedef int32_t (*QuickCheckFn)(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status);
|
2002-10-29 01:27:26 +00:00
|
|
|
|
|
|
|
class QuickCheckPerfFunction : public UPerfFunction{
|
|
|
|
private:
|
|
|
|
ULine* lines;
|
|
|
|
int32_t numLines;
|
|
|
|
QuickCheckFn fn;
|
|
|
|
UNormalizationMode mode;
|
|
|
|
int32_t retVal;
|
|
|
|
UBool uselen;
|
|
|
|
const UChar* src;
|
|
|
|
int32_t srcLen;
|
|
|
|
UBool line_mode;
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t options;
|
|
|
|
|
2002-10-29 01:27:26 +00:00
|
|
|
public:
|
2002-11-19 03:20:25 +00:00
|
|
|
virtual void call(UErrorCode* status){
|
2002-10-29 01:27:26 +00:00
|
|
|
if(line_mode==TRUE){
|
|
|
|
if(uselen){
|
|
|
|
for(int32_t i = 0; i< numLines; i++){
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(lines[i].name,lines[i].len,mode, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
}else{
|
|
|
|
for(int32_t i = 0; i< numLines; i++){
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(lines[i].name,-1,mode, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
if(uselen){
|
2002-11-19 03:20:25 +00:00
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(src,srcLen,mode, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}else{
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(src,-1,mode, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
virtual long getOperationsPerIteration(){
|
|
|
|
if(line_mode==TRUE){
|
|
|
|
int32_t totalChars=0;
|
|
|
|
for(int32_t i =0; i< numLines; i++){
|
|
|
|
totalChars+= lines[i].len;
|
|
|
|
}
|
|
|
|
return totalChars;
|
|
|
|
}else{
|
|
|
|
return srcLen;
|
|
|
|
}
|
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
QuickCheckPerfFunction(QuickCheckFn func, ULine* srcLines,int32_t srcNumLines, UNormalizationMode _mode, int32_t opts, UBool _uselen) : options(opts) {
|
2002-10-29 01:27:26 +00:00
|
|
|
fn = func;
|
|
|
|
lines = srcLines;
|
|
|
|
numLines = srcNumLines;
|
|
|
|
uselen = _uselen;
|
|
|
|
mode = _mode;
|
|
|
|
src = NULL;
|
|
|
|
srcLen = 0;
|
|
|
|
line_mode = TRUE;
|
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
QuickCheckPerfFunction(QuickCheckFn func, const UChar* source,int32_t sourceLen, UNormalizationMode _mode, int32_t opts, UBool _uselen) : options(opts) {
|
2002-10-29 01:27:26 +00:00
|
|
|
fn = func;
|
|
|
|
lines = NULL;
|
|
|
|
numLines = 0;
|
|
|
|
uselen = _uselen;
|
|
|
|
mode = _mode;
|
|
|
|
src = source;
|
|
|
|
srcLen = sourceLen;
|
|
|
|
line_mode = FALSE;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class NormPerfFunction : public UPerfFunction{
|
|
|
|
private:
|
|
|
|
ULine* lines;
|
|
|
|
int32_t numLines;
|
|
|
|
UChar dest[DEST_BUFFER_CAPACITY];
|
2002-11-13 20:55:52 +00:00
|
|
|
UChar* pDest;
|
2002-10-29 01:27:26 +00:00
|
|
|
int32_t destLen;
|
|
|
|
NormFn fn;
|
|
|
|
int32_t retVal;
|
|
|
|
UBool uselen;
|
|
|
|
const UChar* src;
|
|
|
|
int32_t srcLen;
|
|
|
|
UBool line_mode;
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t options;
|
2002-10-29 01:27:26 +00:00
|
|
|
|
|
|
|
public:
|
2002-11-19 03:20:25 +00:00
|
|
|
virtual void call(UErrorCode* status){
|
2002-10-29 01:27:26 +00:00
|
|
|
if(line_mode==TRUE){
|
|
|
|
if(uselen){
|
|
|
|
for(int32_t i = 0; i< numLines; i++){
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(lines[i].name,lines[i].len,pDest,destLen, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
}else{
|
|
|
|
for(int32_t i = 0; i< numLines; i++){
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(lines[i].name,-1,pDest,destLen, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
if(uselen){
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(src,srcLen,pDest,destLen, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}else{
|
2003-02-18 21:15:09 +00:00
|
|
|
retVal = (*fn)(src,-1,pDest,destLen, options, status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
virtual long getOperationsPerIteration(){
|
|
|
|
if(line_mode ==TRUE){
|
|
|
|
int32_t totalChars=0;
|
|
|
|
for(int32_t i =0; i< numLines; i++){
|
|
|
|
totalChars+= lines[i].len;
|
|
|
|
}
|
|
|
|
return totalChars;
|
|
|
|
}else{
|
|
|
|
return srcLen;
|
|
|
|
}
|
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
NormPerfFunction(NormFn func, int32_t opts, ULine* srcLines,int32_t srcNumLines,UBool _uselen) : options(opts) {
|
2002-10-29 01:27:26 +00:00
|
|
|
fn = func;
|
|
|
|
lines = srcLines;
|
|
|
|
numLines = srcNumLines;
|
|
|
|
uselen = _uselen;
|
|
|
|
destLen = DEST_BUFFER_CAPACITY;
|
2002-11-13 20:55:52 +00:00
|
|
|
pDest = dest;
|
2002-10-29 01:27:26 +00:00
|
|
|
src = NULL;
|
|
|
|
srcLen = 0;
|
|
|
|
line_mode = TRUE;
|
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
NormPerfFunction(NormFn func, int32_t opts, const UChar* source,int32_t sourceLen,UBool _uselen) : options(opts) {
|
2002-10-29 01:27:26 +00:00
|
|
|
fn = func;
|
|
|
|
lines = NULL;
|
|
|
|
numLines = 0;
|
|
|
|
uselen = _uselen;
|
2002-11-13 20:55:52 +00:00
|
|
|
destLen = sourceLen*3;
|
|
|
|
pDest = (UChar*) malloc(destLen * U_SIZEOF_UCHAR);
|
2002-10-29 01:27:26 +00:00
|
|
|
src = source;
|
|
|
|
srcLen = sourceLen;
|
|
|
|
line_mode = FALSE;
|
2002-11-13 20:55:52 +00:00
|
|
|
}
|
|
|
|
~NormPerfFunction(){
|
|
|
|
if(dest != pDest){
|
|
|
|
free(pDest);
|
|
|
|
}
|
|
|
|
}
|
2002-10-29 01:27:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NormalizerPerformanceTest : public UPerfTest{
|
|
|
|
private:
|
|
|
|
ULine* NFDFileLines;
|
|
|
|
ULine* NFCFileLines;
|
|
|
|
UChar* NFDBuffer;
|
|
|
|
UChar* NFCBuffer;
|
2002-11-19 03:20:25 +00:00
|
|
|
UChar* origBuffer;
|
|
|
|
int32_t origBufferLen;
|
2002-10-29 01:27:26 +00:00
|
|
|
int32_t NFDBufferLen;
|
|
|
|
int32_t NFCBufferLen;
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t options;
|
2002-10-29 01:27:26 +00:00
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
void normalizeInput(ULine* dest,const UChar* src ,int32_t srcLen,UNormalizationMode mode, int32_t options);
|
|
|
|
UChar* normalizeInput(int32_t& len, const UChar* src ,int32_t srcLen,UNormalizationMode mode, int32_t options);
|
2002-10-29 01:27:26 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
NormalizerPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status);
|
|
|
|
~NormalizerPerformanceTest();
|
|
|
|
virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par = NULL);
|
|
|
|
/* NFC performance */
|
|
|
|
UPerfFunction* TestICU_NFC_NFD_Text();
|
|
|
|
UPerfFunction* TestICU_NFC_NFC_Text();
|
|
|
|
UPerfFunction* TestICU_NFC_Orig_Text();
|
|
|
|
|
|
|
|
/* NFD performance */
|
|
|
|
UPerfFunction* TestICU_NFD_NFD_Text();
|
|
|
|
UPerfFunction* TestICU_NFD_NFC_Text();
|
|
|
|
UPerfFunction* TestICU_NFD_Orig_Text();
|
|
|
|
|
|
|
|
/* FCD performance */
|
|
|
|
UPerfFunction* TestICU_FCD_NFD_Text();
|
|
|
|
UPerfFunction* TestICU_FCD_NFC_Text();
|
|
|
|
UPerfFunction* TestICU_FCD_Orig_Text();
|
|
|
|
|
|
|
|
/*Win NFC performance */
|
|
|
|
UPerfFunction* TestWin_NFC_NFD_Text();
|
|
|
|
UPerfFunction* TestWin_NFC_NFC_Text();
|
|
|
|
UPerfFunction* TestWin_NFC_Orig_Text();
|
|
|
|
|
|
|
|
/* Win NFD performance */
|
|
|
|
UPerfFunction* TestWin_NFD_NFD_Text();
|
|
|
|
UPerfFunction* TestWin_NFD_NFC_Text();
|
|
|
|
UPerfFunction* TestWin_NFD_Orig_Text();
|
|
|
|
|
|
|
|
/* Quick check performance */
|
|
|
|
UPerfFunction* TestQC_NFC_NFD_Text();
|
|
|
|
UPerfFunction* TestQC_NFC_NFC_Text();
|
|
|
|
UPerfFunction* TestQC_NFC_Orig_Text();
|
|
|
|
|
|
|
|
UPerfFunction* TestQC_NFD_NFD_Text();
|
|
|
|
UPerfFunction* TestQC_NFD_NFC_Text();
|
|
|
|
UPerfFunction* TestQC_NFD_Orig_Text();
|
|
|
|
|
|
|
|
UPerfFunction* TestQC_FCD_NFD_Text();
|
|
|
|
UPerfFunction* TestQC_FCD_NFC_Text();
|
|
|
|
UPerfFunction* TestQC_FCD_Orig_Text();
|
|
|
|
|
|
|
|
/* IsNormalized performnace */
|
|
|
|
UPerfFunction* TestIsNormalized_NFC_NFD_Text();
|
|
|
|
UPerfFunction* TestIsNormalized_NFC_NFC_Text();
|
|
|
|
UPerfFunction* TestIsNormalized_NFC_Orig_Text();
|
|
|
|
|
|
|
|
UPerfFunction* TestIsNormalized_NFD_NFD_Text();
|
|
|
|
UPerfFunction* TestIsNormalized_NFD_NFC_Text();
|
|
|
|
UPerfFunction* TestIsNormalized_NFD_Orig_Text();
|
|
|
|
|
|
|
|
UPerfFunction* TestIsNormalized_FCD_NFD_Text();
|
|
|
|
UPerfFunction* TestIsNormalized_FCD_NFC_Text();
|
|
|
|
UPerfFunction* TestIsNormalized_FCD_Orig_Text();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
// Platform / ICU version specific proto-types
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
#if (U_ICU_VERSION_MAJOR_NUM > 1 ) || ((U_ICU_VERSION_MAJOR_NUM == 1 )&&(U_ICU_VERSION_MINOR_NUM > 8) && (U_ICU_VERSION_PATCHLEVEL_NUM >=1))
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UNORM_NFD, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UNORM_NFC, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFKD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UNORM_NFKD, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFKC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UNORM_NFKC, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormFCD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UNORM_FCD, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUQuickCheck(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
|
|
|
|
#if (U_ICU_VERSION_MAJOR_NUM > 2 ) || ((U_ICU_VERSION_MAJOR_NUM == 2 )&&(U_ICU_VERSION_MINOR_NUM >= 6))
|
2003-02-26 01:45:06 +00:00
|
|
|
return unorm_quickCheckWithOptions(src,srcLen,mode, options, status);
|
2003-02-18 21:15:09 +00:00
|
|
|
#else
|
2002-10-29 01:27:26 +00:00
|
|
|
return unorm_quickCheck(src,srcLen,mode,status);
|
2003-02-18 21:15:09 +00:00
|
|
|
#endif
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUIsNormalized(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
|
2002-10-29 01:27:26 +00:00
|
|
|
return unorm_isNormalized(src,srcLen,mode,status);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UCOL_DECOMP_CAN, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UCOL_COMPOSE_CAN, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFKD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UCOL_DECOMP_COMPAT, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormNFKC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UCOL_COMPOSE_COMPAT, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUNormFCD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
|
|
|
return unorm_normalize(src,srcLen,UNORM_FCD, options,dest,dstLen,status);
|
2002-10-29 01:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUQuickCheck(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
|
2002-10-29 01:27:26 +00:00
|
|
|
return unorm_quickCheck(src,srcLen,mode,status);
|
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t ICUIsNormalized(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
|
2002-10-29 01:27:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return FoldStringW(MAP_COMPOSITE,src,srcLen,dest,dstLen);
|
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return FoldStringW(MAP_PRECOMPOSED,src,srcLen,dest,dstLen);
|
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFKD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return FoldStringW(MAP_COMPOSITE+MAP_FOLDCZONE,src,srcLen,dest,dstLen);
|
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFKC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return FoldStringW(MAP_FOLDCZONE,src,srcLen,dest,dstLen);
|
|
|
|
}
|
|
|
|
#else
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return 0 ;
|
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFKD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2003-02-18 21:15:09 +00:00
|
|
|
int32_t WinNormNFKC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
|
2002-10-29 01:27:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#endif // NORMPERF_H
|