From: Morgan Deters Date: Fri, 19 Feb 2010 23:10:02 +0000 (+0000) Subject: specialized implementation for boolean node attributes ("flags"): they now share... X-Git-Tag: cvc5-1.0.0~9241 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7697b5218118d71800318472a7423a5b42bee469;p=cvc5.git specialized implementation for boolean node attributes ("flags"): they now share memory words properly; also, implementations of some output functionality --- diff --git a/src/expr/Makefile.am b/src/expr/Makefile.am index 7393f27a5..c3090e40f 100644 --- a/src/expr/Makefile.am +++ b/src/expr/Makefile.am @@ -14,7 +14,6 @@ libexpr_la_SOURCES = \ node_manager.h \ expr_manager.h \ attribute.h \ - attribute.cpp \ @srcdir@/kind.h \ node.cpp \ node_builder.cpp \ diff --git a/src/expr/attribute.cpp b/src/expr/attribute.cpp deleted file mode 100644 index ea672b514..000000000 --- a/src/expr/attribute.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/********************* -*- C++ -*- */ -/** attribute.cpp - ** Original author: mdeters - ** Major contributors: none - ** Minor contributors (to current version): none - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information. - ** - ** Node attributes. - **/ - -#include "expr/attribute.h" - -#include - -using std::string; - -namespace CVC4 { -namespace expr { -namespace attr { - -unsigned BitAssignment::s_bit = 0; - -}/* CVC4::expr::attr namespace */ -}/* CVC4::expr namespace */ -}/* CVC4 namespace */ diff --git a/src/expr/attribute.h b/src/expr/attribute.h index b8cddacbf..12de9eb5f 100644 --- a/src/expr/attribute.h +++ b/src/expr/attribute.h @@ -16,7 +16,7 @@ ** ** An attribute structure looks like the following: ** - ** struct VarName_attr { + ** struct VarNameAttr { ** ** // the value type for this attribute ** typedef std::string value_type; @@ -24,9 +24,6 @@ ** // an extra hash value (to avoid same-value-type collisions) ** enum { hash_value = 1 }; ** - ** // whether inclusion in the table keeps the (key) Node live or not - ** static const bool hard_key = false; - ** ** // cleanup routine when the Node goes away ** static inline void cleanup(const std::string&) { ** } @@ -55,6 +52,8 @@ namespace CVC4 { namespace expr { +// ATTRIBUTE HASH FUNCTIONS ==================================================== + struct AttrHashFcn { enum { LARGE_PRIME = 1 }; std::size_t operator()(const std::pair& p) const { @@ -68,97 +67,7 @@ struct AttrHashBoolFcn { } }; -/* -template -class AttrTable; - -template <> -class AttrTable { -public: - class BitAccessor { - - uint64_t& d_word; - - unsigned d_bit; - - public: - - BitAccessor(uint64_t& word, unsigned bit) : - d_word(word), - d_bit(bit) { - } - - BitAccessor& operator=(bool b) { - if(b) { - // set the bit - d_word |= (1 << d_bit); - } else { - // clear the bit - d_word &= ~(1 << d_bit); - } - - return *this; - } - }; - - // bool specialization - //static AttrHash* s_hash; - - //typedef AttrHash::iterator iterator; - //typedef AttrHash::const_iterator const_iterator; - - template - BitAccessor& find(Node e, const Attr&); - - template - bool find(Node e, const Attr&) const; -}; - -template <> -class AttrTable { -public: - // int(egral) specialization - //static AttrHash* s_hash; - typedef AttrHash::iterator iterator; - typedef AttrHash::const_iterator const_iterator; - uint64_t& find(TNode); -}; - -template -class AttrTable { -public: - // pointer specialization - //static AttrHash* s_hash; - typedef AttrHash::iterator iterator; - typedef AttrHash::const_iterator const_iterator; -}; - -template <> -class AttrTable { -public: - // Node specialization - //static AttrHash* s_hash; - typedef AttrHash::iterator iterator; - typedef AttrHash::const_iterator const_iterator; - Node find(TNode); -}; - -template <> -class AttrTable { -public: - // string specialization - //static AttrHash* s_hash; - typedef AttrHash::iterator iterator; - typedef AttrHash::const_iterator const_iterator; - Node find(TNode); -}; - -*/ - -/* -template -AttrHash* AttrTable::s_hash = &g_hash_ptr; -*/ +// ATTRIBUTE TYPE MAPPINGS ===================================================== template struct KindValueToTableValueMapping { @@ -209,11 +118,12 @@ struct KindTableMapping { typedef typename AttrKind::value_type table_identifier; }; +// ATTRIBUTE HASH TABLES ======================================================= + // use a TAG to indicate which table it should be in template struct AttrHash : public __gnu_cxx::hash_map, value_type, AttrHashFcn> {}; -/* template <> class AttrHash : protected __gnu_cxx::hash_map { @@ -243,46 +153,63 @@ class AttrHash : protected __gnu_cxx::hash_map& d_word; + std::pair* d_entry; - int d_bit; + unsigned d_bit; public: BitIterator() : - d_word((uint64_t&) d_bit), - d_bit(-1) { + d_entry(NULL), + d_bit(0) { } - BitIterator(std::pair& entry, unsigned bit) : - d_entry(entry), + BitIterator(std::pair& entry, unsigned bit) : + d_entry(&entry), d_bit(bit) { } - BitAccessor operator*() { - return BitAccessor(d_word, d_bit); + std::pair operator*() { + return std::make_pair(d_entry->first, BitAccessor(d_entry->second, d_bit)); + } + + bool operator==(const BitIterator& b) { + return d_entry == b.d_entry && d_bit == b.d_bit; } }; class ConstBitIterator { - uint64_t& d_word; + const std::pair* d_entry; unsigned d_bit; public: - ConstBitIterator(uint64_t& word, unsigned bit) : - d_word(word), + ConstBitIterator() : + d_entry(NULL), + d_bit(0) { + } + + ConstBitIterator(const std::pair& entry, unsigned bit) : + d_entry(&entry), d_bit(bit) { } - bool operator*() { - return (d_word & (1 << d_bit)) ? true : false; + std::pair operator*() { + return std::make_pair(d_entry->first, (d_entry->second & (1 << d_bit)) ? true : false); + } + + bool operator==(const ConstBitIterator& b) { + return d_entry == b.d_entry && d_bit == b.d_bit; } }; @@ -300,20 +227,34 @@ public: if(i == super::end()) { return BitIterator(); } + Debug.printf("boolattr", "underlying word at 0x%p looks like 0x%016llx, bit is %u\n", &(*i).second, (*i).second, k.first); return BitIterator(*i, k.first); } + BitIterator end() { + return BitIterator(); + } + ConstBitIterator find(const std::pair& k) const { super::const_iterator i = super::find(k.second); + if(i == super::end()) { + return ConstBitIterator(); + } + Debug.printf("boolattr", "underlying word at 0x%p looks like 0x%016llx, bit is %u\n", &(*i).second, (*i).second, k.first); return ConstBitIterator(*i, k.first); } + ConstBitIterator end() const { + return ConstBitIterator(); + } + BitAccessor operator[](const std::pair& k) { uint64_t& word = super::operator[](k.second); return BitAccessor(word, k.first); } -}; -*/ +};/* class AttrHash */ + +// ATTRIBUTE PATTERN =========================================================== /** * An "attribute type" structure. @@ -330,13 +271,15 @@ struct Attribute { static inline unsigned getId() { return s_id; } static inline unsigned getHashValue() { return s_hashValue; } + static const bool has_default_value = false; + private: /** an id */ - static unsigned s_id; + static const unsigned s_id; /** an extra hash value (to avoid same-value-type collisions) */ - static unsigned s_hashValue; + static const unsigned s_hashValue; }; /** @@ -352,21 +295,28 @@ struct Attribute { static inline void cleanup(const bool&) {} static inline unsigned getId() { return s_id; } - static inline unsigned getBit() { return s_bit; } static inline unsigned getHashValue() { return s_hashValue; } -private: + static const bool has_default_value = true; + static const bool default_value = false; - /** an id */ - static unsigned s_id; + static inline unsigned checkID(unsigned id) { + AlwaysAssert(id <= 63, + "Too many boolean node attributes registered during initialization !"); + return id; + } + +private: /** a bit assignment */ - static unsigned s_bit; + static const unsigned s_id; /** an extra hash value (to avoid same-value-type collisions) */ - static unsigned s_hashValue; + static const unsigned s_hashValue; }; +// SPECIFIC, GLOBAL ATTRIBUTE DEFINITIONS ====================================== + namespace attr { struct VarName {}; struct Type {}; @@ -378,46 +328,24 @@ namespace attr { template unsigned LastAttributeId::s_id = 0; - - struct BitAssignment { - static unsigned s_bit; - }; }/* CVC4::expr::attr namespace */ typedef Attribute VarNameAttr; typedef Attribute TypeAttr; -/* -template -class AttributeTable { - typedef typename Attr::value_type value_type; - - AttrTable& d_table; - -}; -*/ - -/* -template -struct AttrTables { - -}; -*/ +// ATTRIBUTE IDENTIFIER ASSIGNMENT ============================================= template -unsigned Attribute::s_id = +const unsigned Attribute::s_id = attr::LastAttributeId::table_value_type>::s_id++; template -unsigned Attribute::s_hashValue = Attribute::s_id; +const unsigned Attribute::s_hashValue = Attribute::s_id; template -unsigned Attribute::s_id = - attr::LastAttributeId::s_id++; -template -unsigned Attribute::s_bit = - attr::BitAssignment::s_bit++; +const unsigned Attribute::s_id = + Attribute::checkID(attr::LastAttributeId::s_id++); template -unsigned Attribute::s_hashValue = Attribute::s_id; +const unsigned Attribute::s_hashValue = Attribute::s_id; class AttributeManager; @@ -426,10 +354,12 @@ struct getTable { //inline AttrHash >& get(AttributeManager& am); }; +// ATTRIBUTE MANAGER =========================================================== + class AttributeManager { NodeManager* d_nm; - AttrHash d_bools; + AttrHash d_bools; AttrHash d_ints; AttrHash d_exprs; AttrHash d_strings; @@ -445,10 +375,14 @@ public: typename AttrKind::value_type getAttribute(const Node& n, const AttrKind&); + template + bool hasAttribute(const Node& n, + const AttrKind&); + template bool hasAttribute(const Node& n, const AttrKind&, - typename AttrKind::value_type* = NULL); + typename AttrKind::value_type*); template void setAttribute(const Node& n, @@ -456,9 +390,11 @@ public: const typename AttrKind::value_type& value); }; +// MAPPING OF ATTRIBUTE KINDS TO TABLES IN THE ATTRIBUTE MANAGER =============== + template <> struct getTable { - typedef AttrHash table_type; + typedef AttrHash table_type; static inline table_type& get(AttributeManager& am) { return am.d_bools; } @@ -496,9 +432,11 @@ struct getTable { } }; +// ATTRIBUTE MANAGER IMPLEMENTATIONS =========================================== + template typename AttrKind::value_type AttributeManager::getAttribute(const Node& n, - const AttrKind& marker) { + const AttrKind&) { typedef typename AttrKind::value_type value_type; typedef KindValueToTableValueMapping mapping; @@ -511,30 +449,95 @@ typename AttrKind::value_type AttributeManager::getAttribute(const Node& n, return typename AttrKind::value_type(); } - return mapping::convertBack(i->second); + return mapping::convertBack((*i).second); } +/* helper template class for hasAttribute(), specialized based on + * whether AttrKind has a "default value" that all Nodes implicitly + * have or not. */ +template +struct HasAttribute; + template -bool AttributeManager::hasAttribute(const Node& n, - const AttrKind&, - typename AttrKind::value_type* ret) { +struct HasAttribute { + static inline bool hasAttribute(AttributeManager* am, + const Node& n) { + return true; + } - typedef typename AttrKind::value_type value_type; - typedef KindValueToTableValueMapping mapping; - typedef typename getTable::table_type table_type; + static inline bool hasAttribute(AttributeManager* am, + const Node& n, + typename AttrKind::value_type* ret) { + if(ret != NULL) { + typedef typename AttrKind::value_type value_type; + typedef KindValueToTableValueMapping mapping; + typedef typename getTable::table_type table_type; - table_type& ah = getTable::get(*this); - typename table_type::iterator i = ah.find(std::make_pair(AttrKind::getId(), n)); + table_type& ah = getTable::get(*am); + typename table_type::iterator i = ah.find(std::make_pair(AttrKind::getId(), n)); - if(i == ah.end()) { - return false; + if(i == ah.end()) { + *ret = AttrKind::default_value; + } else { + *ret = mapping::convertBack((*i).second); + } + } + + return true; } +}; + +template +struct HasAttribute { + static inline bool hasAttribute(AttributeManager* am, + const Node& n) { + typedef typename AttrKind::value_type value_type; + typedef KindValueToTableValueMapping mapping; + typedef typename getTable::table_type table_type; + + table_type& ah = getTable::get(*am); + typename table_type::iterator i = ah.find(std::make_pair(AttrKind::getId(), n)); + + if(i == ah.end()) { + return false; + } - if(ret != NULL) { - *ret = mapping::convertBack(i->second); + return true; } - return true; + static inline bool hasAttribute(AttributeManager* am, + const Node& n, + typename AttrKind::value_type* ret) { + typedef typename AttrKind::value_type value_type; + typedef KindValueToTableValueMapping mapping; + typedef typename getTable::table_type table_type; + + table_type& ah = getTable::get(*am); + typename table_type::iterator i = ah.find(std::make_pair(AttrKind::getId(), n)); + + if(i == ah.end()) { + return false; + } + + if(ret != NULL) { + *ret = mapping::convertBack((*i).second); + } + + return true; + } +}; + +template +bool AttributeManager::hasAttribute(const Node& n, + const AttrKind&) { + return HasAttribute::hasAttribute(this, n); +} + +template +bool AttributeManager::hasAttribute(const Node& n, + const AttrKind&, + typename AttrKind::value_type* ret) { + return HasAttribute::hasAttribute(this, n, ret); } template @@ -550,23 +553,6 @@ inline void AttributeManager::setAttribute(const Node& n, ah[std::make_pair(AttrKind::getId(), n)] = mapping::convert(value); } -/* - -template -struct last_attribute_id { - static unsigned value; -}; - -template -unsigned last_attribute_id::value = 0; - -template -unsigned register_attribute_kind() { - return last_attribute_id::value++; -} - -*/ - }/* CVC4::expr namespace */ }/* CVC4 namespace */ diff --git a/src/util/output.cpp b/src/util/output.cpp index fdc54d9b5..278158ad1 100644 --- a/src/util/output.cpp +++ b/src/util/output.cpp @@ -18,18 +18,108 @@ #include #include "util/output.h" +using namespace std; + namespace CVC4 { /* Definitions of the declared globals from output.h... */ null_streambuf null_sb; -std::ostream null_os(&null_sb); - -DebugC DebugOut (&std::cout); -WarningC Warning(&std::cerr); -MessageC Message(&std::cout); -NoticeC Notice (&std::cout); -ChatC Chat (&std::cout); -TraceC Trace (&std::cout); +ostream null_os(&null_sb); + +DebugC DebugOut(&cout); +WarningC Warning (&cerr); +MessageC Message (&cout); +NoticeC Notice (&cout); +ChatC Chat (&cout); +TraceC Trace (&cout); + +void DebugC::printf(const char* tag, const char* fmt, ...) { + if(d_tags.find(string(tag)) != d_tags.end()) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; + } +} + +void DebugC::printf(string tag, const char* fmt, ...) { + if(d_tags.find(tag) != d_tags.end()) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; + } +} + +void WarningC::printf(const char* fmt, ...) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; +} + +void MessageC::printf(const char* fmt, ...) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; +} + +void NoticeC::printf(const char* fmt, ...) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; +} + +void ChatC::printf(const char* fmt, ...) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; +} + +void TraceC::printf(const char* tag, const char* fmt, ...) { + if(d_tags.find(string(tag)) != d_tags.end()) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; + } +} + +void TraceC::printf(string tag, const char* fmt, ...) { + if(d_tags.find(tag) != d_tags.end()) { + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; + } +} }/* CVC4 namespace */ diff --git a/src/util/output.h b/src/util/output.h index f897fd1ca..94841a1f5 100644 --- a/src/util/output.h +++ b/src/util/output.h @@ -57,23 +57,46 @@ class CVC4_PUBLIC DebugC { public: DebugC(std::ostream* os) : d_os(os) {} - void operator()(const char* tag, const char*); - void operator()(const char* tag, std::string); - void operator()(std::string tag, const char*); - void operator()(std::string tag, std::string); + void operator()(const char* tag, const char* s) { + if(d_tags.find(std::string(tag)) != d_tags.end()) { + *d_os << s; + } + } - static void printf(const char* tag, const char* fmt, ...) __attribute__ ((format(printf, 2, 3))); - static void printf(std::string tag, const char* fmt, ...) __attribute__ ((format(printf, 2, 3))); + void operator()(const char* tag, const std::string& s) { + if(d_tags.find(std::string(tag)) != d_tags.end()) { + *d_os << s; + } + } + + void operator()(const std::string& tag, const char* s) { + if(d_tags.find(tag) != d_tags.end()) { + *d_os << s; + } + } + + void operator()(const std::string& tag, const std::string& s) { + if(d_tags.find(tag) != d_tags.end()) { + *d_os << s; + } + } + + void printf(const char* tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))); + void printf(std::string tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))); std::ostream& operator()(const char* tag) { - if(d_tags.find(std::string(tag)) != d_tags.end()) + if(d_tags.find(std::string(tag)) != d_tags.end()) { return *d_os; - else return null_os; + } else { + return null_os; + } } std::ostream& operator()(std::string tag) { - if(d_tags.find(tag) != d_tags.end()) + if(d_tags.find(tag) != d_tags.end()) { return *d_os; - else return null_os; + } else { + return null_os; + } } /** * The "Yeting option" - this allows use of Debug() without a tag @@ -190,28 +213,23 @@ public: void operator()(std::string tag, const char*); void operator()(std::string tag, std::string); - void printf(const char* tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))) { - // chop off output after 1024 bytes - char buf[1024]; - va_list vl; - va_start(vl, fmt); - vsnprintf(buf, sizeof(buf), fmt, vl); - va_end(vl); - *d_os << buf; - } - void printf(std::string tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))) { - } + void printf(const char* tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))); + void printf(std::string tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))); std::ostream& operator()(const char* tag) { - if(d_tags.find(tag) != d_tags.end()) + if(d_tags.find(tag) != d_tags.end()) { return *d_os; - else return null_os; + } else { + return null_os; + } } std::ostream& operator()(std::string tag) { - if(d_tags.find(tag) != d_tags.end()) + if(d_tags.find(tag) != d_tags.end()) { return *d_os; - else return null_os; + } else { + return null_os; + } } void on (const char* tag) { d_tags.insert(std::string(tag)); }; diff --git a/test/unit/expr/node_white.h b/test/unit/expr/node_white.h index 73a7b1a54..e2e1a94fd 100644 --- a/test/unit/expr/node_white.h +++ b/test/unit/expr/node_white.h @@ -31,12 +31,16 @@ struct Test1; struct Test2; struct Test3; struct Test4; +struct Test5; typedef Attribute TestStringAttr1; typedef Attribute TestStringAttr2; -typedef Attribute TestFlag1; -typedef Attribute TestFlag2; +typedef Attribute TestFlag1; +typedef Attribute TestFlag2; +typedef Attribute TestFlag3; +typedef Attribute TestFlag4; +typedef Attribute TestFlag5; class NodeWhite : public CxxTest::TestSuite { @@ -82,15 +86,17 @@ public: TS_ASSERT(TestFlag1::s_id == 0); TS_ASSERT(TestFlag2::s_id == 1); - TS_ASSERT(attr::LastAttributeId::s_id == 2); - TS_ASSERT(TestFlag1::s_bit == 0); - TS_ASSERT(TestFlag2::s_bit == 1); - TS_ASSERT(attr::BitAssignment::s_bit == 2); + TS_ASSERT(TestFlag3::s_id == 2); + TS_ASSERT(TestFlag4::s_id == 3); + TS_ASSERT(TestFlag5::s_id == 4); + TS_ASSERT(attr::LastAttributeId::s_id == 5); } void testAttributes() { AttributeManager& am = d_nm->d_am; + //Debug.on("boolattr"); + Node a = d_nm->mkVar(); Node b = d_nm->mkVar(); Node c = d_nm->mkVar(); @@ -100,16 +106,211 @@ public: b.setAttribute(VarNameAttr(), "b"); c.setAttribute(VarNameAttr(), "c"); + // test that all boolean flags are FALSE to start + Debug("boolattr", "get flag 1 on a (should be F)\n"); + TS_ASSERT(! a.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on b (should be F)\n"); + TS_ASSERT(! b.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on c (should be F)\n"); + TS_ASSERT(! c.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on unnamed (should be F)\n"); + TS_ASSERT(! unnamed.getAttribute(TestFlag1())); + + Debug("boolattr", "get flag 2 on a (should be F)\n"); + TS_ASSERT(! a.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on b (should be F)\n"); + TS_ASSERT(! b.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on c (should be F)\n"); + TS_ASSERT(! c.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on unnamed (should be F)\n"); + TS_ASSERT(! unnamed.getAttribute(TestFlag2())); + + Debug("boolattr", "get flag 3 on a (should be F)\n"); + TS_ASSERT(! a.getAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on b (should be F)\n"); + TS_ASSERT(! b.getAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on c (should be F)\n"); + TS_ASSERT(! c.getAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on unnamed (should be F)\n"); + TS_ASSERT(! unnamed.getAttribute(TestFlag3())); + + Debug("boolattr", "get flag 4 on a (should be F)\n"); + TS_ASSERT(! a.getAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on b (should be F)\n"); + TS_ASSERT(! b.getAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on c (should be F)\n"); + TS_ASSERT(! c.getAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on unnamed (should be F)\n"); + TS_ASSERT(! unnamed.getAttribute(TestFlag4())); + + Debug("boolattr", "get flag 5 on a (should be F)\n"); + TS_ASSERT(! a.getAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on b (should be F)\n"); + TS_ASSERT(! b.getAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on c (should be F)\n"); + TS_ASSERT(! c.getAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on unnamed (should be F)\n"); + TS_ASSERT(! unnamed.getAttribute(TestFlag5())); + + // test that they all HAVE the boolean attributes + Debug("boolattr", "get flag 1 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag1())); + + Debug("boolattr", "get flag 2 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag2())); + + Debug("boolattr", "get flag 3 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag3())); + + Debug("boolattr", "get flag 4 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag4())); + + Debug("boolattr", "get flag 5 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag5())); + + // test two-arg version of hasAttribute() + bool bb; + Debug("boolattr", "get flag 1 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag1(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 1 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag1(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 1 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag1(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 1 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag1(), &bb)); + TS_ASSERT(! bb); + + Debug("boolattr", "get flag 2 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag2(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 2 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag2(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 2 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag2(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 2 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag2(), &bb)); + TS_ASSERT(! bb); + + Debug("boolattr", "get flag 3 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag3(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 3 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag3(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 3 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag3(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 3 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag3(), &bb)); + TS_ASSERT(! bb); + + Debug("boolattr", "get flag 4 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag4(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 4 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag4(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 4 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag4(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 4 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag4(), &bb)); + TS_ASSERT(! bb); + + Debug("boolattr", "get flag 5 on a (should be F)\n"); + TS_ASSERT(a.hasAttribute(TestFlag5(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 5 on b (should be F)\n"); + TS_ASSERT(b.hasAttribute(TestFlag5(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 5 on c (should be F)\n"); + TS_ASSERT(c.hasAttribute(TestFlag5(), &bb)); + TS_ASSERT(! bb); + Debug("boolattr", "get flag 5 on unnamed (should be F)\n"); + TS_ASSERT(unnamed.hasAttribute(TestFlag5(), &bb)); + TS_ASSERT(! bb); + + // setting boolean flags + Debug("boolattr", "set flag 1 on a to T\n"); a.setAttribute(TestFlag1(), true); + Debug("boolattr", "set flag 1 on b to F\n"); b.setAttribute(TestFlag1(), false); + Debug("boolattr", "set flag 1 on c to F\n"); c.setAttribute(TestFlag1(), false); + Debug("boolattr", "set flag 1 on unnamed to T\n"); unnamed.setAttribute(TestFlag1(), true); + Debug("boolattr", "set flag 2 on a to F\n"); a.setAttribute(TestFlag2(), false); + Debug("boolattr", "set flag 2 on b to T\n"); b.setAttribute(TestFlag2(), true); + Debug("boolattr", "set flag 2 on c to T\n"); c.setAttribute(TestFlag2(), true); + Debug("boolattr", "set flag 2 on unnamed to F\n"); unnamed.setAttribute(TestFlag2(), false); + Debug("boolattr", "set flag 3 on a to T\n"); + a.setAttribute(TestFlag3(), true); + Debug("boolattr", "set flag 3 on b to T\n"); + b.setAttribute(TestFlag3(), true); + Debug("boolattr", "set flag 3 on c to T\n"); + c.setAttribute(TestFlag3(), true); + Debug("boolattr", "set flag 3 on unnamed to T\n"); + unnamed.setAttribute(TestFlag3(), true); + + Debug("boolattr", "set flag 4 on a to T\n"); + a.setAttribute(TestFlag4(), true); + Debug("boolattr", "set flag 4 on b to T\n"); + b.setAttribute(TestFlag4(), true); + Debug("boolattr", "set flag 4 on c to T\n"); + c.setAttribute(TestFlag4(), true); + Debug("boolattr", "set flag 4 on unnamed to T\n"); + unnamed.setAttribute(TestFlag4(), true); + + Debug("boolattr", "set flag 5 on a to T\n"); + a.setAttribute(TestFlag5(), true); + Debug("boolattr", "set flag 5 on b to T\n"); + b.setAttribute(TestFlag5(), true); + Debug("boolattr", "set flag 5 on c to F\n"); + c.setAttribute(TestFlag5(), false); + Debug("boolattr", "set flag 5 on unnamed to T\n"); + unnamed.setAttribute(TestFlag5(), true); + TS_ASSERT(a.getAttribute(VarNameAttr()) == "a"); TS_ASSERT(a.getAttribute(VarNameAttr()) != "b"); TS_ASSERT(a.getAttribute(VarNameAttr()) != "c"); @@ -142,16 +343,51 @@ public: TS_ASSERT(! c.hasAttribute(TestStringAttr2())); TS_ASSERT(! unnamed.hasAttribute(TestStringAttr2())); + Debug("boolattr", "get flag 1 on a (should be T)\n"); TS_ASSERT(a.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on b (should be F)\n"); TS_ASSERT(! b.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on c (should be F)\n"); TS_ASSERT(! c.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 1 on unnamed (should be T)\n"); TS_ASSERT(unnamed.getAttribute(TestFlag1())); + Debug("boolattr", "get flag 2 on a (should be F)\n"); TS_ASSERT(! a.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on b (should be T)\n"); TS_ASSERT(b.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on c (should be T)\n"); TS_ASSERT(c.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 2 on unnamed (should be F)\n"); TS_ASSERT(! unnamed.getAttribute(TestFlag2())); + Debug("boolattr", "get flag 3 on a (should be T)\n"); + TS_ASSERT(a.getAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on b (should be T)\n"); + TS_ASSERT(b.getAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on c (should be T)\n"); + TS_ASSERT(c.getAttribute(TestFlag3())); + Debug("boolattr", "get flag 3 on unnamed (should be T)\n"); + TS_ASSERT(unnamed.getAttribute(TestFlag3())); + + Debug("boolattr", "get flag 4 on a (should be T)\n"); + TS_ASSERT(a.getAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on b (should be T)\n"); + TS_ASSERT(b.getAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on c (should be T)\n"); + TS_ASSERT(c.getAttribute(TestFlag4())); + Debug("boolattr", "get flag 4 on unnamed (should be T)\n"); + TS_ASSERT(unnamed.getAttribute(TestFlag4())); + + Debug("boolattr", "get flag 5 on a (should be T)\n"); + TS_ASSERT(a.getAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on b (should be T)\n"); + TS_ASSERT(b.getAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on c (should be F)\n"); + TS_ASSERT(! c.getAttribute(TestFlag5())); + Debug("boolattr", "get flag 5 on unnamed (should be T)\n"); + TS_ASSERT(unnamed.getAttribute(TestFlag5())); + a.setAttribute(TestStringAttr1(), "foo"); b.setAttribute(TestStringAttr1(), "bar"); c.setAttribute(TestStringAttr1(), "baz");