diff options
Diffstat (limited to 'dep/src/g3dlite/Any.cpp')
-rw-r--r-- | dep/src/g3dlite/Any.cpp | 1237 |
1 files changed, 0 insertions, 1237 deletions
diff --git a/dep/src/g3dlite/Any.cpp b/dep/src/g3dlite/Any.cpp deleted file mode 100644 index de4d32e83ea..00000000000 --- a/dep/src/g3dlite/Any.cpp +++ /dev/null @@ -1,1237 +0,0 @@ -/** - @file Any.cpp - - @author Morgan McGuire - @author Shawn Yarbrough - - @created 2006-06-11 - @edited 2009-11-15 - - Copyright 2000-2009, Morgan McGuire. - All rights reserved. - */ - -#include "G3D/Any.h" -#include "G3D/TextOutput.h" -#include "G3D/TextInput.h" -#include "G3D/stringutils.h" -#include <deque> -#include <iostream> - -namespace G3D { - -void Any::beforeRead() const { - if (isPlaceholder()) { - // Tried to read from a placeholder--throw an exception as if - // the original operator[] had failed. - KeyNotFound e; - alwaysAssertM(m_data, "Corrupt placeholder"); - - e.filename = m_data->source.filename; - e.line = m_data->source.line; - e.character = m_data->source.character; - e.key = m_placeholderName; - e.message = - "This exception may have been thrown later than " - "the actual operator[] invocation."; - - throw e; - } -} - - -Any::Data* Any::Data::create(const Data* d) { - Data* p = create(d->type); - - p->comment = d->comment; - p->name = d->name; - - switch (d->type) { - case NONE: - case BOOLEAN: - case NUMBER: - // No clone needed - break; - - case STRING: - *(p->value.s) = *(d->value.s); - break; - - case ARRAY: - *(p->value.a) = *(d->value.a); - break; - - case TABLE: - *(p->value.t) = *(d->value.t); - // Note that placeholders may be copied; that is ok--they are still - // just placeholders. - break; - } - - return p; -} - - -Any::Data* Any::Data::create(Any::Type t) { - size_t s = sizeof(Data); - - switch (t) { - case NONE: - case BOOLEAN: - case NUMBER: - // No extra space needed - break; - - case STRING: - s += sizeof(std::string); - break; - - case ARRAY: - s += sizeof(AnyArray); - break; - - case TABLE: - s += sizeof(AnyTable); - break; - } - - // Allocate the data object - Data* p = new (MemoryManager::create()->alloc(s)) Data(t); - - // Create the (empyt) value object at the end of the Data object - switch (t) { - case NONE: - case BOOLEAN: - case NUMBER: - // No value - break; - - case STRING: - p->value.s = new (p + 1) std::string(); - break; - - case ARRAY: - p->value.a = new (p + 1) AnyArray(); - break; - - case TABLE: - p->value.t = new (p + 1) AnyTable(); - break; - } - - return p; -} - - -void Any::Data::destroy(Data* d) { - if (d != NULL) { - d->~Data(); - MemoryManager::create()->free(d); - } -} - - -Any::Data::~Data() { - debugAssertM(referenceCount.value() <= 0, "Deleted while still referenced."); - - // Destruct but do not deallocate children - switch (type) { - case STRING: - debugAssert(value.s != NULL); - value.s->~basic_string(); - break; - - case ARRAY: - debugAssert(value.a != NULL); - value.a->~Array(); - break; - - case TABLE: - debugAssert(value.t != NULL); - value.t->~Table(); - break; - - default: - // All other types should have a NULL value pointer (i.e., they were used just for name and comment fields) - debugAssertM(value.s == NULL, "Corrupt Any::Data::Value"); - } - - value.s = NULL; -} - - -////////////////////////////////////////////////////////////// - -bool Any::containsKey(const std::string& x) const { - beforeRead(); - verifyType(TABLE); - - Any* a = m_data->value.t->getPointer(x); - - // Don't return true for placeholder objects - return (a != NULL) && (! a->isPlaceholder()); -} - - -void Any::dropReference() { - if (m_data && m_data->referenceCount.decrement() <= 0) { - // This was the last reference to the shared data - Data::destroy(m_data); - } - m_data = NULL; -} - - -void Any::ensureMutable() { - if (m_data && (m_data->referenceCount.value() >= 1)) { - // Copy the data. We must do this before dropping the reference - // to avoid a race condition - Data* d = Data::create(m_data); - dropReference(); - m_data = d; - } -} - - -Any::Any() : m_type(NONE), m_data(NULL) { -} - - -Any::Any(TextInput& t) : m_type(NONE), m_data(NULL) { - deserialize(t); -} - - -Any::Any(const Any& x) : m_type(NONE), m_data(NULL) { - x.beforeRead(); - *this = x; -} - - -Any::Any(double x) : m_type(NUMBER), m_simpleValue(x), m_data(NULL) { -} - - -#ifdef G3D_32BIT -Any::Any(int64 x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) { -} -#endif // G3D_32BIT - - -Any::Any(long x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) { -} - - -Any::Any(int x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) { -} - - -Any::Any(short x) : m_type(NUMBER), m_simpleValue((double)x), m_data(NULL) { -} - - -Any::Any(bool x) : m_type(BOOLEAN), m_simpleValue(x), m_data(NULL) { -} - - -Any::Any(const std::string& s) : m_type(STRING), m_data(Data::create(STRING)) { - *(m_data->value.s) = s; -} - - -Any::Any(const char* s) : m_type(STRING), m_data(NULL) { - if (s == NULL) { - m_type = NONE; - } else { - ensureData(); - *(m_data->value.s) = s; - } -} - - -Any::Any(Type t, const std::string& name) : m_type(t), m_data(NULL) { - alwaysAssertM(t == ARRAY || t == TABLE, "Can only create ARRAY or TABLE from Type enum."); - - ensureData(); - if (name != "") { - m_data->name = name; - } -} - - -Any::~Any() { - dropReference(); -} - - -void Any::beforeWrite() { - if (isPlaceholder()) { - // This is no longer a placeholder - m_placeholderName = ""; - } -} - -Any& Any::operator=(const Any& x) { - x.beforeRead(); - - if (this == &x) { - return *this; - } - - beforeWrite(); - - dropReference(); - - m_type = x.m_type; - m_simpleValue = x.m_simpleValue; - - if (x.m_data != NULL) { - x.m_data->referenceCount.increment(); - m_data = x.m_data; - } - - return *this; -} - - -Any& Any::operator=(double x) { - *this = Any(x); - return *this; -} - - -Any& Any::operator=(int x) { - return (*this = Any(x)); -} - - -Any& Any::operator=(bool x) { - *this = Any(x); - return *this; -} - - -Any& Any::operator=(const std::string& x) { - *this = Any(x); - return *this; -} - - -Any& Any::operator=(const char* x) { - *this = Any(x); - return *this; -} - - -Any& Any::operator=(Type t) { - switch (t) { - case NONE: - *this = Any(); - break; - - case TABLE: - case ARRAY: - *this = Any(t); - break; - - default: - alwaysAssertM(false, "Can only assign NONE, TABLE, or ARRAY Type enum."); - } - - return *this; -} - - -Any::Type Any::type() const { - beforeRead(); - return m_type; -} - - -const std::string& Any::comment() const { - beforeRead(); - - static const std::string blank; - if (m_data != NULL) { - return m_data->comment; - } else { - return blank; - } -} - - -void Any::setComment(const std::string& c) { - beforeRead(); - ensureData(); - m_data->comment = c; -} - - -bool Any::isNone() const { - beforeRead(); - return (m_type == NONE); -} - - -double Any::number() const { - beforeRead(); - verifyType(NUMBER); - return m_simpleValue.n; -} - - -const std::string& Any::string() const { - beforeRead(); - verifyType(STRING); - return *(m_data->value.s); -} - - -bool Any::boolean() const { - beforeRead(); - verifyType(BOOLEAN); - return m_simpleValue.b; -} - - -const std::string& Any::name() const { - beforeRead(); - static const std::string blank; - if (m_data != NULL) { - return m_data->name; - } else { - return blank; - } -} - - -void Any::setName(const std::string& n) { - beforeRead(); - ensureData(); - m_data->name = n; -} - - -int Any::size() const { - beforeRead(); - verifyType(ARRAY, TABLE); - switch (m_type) { - case TABLE: - return m_data->value.t->size(); - - case ARRAY: - return m_data->value.a->size(); - - default:; - return 0; - } // switch (m_type) -} - - -int Any::length() const { - beforeRead(); - return size(); -} - - -void Any::resize(int n) { - beforeRead(); - alwaysAssertM(n >= 0, "Cannot resize less than 0."); - verifyType(ARRAY); - m_data->value.a->resize(n); -} - - -void Any::clear() { - beforeRead(); - verifyType(ARRAY, TABLE); - switch (m_type) { - case ARRAY: - m_data->value.a->clear(); - break; - - case TABLE: - m_data->value.t->clear(); - break; - - default:; - } -} - - -const Any& Any::operator[](int i) const { - beforeRead(); - verifyType(ARRAY); - debugAssert(m_data != NULL); - Array<Any>& array = *(m_data->value.a); - return array[i]; -} - - -Any& Any::next() { - beforeRead(); - verifyType(ARRAY); - int n = size(); - resize(n + 1); - return (*this)[n]; -} - - -Any& Any::operator[](int i) { - beforeRead(); - verifyType(ARRAY); - debugAssert(m_data != NULL); - Array<Any>& array = *(m_data->value.a); - return array[i]; -} - - -const Array<Any>& Any::array() const { - beforeRead(); - verifyType(ARRAY); - debugAssert(m_data != NULL); - return *(m_data->value.a); -} - - -void Any::append(const Any& x0) { - beforeRead(); - verifyType(ARRAY); - debugAssert(m_data != NULL); - m_data->value.a->append(x0); -} - - -void Any::append(const Any& x0, const Any& x1) { - beforeRead(); - append(x0); - append(x1); -} - - -void Any::append(const Any& x0, const Any& x1, const Any& x2) { - beforeRead(); - append(x0); - append(x1); - append(x2); -} - - -void Any::append(const Any& x0, const Any& x1, const Any& x2, const Any& x3) { - beforeRead(); - append(x0); - append(x1); - append(x2); - append(x3); -} - - -const Table<std::string, Any>& Any::table() const { - beforeRead(); - verifyType(TABLE); - debugAssert(m_data != NULL); - return *(m_data->value.t); -} - - -const Any& Any::operator[](const std::string& x) const { - beforeRead(); - verifyType(TABLE); - debugAssert(m_data != NULL); - const Table<std::string, Any>& table = *(m_data->value.t); - Any* value = table.getPointer(x); - if (value == NULL) { - KeyNotFound e; - if (m_data) { - e.filename = m_data->source.filename; - e.line = m_data->source.line; - e.character = m_data->source.character; - } - e.key = x; - throw e; - } - return *value; -} - - -Any& Any::operator[](const std::string& key) { - beforeRead(); - verifyType(TABLE); - - bool created = false; - Any& value = m_data->value.t->getCreate(key, created); - - if (created) { - // The entry was created by this method; do not allow it to be - // read before it is written. - value.m_placeholderName = key; - - // Write source data for the value - value.ensureData(); - value.m_data->source = source(); - } - - return value; -} - - -void Any::set(const std::string& k, const Any& v) { - beforeRead(); - v.beforeRead(); - verifyType(TABLE); - debugAssert(m_data != NULL); - Table<std::string, Any>& table = *(m_data->value.t); - table.set(k, v); -} - - -const Any& Any::get(const std::string& x, const Any& defaultVal) const { - beforeRead(); - defaultVal.beforeRead(); - try { - return operator[](x); - } catch(KeyNotFound) { - return defaultVal; - } -} - - -bool Any::operator==(const Any& x) const { - beforeRead(); - x.beforeRead(); - if (m_type != x.m_type) { - return false; - } - - switch (m_type) { - case NONE: - return true; - - case BOOLEAN: - return (m_simpleValue.b == x.m_simpleValue.b); - - case NUMBER: - return (m_simpleValue.n == x.m_simpleValue.n); - - case STRING: - debugAssert(m_data != NULL); - return (*(m_data->value.s) == *(x.m_data->value.s)); - - case TABLE: { - if (size() != x.size()) { - return false; - } - debugAssert(m_data != NULL); - if (m_data->name != x.m_data->name) { - return false; - } - Table<std::string, Any>& cmptable = *( m_data->value.t); - Table<std::string, Any>& xcmptable = *(x.m_data->value.t); - for (Table<std::string,Any>::Iterator it1 = cmptable.begin(), it2 = xcmptable.begin(); - it1 != cmptable.end() && it2 != xcmptable.end(); - ++it1, ++it2) { - if (*it1 != *it2) { - return false; - } - } - return true; - } - - case ARRAY: { - if (size() != x.size()) { - return false; - } - debugAssert(m_data != NULL); - if (m_data->name != x.m_data->name) { - return false; - } - - Array<Any>& cmparray = *( m_data->value.a); - Array<Any>& xcmparray = *(x.m_data->value.a); - - for (int ii = 0; ii < size(); ++ii) { - if (cmparray[ii] != xcmparray[ii]) { - return false; - } - } - return true; - } - - default: - alwaysAssertM(false, "Unknown type."); - return false; - } // switch (m_type) - -} - - -bool Any::operator!=(const Any& x) const { - beforeRead(); - x.beforeRead(); - return !operator==(x); -} - - -static void getDeserializeSettings(TextInput::Settings& settings) { - settings.cppBlockComments = true; - settings.cppLineComments = true; - settings.otherLineComments = true; - settings.otherCommentCharacter = '#'; - settings.generateCommentTokens = true; - settings.singleQuotedStrings = false; - settings.msvcSpecials = false; - settings.caseSensitive = false; -} - - -std::string Any::unparse() const { - beforeRead(); - TextOutput::Settings settings; - TextOutput to(settings); - serialize(to); - return to.commitString(); -} - - -void Any::parse(const std::string& src) { - beforeRead(); - TextInput::Settings settings; - getDeserializeSettings(settings); - - TextInput ti(TextInput::FROM_STRING, src, settings); - deserialize(ti); -} - - -void Any::load(const std::string& filename) { - beforeRead(); - TextInput::Settings settings; - getDeserializeSettings(settings); - - TextInput ti(filename, settings); - deserialize(ti); -} - - -void Any::save(const std::string& filename) const { - beforeRead(); - TextOutput::Settings settings; - settings.wordWrap = TextOutput::Settings::WRAP_NONE; - - TextOutput to(filename,settings); - serialize(to); - to.commit(); -} - - -static bool needsQuotes(const std::string& s) { - if (! isLetter(s[0]) && (s[0] != '_')) { - return true; - } - - for (int i = 0; i < (int)s.length(); ++i) { - char c = s[i]; - - // peek character - char p = (i == (int)s.length() - 1) ? '_' : s[i + 1]; - - // Identify separators - if ((c == '-' && p == '>') || - (c == ':' && p == ':')) { - // Skip over this symbol - ++i; - continue; - } - - if (! isDigit(c) && ! isLetter(c) & (c != '.')) { - // This is an illegal character for an identifier, so we need quotes - return true; - } - } - - return false; -} - - -// TODO: if the output will fit on one line, compress tables and arrays into a single line -void Any::serialize(TextOutput& to) const { - beforeRead(); - if (m_data && ! m_data->comment.empty()) { - to.printf("\n/* %s */\n", m_data->comment.c_str()); - } - - switch (m_type) { - case NONE: - to.writeSymbol("NONE"); - break; - - case BOOLEAN: - to.writeBoolean(m_simpleValue.b); - break; - - case NUMBER: - to.writeNumber(m_simpleValue.n); - break; - - case STRING: - debugAssert(m_data != NULL); - to.writeString(*(m_data->value.s)); - break; - - case TABLE: { - debugAssert(m_data != NULL); - if (! m_data->name.empty()) { - if (needsQuotes(m_data->name)) { - to.writeString(m_data->name); - } else { - to.writeSymbol(m_data->name); - } - } - to.writeSymbol("{"); - to.writeNewline(); - to.pushIndent(); - AnyTable& table = *(m_data->value.t); - Array<std::string> keys; - table.getKeys(keys); - keys.sort(); - - for (int i = 0; i < keys.size(); ++i) { - - to.writeSymbol(keys[i]); - to.writeSymbol("="); - table[keys[i]].serialize(to); - - if (i < keys.size() - 1) { - to.writeSymbol(","); - } - to.writeNewline(); - - // Skip a line between table entries - to.writeNewline(); - } - - to.popIndent(); - to.writeSymbol("}"); - break; - } - - case ARRAY: { - debugAssert(m_data != NULL); - if (! m_data->name.empty()) { - // For arrays, leave no trailing space between the name and the paren - to.writeSymbol(format("%s(", m_data->name.c_str())); - } else { - to.writeSymbol("("); - } - to.writeNewline(); - to.pushIndent(); - Array<Any>& array = *(m_data->value.a); - for (int ii = 0; ii < size(); ++ii) { - array[ii].serialize(to); - if (ii < size() - 1) { - to.writeSymbol(","); - to.writeNewline(); - } - - // Put the close paren on an array right behind the last element - } - to.popIndent(); - to.writeSymbol(")"); - break; - } - } -} - - -void Any::deserializeComment(TextInput& ti, Token& token, std::string& comment) { - // Parse comments - while (token.type() == Token::COMMENT) { - comment += trimWhitespace(token.string()) + "\n"; - - // Allow comments to contain newlines. - do { - token = ti.read(); - comment += "\n"; - } while (token.type() == Token::NEWLINE); - } - - comment = trimWhitespace(comment); -} - -/** True if \a c is an open paren of some form */ -static bool isOpen(const char c) { - return c == '(' || c == '[' || c == '{'; -} - - -/** True if \a c is an open paren of some form */ -static bool isClose(const char c) { - return c == ')' || c == ']' || c == '}'; -} - - -/** True if \a s is a C++ name operator */ -static bool isNameOperator(const std::string& s) { - return s == "." || s == "::" || s == "->"; -} - - -void Any::deserializeName(TextInput& ti, Token& token, std::string& name) { - debugAssert(token.type() == Token::SYMBOL); - std::string s = token.string(); - while (! isOpen(s[0])) { - name += s; - - // Skip newlines and comments - token = ti.readSignificant(); - - if (token.type() != Token::SYMBOL) { - throw ParseError(ti.filename(), token.line(), token.character(), - "Expected symbol while parsing Any"); - } - s = token.string(); - } -} - - -void Any::deserialize(TextInput& ti) { - beforeRead(); - Token token = ti.read(); - deserialize(ti, token); - // Restore the last token - ti.push(token); -} - - -void Any::deserialize(TextInput& ti, Token& token) { - // Deallocate old data - dropReference(); - m_type = NONE; - m_simpleValue.b = false; - - // Skip leading newlines - while (token.type() == Token::NEWLINE) { - token = ti.read(); - } - - std::string comment; - if (token.type() == Token::COMMENT) { - deserializeComment(ti, token, comment); - } - - if (token.type() == Token::END) { - // There should never be a comment without an Any following it; even - // if the file ends with some commented out stuff, - // that should not happen after a comma, so we'd never read that - // far in a proper file. - throw ParseError(ti.filename(), token.line(), token.character(), - "File ended without a properly formed Any"); - } - - switch (token.type()) { - case Token::STRING: - m_type = STRING; - ensureData(); - *(m_data->value.s) = token.string(); - m_data->source.set(ti, token); - break; - - case Token::NUMBER: - m_type = NUMBER; - m_simpleValue.n = token.number(); - ensureData(); - m_data->source.set(ti, token); - break; - - case Token::BOOLEAN: - m_type = BOOLEAN; - m_simpleValue.b = token.boolean(); - ensureData(); - m_data->source.set(ti, token); - break; - - case Token::SYMBOL: - // Named Array, Named Table, Array, Table, or NONE - if (toUpper(token.string()) == "NONE") { - // Nothing left to do; we initialized to NONE originally - ensureData(); - m_data->source.set(ti, token); - } else { - // Array or Table - - // Parse the name - - // s must have at least one element or this would not have - // been parsed as a symbol - std::string name; - deserializeName(ti, token, name); - if (token.type() != Token::SYMBOL) { - throw ParseError(ti.filename(), token.line(), token.character(), - "Malformed Any TABLE or ARRAY; must start with [, (, or {"); - } - - if (isOpen(token.string()[0])) { - // Array or table - deserializeBody(ti, token); - } else { - throw ParseError(ti.filename(), token.line(), token.character(), - "Malformed Any TABLE or ARRAY; must start with [, (, or {"); - } - - if (! name.empty()) { - ensureData(); - m_data->name = name; - } - } // if NONE - break; - - default: - throw ParseError(ti.filename(), token.line(), token.character(), - "Unexpected token"); - - } // switch - - if (! comment.empty()) { - ensureData(); - m_data->comment = comment; - } - - if (m_type != ARRAY && m_type != TABLE) { - // Array and table already consumed their last token - token = ti.read(); - } -} - - -void Any::ensureData() { - if (m_data == NULL) { - m_data = Data::create(m_type); - } -} - - -static bool isSeparator(char c) { - return c == ',' || c == ';'; -} - - -void Any::readUntilCommaOrClose(TextInput& ti, Token& token) { - while (! ((token.type() == Token::SYMBOL) && - (isClose(token.string()[0])) || - isSeparator(token.string()[0]))) { - switch (token.type()) { - case Token::NEWLINE: - case Token::COMMENT: - // Consume - token = ti.read(); - break; - - default: - throw ParseError(ti.filename(), token.line(), token.character(), - "Expected a comma or close paren"); - } - } -} - - -void Any::deserializeBody(TextInput& ti, Token& token) { - char closeSymbol = '}'; - m_type = TABLE; - - const char c = token.string()[0]; - - if (c != '{') { - m_type = ARRAY; - // Chose the appropriate close symbol - closeSymbol = (c == '(') ? ')' : ']'; - } - - // Allocate the underlying data structure - ensureData(); - m_data->source.set(ti, token); - - // Consume the open token - token = ti.read(); - - while (! ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol))) { - - // Read any leading comment. This must be done here (and not in the recursive deserialize - // call) in case the body contains only a comment. - std::string comment; - deserializeComment(ti, token, comment); - - if ((token.type() == Token::SYMBOL) && (token.string()[0] == closeSymbol)) { - // We're done; this catches the case where the array is empty - break; - } - - // Pointer the value being read - Any a = NULL; - std::string key; - - if (m_type == TABLE) { - // Read the key - if (token.type() != Token::SYMBOL && token.type() != Token::STRING) { - throw ParseError(ti.filename(), token.line(), token.character(), "Expected a name"); - } - - key = token.string(); - // Consume everything up to the = sign - token = ti.readSignificant(); - - if ((token.type() != Token::SYMBOL) || (token.string() != "=")) { - throw ParseError(ti.filename(), token.line(), token.character(), "Expected ="); - } else { - // Consume (don't consume comments--we want the value pointed to by a to get those). - token = ti.read(); - } - } - a.deserialize(ti, token); - - if (! comment.empty()) { - // Prepend the comment we read earlier - a.ensureData(); - a.m_data->comment = trimWhitespace(comment + "\n" + a.m_data->comment); - } - - if (m_type == TABLE) { - set(key, a); - } else { - append(a); - } - - // Read until the comma or close paren, discarding trailing comments and newlines - readUntilCommaOrClose(ti, token); - - // Consume the comma - if (isSeparator(token.string()[0])) { - token = ti.read(); - } - } - - // Consume the close paren (to match other deserialize methods) - token = ti.read(); -} - - -Any::operator int() const { - beforeRead(); - return iRound(number()); -} - - -Any::operator float() const { - beforeRead(); - return float(number()); -} - - -Any::operator double() const { - beforeRead(); - return number(); -} - - -Any::operator bool() const { - beforeRead(); - return boolean(); -} - - -Any::operator std::string() const { - beforeRead(); - return string(); -} - - -const Any::Source& Any::source() const { - static Source s; - if (m_data) { - return m_data->source; - } else { - return s; - } -} - - -void Any::verify(bool value, const std::string& message) const { - beforeRead(); - if (! value) { - ParseError p; - if (m_data) { - p.filename = m_data->source.filename; - p.line = m_data->source.line; - p.character = m_data->source.character; - } - - if (name().empty()) { - p.message = "Parse error"; - } else { - p.message = "Parse error while reading the contents of " + name(); - } - - if (! message.empty()) { - p.message = p.message + ": " + message; - } - - throw p; - } -} - - -void Any::verifyName(const std::string& n) const { - beforeRead(); - verify(beginsWith(toUpper(name()), toUpper(n)), "Name must begin with " + n); -} - - -void Any::verifyType(Type t) const { - beforeRead(); - if (type() != t) { - verify(false, "Must have type " + toString(t)); - } -} - - -void Any::verifyType(Type t0, Type t1) const { - beforeRead(); - if (type() != t0 && type() != t1) { - verify(false, "Must have type " + toString(t0) + " or " + toString(t1)); - } -} - - -void Any::verifySize(int low, int high) const { - beforeRead(); - verifyType(ARRAY, TABLE); - if (size() < low || size() > high) { - verify(false, format("Size must be between %d and %d", low, high)); - } -} - - -void Any::verifySize(int s) const { - beforeRead(); - verifyType(ARRAY, TABLE); - if (size() != s) { - verify(false, format("Size must be %d", s)); - } -} - - -std::string Any::toString(Type t) { - switch(t) { - case NONE: return "NONE"; - case BOOLEAN: return "BOOLEAN"; - case NUMBER: return "NUMBER"; - case STRING: return "STRING"; - case ARRAY: return "ARRAY"; - case TABLE: return "TABLE"; - default: - alwaysAssertM(false, "Illegal Any::Type"); - return ""; - } -} - -} // namespace G3D - |