// // This software may only be used by you under license from the // University of Notre Dame. A copy of the University of Notre Dame's // Source Code Agreement is available at the inilib Internet website // having the URL: If you // received this software without first entering into a license with the // University of Notre Dame, you have an infringing copy of this software // and cannot use it without violating the University of Notre Dame's // intellectual property rights. // // $Id: attribute.cc,v 1.13 2005/03/10 18:13:12 bwbarrett Exp $ // // FUNCTION: Parse initialization files, // maintain state of program // save state of program #include #include #include "attribute.h" #include "int_attribute.h" #include "double_attribute.h" #include "string_attribute.h" #include "bool_attribute.h" // Note: we could have used "using namespace std; using namespace // INI;" in here, but this file used to be part of a .h file, where // such things would be a distinct no-no. Hence, just for consistency // (and because we're lazy and have 6 billion other details to attend // to), we kept the std:: and INI:: everywhere. // instantiate the static variable int INI::attribute::precision = 4; INI::attribute::attribute() : data(0), debug(true) { // Don't need nuttin' here, but the default constructor is necessary } INI::attribute::attribute(attribute* _data) : debug(true) { data = _data->make_copy(); } INI::attribute::attribute(const attribute& _attr) : debug(true) { if (_attr.data) data = _attr.data->make_copy(); else data = 0; } INI::attribute::~attribute() { debug << "*** Entering attribute::~attribute() ***" << std::endl; if (data) delete data; } INI::attribute& INI::attribute::operator=(int new_value) { debug << "*** Entering attribute::operator=(int) ***" << std::endl; if (data) (*data) = new_value; else data = new int_attribute(new_value); return *this; } INI::attribute& INI::attribute::operator=(double new_value) { debug << "*** Entering attribute::operator=(double) ***" << std::endl; if (data) (*data) = new_value; else data = new double_attribute(new_value); return *this; } INI::attribute& INI::attribute::operator=(const std::string& new_value) { debug << "*** Entering attribute::operator=(std::string&) ***" << std::endl; if (data) (*data) = new_value; else data = new string_attribute(new_value); return *this; } INI::attribute& INI::attribute::operator=(bool new_value) { debug << "*** Entering attribute::operator=(bool) ***" << std::endl; if (data) (*data) = new_value; else data = new bool_attribute(new_value); return *this; } // Argh... Without this, the code: // // attribute = "hi" // // will have the bool version (above) called instead of the string // version. But the casting operator is NOT needed and will result in // a ambiguity error from the compiler... INI::attribute& INI::attribute::operator=(const char *new_value) { debug << "*** Entering attribute::operator=(const char*) ***" << std::endl; if (data) (*data) = new_value; else data = new string_attribute(new_value); return *this; } INI::attribute& INI::attribute::operator=(const INI::attribute& new_value) { debug << "*** Entering attribute::operator=(attribute&) ***" << std::endl; if (data) delete data; switch (new_value.get_type()) { case INI::BOOL: data = new bool_attribute((bool) new_value); break; case INI::DOUBLE: data = new double_attribute((double) new_value); break; case INI::INT: data = new int_attribute((int) new_value); break; case INI::STRING: data = new string_attribute((std::string) new_value); break; case INI::NONE: break; } return *this; } INI::attribute::operator int() const { debug << "*** Entering attribute::operator int() ***" << std::endl; if (!data) data = new int_attribute(0); return (int) (*data); } INI::attribute::operator double() const { debug << "*** Entering attribute::operator double() ***" << std::endl; if (!data) data = new double_attribute(0.0); return (double) (*data); } INI::attribute::operator std::string() const { debug << "*** Entering attribute::operator std::string() ***" << std::endl; if (!data) data = new string_attribute(""); return (std::string) (*data); } INI::attribute::operator bool() const { debug << "*** Entering attribute::operator bool() ***" << std::endl; if (!data) data = new bool_attribute(false); return (bool) (*data); } INI::attribute& INI::attribute::operator*=(bool a) { if (!data) data = new bool_attribute(false); (*data) *= a; return *this; } INI::attribute& INI::attribute::operator*=(double a) { if (!data) data = new double_attribute(0.0); (*data) *= a; return *this; } INI::attribute& INI::attribute::operator*=(int a) { if (!data) data = new int_attribute(0); (*data) *= a; return *this; } INI::attribute& INI::attribute::operator*=(const std::string& a) { if (!data) data = new string_attribute(""); (*data) *= a; return *this; } INI::attribute& INI::attribute::operator*=(const attribute& a) { if (!data) switch (a.get_type()) { case INI::BOOL: data = new bool_attribute(false); break; case INI::DOUBLE: data = new double_attribute(0.0); break; case INI::INT: data = new int_attribute(0); break; case INI::STRING: data = new string_attribute(""); break; case INI::NONE: // This is kind of interesting... Arbitrary decision time data = new string_attribute(""); break; } (*data) *= a; return *this; } INI::attribute& INI::attribute::operator/=(bool a) { if (!data) data = new bool_attribute(false); (*data) /= a; return *this; } INI::attribute& INI::attribute::operator/=(double a) { if (!data) data = new double_attribute(0.0); (*data) /= a; return *this; } INI::attribute& INI::attribute::operator/=(int a) { if (!data) data = new int_attribute(0); (*data) /= a; return *this; } INI::attribute& INI::attribute::operator/=(const std::string& a) { if (!data) data = new string_attribute(""); (*data) /= a; return *this; } INI::attribute& INI::attribute::operator/=(const attribute& a) { if (!data) switch (a.get_type()) { case INI::BOOL: data = new bool_attribute(false); break; case INI::DOUBLE: data = new double_attribute(0.0); break; case INI::INT: data = new int_attribute(0); break; case INI::STRING: data = new string_attribute(""); break; case INI::NONE: // This is kind of interesting... Arbitrary decision time data = new string_attribute(""); break; } (*data) /= a; return *this; } INI::attribute& INI::attribute::operator%=(bool a) { if (!data) data = new bool_attribute(false); (*data) %= a; return *this; } INI::attribute& INI::attribute::operator%=(double a) { if (!data) data = new double_attribute(0.0); (*data) %= a; return *this; } INI::attribute& INI::attribute::operator%=(int a) { if (!data) data = new int_attribute(0); (*data) %= a; return *this; } INI::attribute& INI::attribute::operator%=(const std::string& a) { if (!data) data = new string_attribute(""); (*data) %= a; return *this; } INI::attribute& INI::attribute::operator%=(const attribute& a) { if (!data) switch (a.get_type()) { case INI::BOOL: data = new bool_attribute(false); break; case INI::DOUBLE: data = new double_attribute(0.0); break; case INI::INT: data = new int_attribute(0); break; case INI::STRING: data = new string_attribute(""); break; case INI::NONE: // This is kind of interesting... Arbitrary decision time data = new string_attribute(""); break; } (*data) %= a; return *this; } INI::attribute& INI::attribute::operator+=(bool a) { if (!data) data = new bool_attribute(false); (*data) += a; return *this; } INI::attribute& INI::attribute::operator+=(double a) { if (!data) data = new double_attribute(0.0); (*data) += a; return *this; } INI::attribute& INI::attribute::operator+=(int a) { if (!data) data = new int_attribute(0); (*data) += a; return *this; } INI::attribute& INI::attribute::operator+=(const std::string& a) { if (!data) data = new string_attribute(""); (*data) += a; return *this; } INI::attribute& INI::attribute::operator+=(const attribute& a) { if (!data) switch (a.get_type()) { case INI::BOOL: data = new bool_attribute(false); break; case INI::DOUBLE: data = new double_attribute(0.0); break; case INI::INT: data = new int_attribute(0); break; case INI::STRING: data = new string_attribute(""); break; case INI::NONE: // This is kind of interesting... Arbitrary decision time data = new string_attribute(""); break; } (*data) += a; return *this; } INI::attribute& INI::attribute::operator-=(bool a) { if (!data) data = new bool_attribute(false); (*data) -= a; return *this; } INI::attribute& INI::attribute::operator-=(double a) { if (!data) data = new double_attribute(0.0); (*data) -= a; return *this; } INI::attribute& INI::attribute::operator-=(int a) { if (!data) data = new int_attribute(0); (*data) -= a; return *this; } INI::attribute& INI::attribute::operator-=(const std::string& a) { if (!data) data = new string_attribute(""); (*data) -= a; return *this; } INI::attribute& INI::attribute::operator-=(const attribute& a) { if (!data) switch (a.get_type()) { case INI::BOOL: data = new bool_attribute(false); break; case INI::DOUBLE: data = new double_attribute(0.0); break; case INI::INT: data = new int_attribute(0); break; case INI::STRING: data = new string_attribute(""); break; case INI::NONE: // This is kind of interesting... Arbitrary decision time data = new string_attribute(""); break; } (*data) -= a; return *this; } INI::attribute& INI::attribute::operator++() // prefix { if (!data) data = new string_attribute(""); ++(*data); return *this; } INI::attribute& INI::attribute::operator--() { if (!data) (*data) = new string_attribute(""); --(*data); return *this; } INI::attr_type INI::attribute::get_type() const { if (data) return data->get_type(); else return NONE; } INI::attribute* INI::attribute::make_copy() const { if (!data) return new attribute(); else return data->make_copy(); } std::ostream& INI::operator<<(std::ostream& out_stream, const attribute& thingy) { out_stream << (std::string) thingy; return out_stream; }