lookup table, tree or ..

Consider

# include <iostream>
# include <cstdio>

class Exterior {
public:
	/* union discriminant  */
	/* union   */
};
class OuterBoundary {
	/* union discriminant  */
	/* union   */
};

#ifndef PolygonType
#define PolygonType (1114)
/* xsd:choice */
union union_PType
{
#define PolygonType_exterior	(1)
	Exterior      *exterior;
#define PolygonType_outerBoundaryIs	(2)
	OuterBoundary *outerBoundaryIs;
};
#endif

class PType
{
public:
	int __unionexterior;	/* union discriminant (of union defined below) */
	union union_PType __union_PolygonType;
};

typedef std::vector < std::string > STRING_VEC ;
STRING_VEC sequence ;

int main( int ac, char** av )
{

	PType xxxx;
	xxxx.__unionexterior  =  PolygonType_exterior; // simualate

	if ( xxxx.__unionexterior == PolygonType_exterior ) {
      Exterior * const ptr =  xxxx.__union_PolygonType.exterior;
      if ( ptr ) {
        std::cout << " 1 " << std::endl;
         // repeat ..
    	 // if ( ptr -> some union discriminant == pre processing directive  )

      }
	} else if ( xxxx.__unionexterior == PolygonType_outerBoundaryIs  ) {
	  OuterBoundary * const ptr =  xxxx.__union_PolygonType.outerBoundaryIs;
	  if ( ptr ) {
	    // repeat ..
	    /// if ( ptr -> some union discriminant == pre processing directive  )
	  }
	} else {
       }
    return EXIT_SUCCESS ;
}

Open in new window


A method in a vendor (COTS) API returns PType.   From there I parse a type ‘PType’ to :
a)     Check a ‘union discriminant’ (preprocessor directive) to determine an appropriate type.
b)    Determine which member to access.    For instance the code above checks the directives in union_PType to determine which member:  Exterior or OuterBoundary to access.  

In some cases this process continues until I encounter a type that’s not encapsulated in a union.   How could I setup a tree like structure or lookup table to avoid the litany of if statements (I have a lot of nested ifs in the ‘real’ code) polluting the code?    Sample (working or pseudo) code will suffice.   Boost BGL seems like an option but still trying to wrap my head around its use.  

I'm open to other options.  Really want to simplify the litany of 'if statements'.   I've consider use of BOOST_FUSION to traverse the structs but I think that falls short given I'm not sure how to map the 'discriminants' to the appropriate types
forums_mpAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sarabandeCommented:
you could do what looks like a "virtual" constructor:

typedef Variant* (*MakeVariant)(union_pType & upt);
class Variant
{
     static std::map<int, MakeVariant> makeMap;
public:
     static Variant * makeVariant(PType ptype)
     {
           Variant * pvar = NULL;
           if (makeMap.find(ptype.__unionexterior) != makeMap.end())
           {
                   pvar = makeMap[ptype.__unionexterior](ptype.__union_polygonType);
           }
           return pvar;
     }
     static bool addMakeFunc(int type, MakeFunc mfunc)
     {
            makeMap[type] = mfunc;
            return true;
     }
       // virtual functions
       virtual bool IsExterior() { return false; }
       virtual bool IsOuterBoundaries() { return false; }
       virtual bool Execute() = 0;
       ...
};


class VariantExterior : public Variant
{
       Exterior * pExt;
       static bool makeFunc_added;
public:
       VariantExterior(Exterior * p) : pExt(p) { }
       static Variant * makeVariantExterior(union_pType * upt)
       {
             return new VariantExterior(upt.exterior);
       }
       // virtual functions
       bool IsExterior() { return true; }
       bool Execute() { .... };
       ...
}

class VariantOuterBoundaries : public Variant
{
       OuterBoundaries* pOuterBoundaries;
       static bool makeFunc_added;
public:
       VariantOuterBoundaries(OuterBoundaries * p) : pOuterBoundaries(p) { }
       static Variant * makeVariantOuterBoundaries (union_pType upt)
       {
             return new VariantOuterBoundaries (upt.outerBoundaries);
       }
       ...
       // virtual functions
       bool IsOuterBoundaries() { return true; }
       bool Execute() { .... };
       ...
}

// variant.cpp
...
// static initialization adds the function pointers
bool VariantExterior::makeFunc_added = 
    Variant::addMakeFunc(PolygonType_exterior, VariantExterior::makeVariantExterior);
bool OuterBoundaries::makeFunc_added = 
    Variant::addMakeFunc(PolygonType_outerBoundearies, VariantOuterBoundaries::makeVariantOuterBoundaries);

int main(...)
{
     ...
     Exterior ext = { 0 };
     PType xxxx;
     xxxx.__unionexterior  =  PolygonType_exterior; // simualate
     xxxx.exterior = &ext;

     Variant * pVar = Variant::makeVariant(xxxx);
     if (pVar == NULL)
           return -1;
     if (pVar->IsExterior())
     {
          ....
     }
     pVar->Execute();

Open in new window


the above "magically" would turn a PType to a Variant* which you could use as a baseclass pointer (for example in containers) and then use without if statements by means of virtual functions.

note, in a client-server environment you may have different variant classes for the client and the server for the same union type.

Sara
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.