StringUtilitiesMacros.h

Go to the documentation of this file.
00001 /*
00002  * The information in this file is
00003  * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
00004  * and is subject to the terms and conditions of the
00005  * GNU Lesser General Public License Version 2.1
00006  * The license text is available from   
00007  * http://www.gnu.org/licenses/lgpl.html
00008  */
00009 
00010 #ifndef STRINGUTILITIESMACROS_H__
00011 #define STRINGUTILITIESMACROS_H__
00012 
00013 /** \page stringutilitiesmacros StringUtilities macros
00014  *  The StringUtilitiesMacros.h file contains definitions for macros which simplify defining type to string mappings.
00015  *  Basic usage is as follows.
00016  *  \code
00017  *  namespace StringUtilities
00018  *  {
00019  *     STRINGSTREAM_MAPPING(int)
00020  *  };
00021  *
00022  *  namespace StringUtilities
00023  *  {
00024  *     STRINGSTREAM_MAPPING_PRECISION(float, numeric_limits<float>::digits10)
00025  *  };
00026  *
00027  *  namespace StringUtilities
00028  *  {
00029  *     BEGIN_ENUM_MAPPING(AoiAddMode)
00030  *     ADD_ENUM_MAPPING(APPEND_AOI, "Append", "Append")
00031  *     ADD_ENUM_MAPPING(REPLACE_AOI, "Replace", "Replace")
00032  *     ADD_ENUM_MAPPING(NEW_AOI, "New", "New")
00033  *     END_ENUM_MAPPING()
00034  *  };
00035  *  \endcode
00036  *
00037  *  Advanced configurations, such as using the macros for type to string conversion but specifying a custom string to type conversion are beyond the scope of this document.
00038  *  If you need such advanced usage, it is suggested that you study the macro definitions in StringUtilitiesMacros.h to determine the best
00039  *  combination of macros and custom code.
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

Software Development Kit - Opticks 4.9.0 Build 16218