Click here to Skip to main content
15,895,777 members
Articles / Desktop Programming / MFC

Another Enum Viewer

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
22 Oct 20015 min read 83K   1.3K   19  
An article on the usage and design of another Enum Viewer
// CPPTypeBuiltin.cpp:  Builtin-type class

#include "CPPType.h"
#include "CPPTypeBuiltin.h"

#ifdef _MSC_VER
   // Disable some warnings that appear commonly in Rogue Wave STL
   #pragma warning (disable:4786)    // long debug names
   #pragma warning (disable:4146)    // unary minus operator applied to unsigned type
   #pragma warning (disable:4018)    // '>' : signed/unsigned mismatch
#endif

#include <vector>

// These should really be nested classes, but #@$&^*@#*&^$ MSVC++ 5.0 
// can't deal with nested classes as template parameters to vector<>

// TypeSpecifier compatibility table
struct CompatTable {
   CompatTable(
      CPPConst::TypeSpecifier toCheck_ = CPPConst::tsNONE,
      CPPConst::TypeSpecifier compatibleWith_ = CPPConst::tsNONE
   ) : 
      toCheck(toCheck_), 
      compatibleWith(compatibleWith_)
   {}
   CPPConst::TypeSpecifier toCheck;
   CPPConst::TypeSpecifier compatibleWith;

	// Need these because MSVC++ 5.0 is brain dead
	bool operator<(const CompatTable& rhs) const { return true; }
	bool operator==(const CompatTable& rhs) const { return true; }
};

// TypeSpecifier name table
struct NameTable {
   NameTable(
      CPPConst::TypeSpecifier ts_ = CPPConst::tsNONE,
      const JLStr& name_ = ""
   ) : ts(ts_), name(name_) {}
   CPPConst::TypeSpecifier ts;
   JLStr name;

	// Need these because MSVC++ 5.0 is brain dead
	bool operator<(const NameTable& rhs) const { return true; }
	bool operator==(const NameTable& rhs) const { return true; }
};

class CPPTypeBuiltin::NameTableVector : 
public vector<NameTable, allocator<NameTable> > 
{
};

class CPPTypeBuiltin::CompatTableVector : 
public vector<CompatTable, allocator<CompatTable> > 
{
};


////////////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////////////
CPPTypeBuiltin::CPPTypeBuiltin(
   CPPConst::TypeSpecifier typeSpecifier_
) :
   CPPType(Builtin),
   typeSpecifier(typeSpecifier_)
{
   // Make sure only valid types are entered.
   assert(TypeSpecifierIsValid(typeSpecifier));
}


/////////////////////////////////////////////////////////////////
// FormatName: Format the name of the type, using the names of the
// modified types where needed to construct the full type name.
//
// Inputs:
//    const JLStr&  declName   If non-empty, then this is used
//                              to format the declarator name
//                              in the proper position.
//    const JLStr&  suffixStr  Any accumulated suffix string
// Return:
//    JLStr    The formatted type name
/////////////////////////////////////////////////////////////////
// virtual 
JLStr 
CPPTypeBuiltin::FormatName(
   const JLStr& declName,
   const JLStr& suffixStr,
   StrListRefI,
   bool
) const
{
   assertValid();
   JLStr tmpStr = FormatTypeSpecifierName(typeSpecifier);
   if (declName.length() != 0 || suffixStr.length() != 0)
   {
      tmpStr += " " + declName + suffixStr;
   }
   return tmpStr;
}


/////////////////////////////////////////////////////////////////
// FormatTypeSpecifierName: Format the name of the type specifiers.
//
// Inputs:
//    CPPConst::TypeSpecifier   ts   The type specifiers
// Return:
//    JLStr    The formatted type name
/////////////////////////////////////////////////////////////////
// static 
JLStr 
CPPTypeBuiltin::FormatTypeSpecifierName(
   CPPConst::TypeSpecifier ts
)
{
   JLStr retval;

   InitTables();
   for (
      NameTableVector::iterator iter = nameTable->begin();
      iter != nameTable->end();
      iter++
   )
   {
      if ((ts & (*iter).ts) != 0)
      {
         if (retval.length() != 0)
         {
            retval += " ";
         }
         retval += (*iter).name;
      }
   }

   return retval;
}

