00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef STRINGUTILITIESMACROS_H__
00011 #define STRINGUTILITIESMACROS_H__
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "StringUtilities.h"
00043 #include <algorithm>
00044 #include <boost/tuple/tuple.hpp>
00045 #include <limits>
00046 #include <string>
00047 #include <vector>
00048
00049 using namespace std;
00050
00051 template<typename T>
00052 std::string convertVectorToString(const std::vector<T>& vec, bool* pError, std::string sep, bool forDisplay)
00053 {
00054 bool error = false;
00055 if (pError != NULL)
00056 {
00057 *pError = false;
00058 }
00059 string vecString = "";
00060 for (typename vector<T>::const_iterator iter = vec.begin(); iter != vec.end(); ++iter)
00061 {
00062 string curVal;
00063 if (forDisplay)
00064 {
00065 curVal = StringUtilities::toDisplayString(*iter, &error);
00066 }
00067 else
00068 {
00069 curVal = StringUtilities::toXmlString(*iter, &error);
00070 }
00071 if (error)
00072 {
00073 if (pError != NULL)
00074 {
00075 *pError = true;
00076 }
00077 return "";
00078 }
00079 vecString += curVal;
00080 if ( (iter + 1) != vec.end())
00081 {
00082 vecString += sep;
00083 }
00084 }
00085 return vecString;
00086 }
00087
00088 template<class T>
00089 std::vector<T> convertStringToVector(string value, bool* pError, std::string sep, bool forDisplay)
00090 {
00091 vector<T> retValues;
00092 bool parsing = true;
00093 bool error = false;
00094 string::size_type lastIndex = 0;
00095 if (pError != NULL)
00096 {
00097 *pError = false;
00098 }
00099 if (value.empty())
00100 {
00101 return retValues;
00102 }
00103 while (parsing)
00104 {
00105 string::size_type index = value.find(sep, lastIndex);
00106 if (index == string::npos)
00107 {
00108 index = value.size();
00109 }
00110 string token = value.substr(lastIndex, (index - lastIndex));
00111 T parsedValue;
00112 if (forDisplay)
00113 {
00114 parsedValue = StringUtilities::fromDisplayString<T>(token, &error);
00115 }
00116 else
00117 {
00118 parsedValue = StringUtilities::fromXmlString<T>(token, &error);
00119 }
00120 if (error)
00121 {
00122 if (pError != NULL)
00123 {
00124 *pError = true;
00125 }
00126 retValues.clear();
00127 return retValues;
00128 }
00129 retValues.push_back(parsedValue);
00130 lastIndex = index + sep.size();
00131 if (index == value.size())
00132 {
00133 parsing = false;
00134 }
00135 }
00136
00137 return retValues;
00138 }
00139
00140 template<int tupleIndex, typename CompareType>
00141 class FindTupleValue
00142 {
00143 public:
00144 FindTupleValue(CompareType valueToFind) : mValue(valueToFind)
00145 {
00146 }
00147
00148 template<typename tupleType>
00149 bool operator()(tupleType compareValue)
00150 {
00151 return compareValue.DISAMBIGUATE_TEMPLATE get<tupleIndex>() == mValue;
00152 }
00153
00154 private:
00155 CompareType mValue;
00156 };
00157
00158 #define ENUM_MAPPING_TO_DISPLAY_STRING(eName__, eAlias__) \
00159 template<>\
00160 std::string toDisplayString(const eName__& val, bool* pError)\
00161 {\
00162 eAlias__##Mapping values = get##eAlias__##Mapping();\
00163 eAlias__##Mapping::iterator foundValue;\
00164 foundValue = std::find_if(values.begin(), values.end(), FindTupleValue<0, eName__>(val));\
00165 if (foundValue != values.end())\
00166 {\
00167 if (pError != NULL)\
00168 {\
00169 *pError = false;\
00170 }\
00171 return foundValue->get<1>();\
00172 }\
00173 if (pError != NULL)\
00174 {\
00175 *pError = true;\
00176 }\
00177 return "";\
00178 }\
00179 template<>\
00180 std::string toDisplayString(const eName__::EnumType& val, bool* pError)\
00181 {\
00182 return toDisplayString(EnumWrapper<eName__::EnumType>(val), pError);\
00183 }\
00184
00185 #define ENUM_MAPPING_TO_DISPLAY_STRING_VEC(eName__) \
00186 template<>\
00187 std::string toDisplayString(const vector<eName__>& vec, bool* pError)\
00188 {\
00189 return convertVectorToString(vec, pError, ", ", true);\
00190 }\
00191
00192 #define ENUM_MAPPING_TO_XML_STRING(eName__, eAlias__) \
00193 template<>\
00194 std::string toXmlString(const eName__& val, bool* pError)\
00195 {\
00196 eAlias__##Mapping values = get##eAlias__##Mapping();\
00197 eAlias__##Mapping::iterator foundValue;\
00198 foundValue = std::find_if(values.begin(), values.end(), FindTupleValue<0, eName__>(val));\
00199 if (foundValue != values.end())\
00200 {\
00201 if (pError != NULL)\
00202 {\
00203 *pError = false;\
00204 }\
00205 return foundValue->get<2>();\
00206 }\
00207 if (pError != NULL)\
00208 {\
00209 *pError = true;\
00210 }\
00211 return "";\
00212 }\
00213 template<>\
00214 std::string toXmlString(const eName__::EnumType& val, bool* pError)\
00215 {\
00216 return toXmlString(EnumWrapper<eName__::EnumType>(val), pError);\
00217 }\
00218
00219 #define ENUM_MAPPING_TO_XML_STRING_VEC(eName__) \
00220 template<>\
00221 std::string toXmlString(const vector<eName__>& vec, bool* pError)\
00222 {\
00223 return convertVectorToString(vec, pError, ", ", false);\
00224 }\
00225
00226 #define ENUM_MAPPING_FROM_DISPLAY_STRING(eName__, eAlias__) \
00227 template<>\
00228 eName__ fromDisplayString<eName__>(std::string value, bool* pError)\
00229 {\
00230 eAlias__##Mapping values = get##eAlias__##Mapping();\
00231 eAlias__##Mapping::iterator foundValue;\
00232 foundValue = std::find_if(values.begin(), values.end(), FindTupleValue<1, string>(value));\
00233 if (foundValue != values.end())\
00234 {\
00235 if (pError != NULL)\
00236 {\
00237 *pError = false;\
00238 }\
00239 return foundValue->get<0>();\
00240 }\
00241 if (pError != NULL)\
00242 {\
00243 *pError = true;\
00244 }\
00245 return eName__();\
00246 }\
00247
00248 #define ENUM_MAPPING_FROM_DISPLAY_STRING_VEC(eName__) \
00249 template<>\
00250 vector<eName__> fromDisplayString<vector<eName__> >(std::string value, bool* pError)\
00251 {\
00252 return convertStringToVector<eName__>(value, pError, ", ", true);\
00253 }\
00254
00255 #define ENUM_MAPPING_FROM_XML_STRING(eName__, eAlias__) \
00256 template<>\
00257 eName__ fromXmlString<eName__>(std::string value, bool* pError)\
00258 {\
00259 eAlias__##Mapping values = get##eAlias__##Mapping();\
00260 eAlias__##Mapping::iterator foundValue;\
00261 foundValue = std::find_if(values.begin(), values.end(), FindTupleValue<2, string>(value));\
00262 if (foundValue != values.end())\
00263 {\
00264 if (pError != NULL)\
00265 {\
00266 *pError = false;\
00267 }\
00268 return foundValue->get<0>();\
00269 }\
00270 if (pError != NULL)\
00271 {\
00272 *pError = true;\
00273 }\
00274 return eName__();\
00275 }\
00276
00277 #define ENUM_MAPPING_FROM_XML_STRING_VEC(eName__) \
00278 template<>\
00279 vector<eName__> fromXmlString<vector<eName__> >(std::string value, bool* pError)\
00280 {\
00281 return convertStringToVector<eName__>(value, pError, ", ", false);\
00282 }\
00283
00284 #define ENUM_MAPPING_PRE_DEFINITIONS(eName__, eAlias__) \
00285 typedef vector<boost::tuple<eName__, string, string> > eAlias__##Mapping;\
00286 const eAlias__##Mapping & get##eAlias__##Mapping();\
00287
00288 #define ENUM_MAPPING_FUNCTION(eAlias__) \
00289 const eAlias__##Mapping& get##eAlias__##Mapping()\
00290 {\
00291 static eAlias__##Mapping values;\
00292 if (values.empty())\
00293 {\
00294
00295 #define ENUM_GET_ALL_VALUES(eName__, eAlias__) \
00296 template<>\
00297 vector<eName__> getAllEnumValues<eName__>()\
00298 {\
00299 vector<eName__> retValues;\
00300 eAlias__##Mapping values = get##eAlias__##Mapping();\
00301 eAlias__##Mapping::iterator iter;\
00302 for (iter = values.begin(); iter != values.end(); ++iter)\
00303 {\
00304 retValues.push_back(iter->get<0>());\
00305 }\
00306 return retValues;\
00307 }\
00308
00309 #define ENUM_GET_ALL_VALUES_DISPLAY_STRING(eName__, eAlias__) \
00310 template<>\
00311 vector<string> getAllEnumValuesAsDisplayString<eName__>()\
00312 {\
00313 vector<string> retValues;\
00314 eAlias__##Mapping values = get##eAlias__##Mapping();\
00315 eAlias__##Mapping::iterator iter;\
00316 for (iter = values.begin(); iter != values.end(); ++iter)\
00317 {\
00318 retValues.push_back(iter->get<1>());\
00319 }\
00320 return retValues;\
00321 }\
00322
00323 #define ENUM_GET_ALL_VALUES_XML_STRING(eName__, eAlias__) \
00324 template<>\
00325 vector<string> getAllEnumValuesAsXmlString<eName__>()\
00326 {\
00327 vector<string> retValues;\
00328 eAlias__##Mapping values = get##eAlias__##Mapping();\
00329 eAlias__##Mapping::iterator iter;\
00330 for (iter = values.begin(); iter != values.end(); ++iter)\
00331 {\
00332 retValues.push_back(iter->get<2>());\
00333 }\
00334 return retValues;\
00335 }\
00336
00337 #define BEGIN_ENUM_MAPPING_ALIAS(eName__, eAlias__) \
00338 ENUM_MAPPING_PRE_DEFINITIONS(eName__, eAlias__) \
00339 ENUM_MAPPING_TO_DISPLAY_STRING(eName__, eAlias__) \
00340 ENUM_MAPPING_TO_DISPLAY_STRING_VEC(eName__) \
00341 ENUM_MAPPING_TO_XML_STRING(eName__, eAlias__) \
00342 ENUM_MAPPING_TO_XML_STRING_VEC(eName__) \
00343 ENUM_MAPPING_FROM_DISPLAY_STRING(eName__, eAlias__) \
00344 ENUM_MAPPING_FROM_DISPLAY_STRING_VEC(eName__) \
00345 ENUM_MAPPING_FROM_XML_STRING(eName__, eAlias__) \
00346 ENUM_MAPPING_FROM_XML_STRING_VEC(eName__) \
00347 ENUM_GET_ALL_VALUES(eName__, eAlias__) \
00348 ENUM_GET_ALL_VALUES_DISPLAY_STRING(eName__, eAlias__) \
00349 ENUM_GET_ALL_VALUES_XML_STRING(eName__, eAlias__) \
00350 ENUM_MAPPING_FUNCTION(eAlias__) \
00351
00352 #define BEGIN_ENUM_MAPPING(eName__) BEGIN_ENUM_MAPPING_ALIAS(eName__, eName__)
00353
00354
00355 #define ADD_ENUM_MAPPING(enumVal, displayValue, xmlValue) values.push_back(boost::make_tuple(enumVal, displayValue, xmlValue));
00356
00357 #define END_ENUM_MAPPING() \
00358 } \
00359 return values; \
00360 }
00361
00362 #define STRINGSTREAM_MAPPING_TO_XML_STRING(type__, __precision) \
00363 template<>\
00364 std::string toXmlString(const type__ & val, bool* pError)\
00365 {\
00366 stringstream buf;\
00367 if (__precision != -1)\
00368 {\
00369 buf.precision(__precision);\
00370 }\
00371 buf << val;\
00372 if (pError != NULL)\
00373 {\
00374 *pError = buf.fail();\
00375 }\
00376 return buf.str();\
00377 }\
00378
00379 #define STRINGSTREAM_MAPPING_TO_XML_STRING_CAST(type__, cast__, precision__) \
00380 template<>\
00381 std::string toXmlString(const type__ & val, bool* pError)\
00382 {\
00383 stringstream buf;\
00384 if (precision__ != -1)\
00385 {\
00386 buf.precision(precision__);\
00387 }\
00388 buf << static_cast<cast__>(val);\
00389 if (pError != NULL)\
00390 {\
00391 *pError = buf.fail();\
00392 }\
00393 return buf.str();\
00394 }\
00395
00396 #define STRINGSTREAM_MAPPING_TO_XML_STRING_VEC(type__) \
00397 template<>\
00398 std::string toXmlString(const vector<type__> & vec, bool* pError)\
00399 {\
00400 return convertVectorToString(vec, pError, ", ", false);\
00401 }\
00402
00403 #define STRINGSTREAM_MAPPING_TO_DISPLAY_STRING(type__, __precision) \
00404 template<>\
00405 std::string toDisplayString(const type__ & val, bool* pError)\
00406 {\
00407 stringstream buf;\
00408 if (__precision != -1)\
00409 {\
00410 buf.precision(__precision);\
00411 }\
00412 buf << val;\
00413 if (pError != NULL)\
00414 {\
00415 *pError = buf.fail();\
00416 }\
00417 return buf.str();\
00418 }\
00419
00420 #define STRINGSTREAM_MAPPING_TO_DISPLAY_STRING_CAST(type__, cast__, precision__) \
00421 template<>\
00422 std::string toDisplayString(const type__ & val, bool* pError)\
00423 {\
00424 stringstream buf;\
00425 if (precision__ != -1)\
00426 {\
00427 buf.precision(precision__);\
00428 }\
00429 buf << static_cast<cast__>(val);\
00430 if (pError != NULL)\
00431 {\
00432 *pError = buf.fail();\
00433 }\
00434 return buf.str();\
00435 }\
00436
00437 #define STRINGSTREAM_MAPPING_TO_DISPLAY_STRING_VEC(type__) \
00438 template<>\
00439 std::string toDisplayString(const vector<type__> & vec, bool* pError)\
00440 {\
00441 return convertVectorToString(vec, pError, ", ", true);\
00442 }\
00443
00444
00445 #define STRINGSTREAM_MAPPING_FROM_XML_STRING(type__) \
00446 template<>\
00447 type__ fromXmlString<type__>(std::string value, bool* pError)\
00448 {\
00449 stringstream buf(value);\
00450 type__ parsedValue;\
00451 buf >> parsedValue;\
00452 if (pError != NULL)\
00453 {\
00454 *pError = buf.fail();\
00455 }\
00456 return parsedValue;\
00457 }\
00458
00459 #define STRINGSTREAM_MAPPING_FROM_XML_STRING_CAST(type__, cast__) \
00460 template<>\
00461 type__ fromXmlString<type__>(std::string value, bool* pError)\
00462 {\
00463 stringstream buf(value);\
00464 cast__ parsedValue;\
00465 buf >> parsedValue;\
00466 if (pError != NULL)\
00467 {\
00468 *pError = buf.fail() || parsedValue > std::numeric_limits<type__>::max()\
00469 || parsedValue < std::numeric_limits<type__>::min();\
00470 }\
00471 if (parsedValue > std::numeric_limits<type__>::max())\
00472 {\
00473 return std::numeric_limits<type__>::max();\
00474 }\
00475 if (parsedValue < std::numeric_limits<type__>::min())\
00476 {\
00477 return std::numeric_limits<type__>::min();\
00478 }\
00479 return static_cast<type__>(parsedValue);\
00480 }\
00481
00482 #define STRINGSTREAM_MAPPING_FROM_XML_STRING_VEC(type__) \
00483 template<>\
00484 vector<type__> fromXmlString<vector<type__> >(std::string value, bool* pError)\
00485 {\
00486 return convertStringToVector<type__>(value, pError, ", ", false);\
00487 }\
00488
00489 #define STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING(type__) \
00490 template<>\
00491 type__ fromDisplayString<type__>(std::string value, bool* pError)\
00492 {\
00493 stringstream buf(value);\
00494 type__ parsedValue;\
00495 buf >> parsedValue;\
00496 if (pError != NULL)\
00497 {\
00498 *pError = buf.fail();\
00499 }\
00500 return parsedValue;\
00501 }\
00502
00503 #define STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING_CAST(type__, cast__) \
00504 template<>\
00505 type__ fromDisplayString<type__>(std::string value, bool* pError)\
00506 {\
00507 stringstream buf(value);\
00508 cast__ parsedValue;\
00509 buf >> parsedValue;\
00510 if (pError != NULL)\
00511 {\
00512 *pError = buf.fail() || parsedValue > std::numeric_limits<type__>::max()\
00513 || parsedValue < std::numeric_limits<type__>::min();\
00514 }\
00515 if (parsedValue > std::numeric_limits<type__>::max())\
00516 {\
00517 return std::numeric_limits<type__>::max();\
00518 }\
00519 if (parsedValue < std::numeric_limits<type__>::min())\
00520 {\
00521 return std::numeric_limits<type__>::min();\
00522 }\
00523 return static_cast<type__>(parsedValue);\
00524 }\
00525
00526 #define STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING_VEC(type__) \
00527 template<>\
00528 vector<type__> fromDisplayString<vector<type__> >(std::string value, bool* pError)\
00529 {\
00530 return convertStringToVector<type__>(value, pError, ", ", true);\
00531 }\
00532
00533 #define STRINGSTREAM_MAPPING_PRECISION(type__, precision__) \
00534 STRINGSTREAM_MAPPING_TO_XML_STRING(type__, precision__) \
00535 STRINGSTREAM_MAPPING_TO_XML_STRING_VEC(type__) \
00536 STRINGSTREAM_MAPPING_TO_DISPLAY_STRING(type__, precision__) \
00537 STRINGSTREAM_MAPPING_TO_DISPLAY_STRING_VEC(type__) \
00538 STRINGSTREAM_MAPPING_FROM_XML_STRING(type__) \
00539 STRINGSTREAM_MAPPING_FROM_XML_STRING_VEC(type__) \
00540 STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING(type__) \
00541 STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING_VEC(type__) \
00542
00543 #define STRINGSTREAM_MAPPING(__type) \
00544 STRINGSTREAM_MAPPING_PRECISION(__type, -1) \
00545
00546 #define STRINGSTREAM_MAPPING_PRECISION_CAST(type__, cast__, precision__) \
00547 STRINGSTREAM_MAPPING_TO_XML_STRING_CAST(type__, cast__, precision__) \
00548 STRINGSTREAM_MAPPING_TO_XML_STRING_VEC(type__) \
00549 STRINGSTREAM_MAPPING_TO_DISPLAY_STRING_CAST(type__, cast__, precision__) \
00550 STRINGSTREAM_MAPPING_TO_DISPLAY_STRING_VEC(type__) \
00551 STRINGSTREAM_MAPPING_FROM_XML_STRING_CAST(type__, cast__) \
00552 STRINGSTREAM_MAPPING_FROM_XML_STRING_VEC(type__) \
00553 STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING_CAST(type__, cast__) \
00554 STRINGSTREAM_MAPPING_FROM_DISPLAY_STRING_VEC(type__) \
00555
00556 #define STRINGSTREAM_MAPPING_CAST(__type, __cast) \
00557 STRINGSTREAM_MAPPING_PRECISION_CAST(__type, __cast, -1)
00558
00559 #define TO_DISPLAY_POINTER_VARIATIONS(interface__) \
00560 template<>\
00561 std::string toDisplayString<interface__>(const interface__ & val, bool* pError)\
00562 {\
00563 return toDisplayString<const interface__ *>(&val, pError);\
00564 }\
00565 template<>\
00566 std::string toDisplayString<interface__ *>(interface__ * const & val, bool* pError)\
00567 {\
00568 return toDisplayString<const interface__*>(val, pError);\
00569 }\
00570
00571 #define TO_XML_POINTER_VARIATIONS(interface__) \
00572 template<>\
00573 std::string toXmlString<interface__>(const interface__ & val, bool* pError)\
00574 {\
00575 return toXmlString<const interface__ *>(&val, pError);\
00576 }\
00577 template<>\
00578 std::string toXmlString<interface__ *>(interface__ * const & val, bool* pError)\
00579 {\
00580 return toXmlString<const interface__*>(val, pError);\
00581 }
00582
00583 #endif