/*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2002-2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
////////////////////////////////////////////////////////////////////////
//
-// Integer types all use to_number for parsing and '<<' for
-// displaying
+// The base implementations use to_number for parsing and '<<' for
+// displaying, suitable for integer types.
//
template <class T>
bool
template <class T>
void
-showParam(ostream &os, const T &value)
+showParam(ostream &os, T const &value)
{
os << value;
}
//
-// Floating-point types
+// Template specializations:
+// - char (8-bit integer)
+// - floating-point types
+// - bool
+// - string
//
+
+// Treat 8-bit ints (chars) as ints on output, not as chars
+template <>
+void
+showParam(ostream &os, const char &value)
+{
+ os << (int)value;
+}
+
+
+template <>
+void
+showParam(ostream &os, const unsigned char &value)
+{
+ os << (unsigned int)value;
+}
+
+
+// Use sscanf() for FP types as to_number() only handles integers
template <>
bool
parseParam(const string &s, float &value)
return (sscanf(s.c_str(), "%lf", &value) == 1);
}
-//
-// bool
-//
+// Be flexible about what we take for bool
template <>
bool
parseParam(const string &s, bool &value)
{
- const string &lower = to_lower(s);
+ const string &ls = to_lower(s);
- if (lower == "true" || lower == "t" || lower == "yes" || lower == "y") {
+ if (ls == "true" || ls == "t" || ls == "yes" || ls == "y" || ls == "1") {
value = true;
return true;
}
- if (lower == "false" || lower == "f" || lower == "no" || lower == "n") {
+ if (ls == "false" || ls == "f" || ls == "no" || ls == "n" || ls == "0") {
value = false;
return true;
}
return false;
}
-
+// Display bools as strings
template <>
void
showParam(ostream &os, const bool &value)
}
-//
-// string
-//
+// String requires no processing to speak of
template <>
bool
parseParam(const string &s, string &value)
void
VectorParam<T>::parse(const string &s)
{
+ if (s.empty()) {
+ wasSet = true;
+ return;
+ }
+
vector<string> tokens;
tokenize(tokens, s, ' ');
// types that can use the above templates
#define INSTANTIATE_PARAM_TEMPLATES(type, typestr) \
template bool parseParam<type>(const string &s, type &value); \
-template void showParam<type>(ostream &os, const type &value); \
+template void showParam<type>(ostream &os, type const &value); \
template void Param<type>::parse(const string &); \
template void VectorParam<type>::parse(const string &); \
template void Param<type>::showValue(ostream &) const; \
list<ParamContext *> *ParamContext::ctxList = NULL;
-ParamContext::ParamContext(const string &_iniSection, bool noAutoParse)
+ParamContext::ParamContext(const string &_iniSection, InitPhase _initPhase)
: iniFilePtr(NULL), // initialized on call to parseParams()
- iniSection(_iniSection), paramList(NULL)
+ iniSection(_iniSection), paramList(NULL),
+ initPhase(_initPhase)
{
- if (!noAutoParse) {
+ // Put this context on global list for initialization
+ if (initPhase != NoAutoInit) {
if (ctxList == NULL)
ctxList = new list<ParamContext *>();
- (*ctxList).push_back(this);
+ // keep list sorted by ascending initPhase values
+ list<ParamContext *>::iterator i = ctxList->begin();
+ list<ParamContext *>::iterator end = ctxList->end();
+ for (; i != end; ++i) {
+ if (initPhase <= (*i)->initPhase) {
+ // found where we want to insert
+ break;
+ }
+ }
+ // (fall through case: insert at end)
+ ctxList->insert(i, this);
}
}