////////////////////////////////////////////////////////////////////
// TypeSpecifierIsValid: static method to validate a type
// specifier.  This works by checking each ORable component
// of the type specifier against each other component, using
// a table of mutual-exclusivity.
////////////////////////////////////////////////////////////////////
// static
bool 
CPPTypeBuiltin::TypeSpecifierIsValid(
   CPPConst::TypeSpecifier typeSpecifier
)
{
   // The compatibility table is independent of the order
   // of the entries and the values of the ts* constants
   // except that tsNONE = 0 (believe it or not...)

   InitTables();

   for (
      CompatTableVector::iterator iter = compatTable->begin();
      iter != compatTable->end();
      iter++
   )
   {
      if ((typeSpecifier & (*iter).toCheck) != CPPConst::tsNONE)
      {
         if ((typeSpecifier & ~(*iter).compatibleWith) != CPPConst::tsNONE)
         {
            return false;
         }
      }
   }
   return true;
}


////////////////////////////////////////////////////////////////////
// InitStatic: initialize the tables used by CPPTypeBuiltin
// We cannot initialize these at compile-time because they
// depend on other static globals being initialized first.
////////////////////////////////////////////////////////////////////
void
CPPTypeBuiltin::InitTables()
{
   if (compatTable != 0)
   {
      return;
   }

   // Initialize builtin type compatibility table
   compatTable = new CompatTableVector;
   compatTable->push_back(CompatTable(
      CPPConst::tsVOID,
      CPPConst::tsVOID
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsCHAR,
      CPPConst::tsCHAR|CPPConst::tsSIGNED|CPPConst::tsUNSIGNED
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsSHORT,
      CPPConst::tsSHORT|CPPConst::tsINT|CPPConst::tsSIGNED|CPPConst::tsUNSIGNED
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsINT,
      CPPConst::tsINT|CPPConst::tsLONG|CPPConst::tsSHORT|CPPConst::tsSIGNED|
         CPPConst::tsUNSIGNED
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsLONG,
      CPPConst::tsLONG|CPPConst::tsINT|CPPConst::tsDOUBLE|CPPConst::tsSIGNED|
         CPPConst::tsUNSIGNED
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsFLOAT,
      CPPConst::tsFLOAT
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsDOUBLE,
      CPPConst::tsLONG|CPPConst::tsDOUBLE
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsSIGNED,
      CPPConst::tsSIGNED|CPPConst::tsCHAR|CPPConst::tsSHORT|CPPConst::tsINT|
         CPPConst::tsLONG|CPPConst::tsINT64
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsUNSIGNED,
      CPPConst::tsUNSIGNED|CPPConst::tsCHAR|CPPConst::tsSHORT|CPPConst::tsINT|
         CPPConst::tsLONG|CPPConst::tsINT64
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsTYPEID,
      CPPConst::tsNONE
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsSTRUCT,
      CPPConst::tsNONE
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsENUM,
      CPPConst::tsNONE
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsUNION,
      CPPConst::tsNONE
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsCLASS,
      CPPConst::tsNONE
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsWCHAR_T,
      CPPConst::tsWCHAR_T
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsBOOL,
      CPPConst::tsBOOL
   ));
   compatTable->push_back(CompatTable(
      CPPConst::tsINT64,
      CPPConst::tsINT64|CPPConst::tsSIGNED|CPPConst::tsUNSIGNED
   ));


   // Initialize builtin-type name table.  The name table includes
   // names for type specifiers that are not valid builtin types,
   // for convenience.
   nameTable = new NameTableVector;
   nameTable->push_back(NameTable(CPPConst::tsSIGNED, "signed"));
   nameTable->push_back(NameTable(CPPConst::tsUNSIGNED, "unsigned"));
   nameTable->push_back(NameTable(CPPConst::tsSHORT, "short"));
   nameTable->push_back(NameTable(CPPConst::tsLONG, "long"));
   nameTable->push_back(NameTable(CPPConst::tsCHAR, "char"));
   nameTable->push_back(NameTable(CPPConst::tsINT, "int"));
   nameTable->push_back(NameTable(CPPConst::tsFLOAT, "float"));
   nameTable->push_back(NameTable(CPPConst::tsDOUBLE, "double"));
   nameTable->push_back(NameTable(CPPConst::tsWCHAR_T, "wchar_t"));
   nameTable->push_back(NameTable(CPPConst::tsBOOL, "bool"));
   nameTable->push_back(NameTable(CPPConst::tsINT64, "int64"));
   nameTable->push_back(NameTable(CPPConst::tsVOID, "void"));
   nameTable->push_back(NameTable(CPPConst::tsENUM, "enum"));
   nameTable->push_back(NameTable(CPPConst::tsCLASS, "class"));
   nameTable->push_back(NameTable(CPPConst::tsSTRUCT, "struct"));
   nameTable->push_back(NameTable(CPPConst::tsUNION, "union"));
   nameTable->push_back(NameTable(CPPConst::tsNONE, ""));
}

CPPTypeBuiltin::CompatTableVector *CPPTypeBuiltin::compatTable;
CPPTypeBuiltin::NameTableVector *CPPTypeBuiltin::nameTable;

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions