Files
geant4/source/geometry/solids/STEP/include/complexSupport.h
T
2016-06-08 15:42:07 +02:00

352 lines
12 KiB
C++

#ifndef COMPLEXSUP_H
#define COMPLEXSUP_H
/*****************************************************************************
* complexSupport.h *
* *
* Description: Slightly simplified version of fedex_plus's complexSupport.h.*
* This version works with the SCL and is used to validate *
* complex entities (user requests to build them). It does not *
* contain info for building these structures from a fedex *
* Express object, as the fedex_plus version. *
* *
* Created by: David Rosenfeld *
* Date: 5/9/97 *
*****************************************************************************/
#include "g4std/iostream"
#include "g4std/fstream"
/*
extern "C"
{
#include <stdio.h>
#include <string.h>
#include <ctype.h>
}
*/
#include "Str.h"
#define FALSE 0
#define TRUE 1
#define LISTEND 999
// LISTEND signifies that an OrList has gone beyond its last viable choice
// among its children.
enum MarkType {
NOMARK, ORMARK, MARK
};
// MARK is the usual value we'd mark with. If we mark with ORMARK, it means
// an OrList marked this node, so we'll know it may become unmarked later if
// we try another choice.
enum MatchType {
UNKNOWN, UNSATISFIED, SATISFIED, MATCHSOME, MATCHALL, NEWCHOICE, NOMORE
};
// These are the conditions the EntList::match() functions may return. They
// are also the assigned values to EntList::viable.
//
// UNKNOWN - The default EntList::viable value - before any matching
// has been attempted.
// UNSATISFIED - EntList had conditions that EntNode did not satisfy (e.g.,
// EntList specified A AND B while EntNode only contained an
// A).
// SATISFIED - EntList had no conditions EntNode did not meet. But,
// EntList did not match (mark) any nodes of EntNode which
// were not already matched.
// MATCHSOME - EntList matched some of the nodes in EntNode.
// MATCHALL - EntList matched all the nodes in EntNode (complex entity
// can be instantiated).
// MORECHOICES - Special case - when trying alternate OR paths, this return
// value signifies that we have found another choice.
// NOMORE - Special case - when trying alternate OR paths, this return
// value signifies that no more alternates within this path.
enum JoinType {
SIMPLE, AND, OR, ANDOR
};
class SimpleList;
class MultList;
class JoinList;
class AndOrList;
class AndList;
class OrList;
class ComplexList;
class ComplexCollect;
class EntNode {
friend class SimpleList;
friend class AndOrList;
friend class AndList;
friend class OrList;
friend class ComplexList;
public:
EntNode( const char *nm="" ) : next(0), mark(NOMARK), multSupers(0)
{ StrToLower( nm, name ); }
EntNode( const char ** ); // given a list, create a
~EntNode() { if ( next ) delete next; } // linked list of EntNodes
operator const char *() { return name; }
// Added missing return types to following operator definitions - GC
int operator== ( EntNode &ent )
{ return ( strcmp( name, ent.name ) == 0 ); }
int operator< ( EntNode &ent )
{ return ( strcmp( name, ent.name ) < 0 ); }
int operator> ( EntNode &ent )
{ return ( strcmp( name, ent.name ) > 0 ); }
EntNode &operator= ( EntNode &ent );
void Name( const char *nm ) { strncpy( name, nm, BUFSIZ-1 ); }
const char *Name() { return name; }
void setmark( MarkType stamp=MARK ) { mark = stamp; }
void markAll( MarkType=MARK );
void unmarkAll() { markAll( NOMARK ); }
int marked( MarkType base=ORMARK ) { return ( mark >= base ); }
int allMarked(); // returns TRUE if all nodes in list are marked
int unmarkedCount();
int multSuprs() { return multSupers; }
void multSuprs( int j ) { multSupers = j; }
void sort( EntNode ** );
EntNode *next;
private:
MarkType mark;
char name[BUFSIZ];
int multSupers; // do I correspond to an entity with >1 supertype?
EntNode *lastSmaller( EntNode * ); // used by ::sort()
};
class EntList {
friend class MultList;
friend class JoinList;
friend class OrList;
friend class ComplexList;
friend class ComplexCollect;
friend G4std::ostream & operator<< ( G4std::ostream &, EntList & );
friend G4std::ostream & operator<< ( G4std::ostream &, MultList & );
public:
EntList( JoinType j ) : join(j), prev(0), next(0), viable(UNKNOWN),
level(0) {}
virtual ~EntList() {}
MatchType viableVal() { return viable; }
virtual void setLevel( int l ) { level = l; }
virtual int contains( char * ) =0;
virtual int hit( char * ) =0;
virtual MatchType matchNonORs( EntNode * ) { return UNKNOWN; }
virtual int acceptChoice( EntNode * ) =0;
virtual void unmarkAll( EntNode * ) =0;
virtual void reset() { viable = UNKNOWN; }
int siblings();
// List access functions. They access desired children based on their
// join or viable values. Below is an incomplete list of possible fns,
// but all we need.
EntList *firstNot( JoinType );
EntList *nextNot( JoinType j ) { return next->firstNot( j ); }
EntList *firstWanted( MatchType );
EntList *nextWanted( MatchType mat ) { return next->firstWanted( mat ); }
EntList *lastNot( JoinType );
EntList *prevNot( JoinType j ) { return prev->lastNot( j ); }
EntList *lastWanted( MatchType );
EntList *prevWanted( MatchType mat ) { return prev->lastWanted( mat ); }
JoinType join;
int multiple() { return ( join != SIMPLE ); }
EntList *next, *prev;
protected:
MatchType viable;
// How does this EntList match the complex type. Used especially if Ent-
// List's parent is an OrList or AndOrList to record if this child is an
// acceptable choice or not. For an AndOr, viable children are accepted
// right away. For Or, only one is accepted, but we keep track of the
// other possible solutions in case we'll want to try them.
int level; // How many levels deep are we (main use for printing).
};
class SimpleList : public EntList {
friend class ComplexList;
friend G4std::ostream & operator<< ( G4std::ostream &, SimpleList & );
public:
SimpleList( const char *n ) : I_marked(NOMARK), EntList(SIMPLE)
{ strcpy( name, n ); }
~SimpleList() {}
// Added missing return type - GC
int operator== ( const char *nm )
{ return ( strcmp( name, nm ) == 0 ); }
const char *Name() { return name; }
int contains( char *nm ) { return *this == nm; }
int hit( char *nm ) { return *this == nm; }
MatchType matchNonORs( EntNode * );
int acceptChoice( EntNode * );
void unmarkAll( EntNode * );
void reset() { viable = UNKNOWN; I_marked = NOMARK; }
private:
char name[BUFSIZ]; // Name of entity we correspond to.
MarkType I_marked; // Did I mark, and with what type of mark.
};
class MultList : public EntList {
// Supports concepts and functionality common to all the compound list
// types, especially AND and ANDOR.
friend class ComplexList;
friend class ComplexCollect;
friend G4std::ostream & operator<< ( G4std::ostream &, MultList & );
public:
MultList( JoinType j ) : EntList(j), supertype(0), numchildren(0),
childList(0) {}
~MultList();
void setLevel( int );
int contains( char * );
int hit( char * );
void appendList( EntList * );
EntList *copyList( EntList * );
virtual MatchType matchORs( EntNode * ) =0;
virtual MatchType tryNext( EntNode * );
int childCount() { return numchildren; }
// EntList *operator[]( int );
EntList *getChild( int );
EntList *getLast() { return ( getChild( numchildren-1 ) ); }
void unmarkAll( EntNode * );
int prevKnown( EntList * );
void reset();
protected:
int supertype; // do I represent a supertype?
int numchildren;
EntList *childList;
// Points to a list of "children" of this EntList. E.g., if join =
// AND, it would point to a list of the entity types we are AND'ing.
// The children may be SIMPLE EntLists (contain entity names) or may
// themselves be And-, Or-, or AndOrLists.
};
class JoinList : public MultList {
// A specialized MultList, super for subtypes AndOrList and AndList, or
// ones which join their multiple children.
public:
JoinList( JoinType j ) : MultList(j) {}
~JoinList() {}
void setViableVal( EntNode * );
int acceptChoice( EntNode * );
};
class AndOrList : public JoinList {
friend class ComplexList;
public:
AndOrList() : JoinList( ANDOR ) {}
~AndOrList() {}
MatchType matchNonORs( EntNode * );
MatchType matchORs( EntNode * );
};
class AndList : public JoinList {
friend class ComplexList;
friend G4std::ostream & operator<< ( G4std::ostream &, ComplexList & );
public:
AndList() : JoinList( AND ) {}
~AndList() {}
MatchType matchNonORs( EntNode * );
MatchType matchORs( EntNode * );
};
class OrList : public MultList {
public:
OrList() : MultList( OR ), choice(-1), choiceCount(0) {}
~OrList() {}
int hit( char * );
MatchType matchORs( EntNode * );
MatchType tryNext( EntNode * );
void unmarkAll( EntNode * );
int acceptChoice( EntNode * );
int acceptNextChoice( EntNode *ents )
{ choice++; return ( acceptChoice( ents ) ); }
void reset() { choice = -1; choiceCount = 0; MultList::reset(); }
private:
int choice, choice1, choiceCount;
// Which choice of our childList did we select from this OrList; what's
// the first viable choice; and how many choices are there entirely.
};
class ComplexList {
// Contains the entire list of EntLists which describe the set of
// instantiable complex entities defined by an EXPRESS expression.
friend class MultList;
friend class ComplexCollect;
friend G4std::ostream & operator<< ( G4std::ostream &, ComplexList & );
public:
// Changed 'and' to 'andl'. 'and' is reserved word in the standard - GC
ComplexList( AndList *andl = NULL ) : head(andl), list(0), next(0),
abstract(0), dependent(0),
multSupers(0) {}
~ComplexList();
void buildList();
void remove();
// Added missing return types to following operator definitions - GC
int operator< ( ComplexList &c )
{ return ( strcmp( supertype(), c.supertype() ) < 0 ); }
int operator< ( char *name )
{ return ( strcmp( supertype(), name ) < 0 ); }
int operator== ( char *name )
{ return ( strcmp( supertype(), name ) == 0 ); }
const char *supertype() { return ((SimpleList *)head->childList)->name; }
// Based on knowledge that ComplexList always created by ANDing supertype
// with subtypes.
int toplevel( const char * );
int contains( EntNode * );
int matches( EntNode * );
EntNode *list; // List of all entities contained in this complex type,
// regardless of how. (Used as a quick way of determining
// if this List *may* contain a certain complex type.)
AndList *head;
ComplexList *next;
int Dependent() { return dependent; }
private:
void addChildren( EntList * );
int hitMultNodes( EntNode * );
int abstract; // is our supertype abstract?
int dependent; // is our supertype also a subtype of other supertype(s)?
int multSupers; // am I a combo-CList created to test a subtype which has
}; // >1 supertypes?
class ComplexCollect {
// The collection of all the ComplexLists defined by the current schema.
public:
ComplexCollect( ComplexList *c = NULL ) : clists(c)
{ count = ( c ? 1 : 0 ); }
~ComplexCollect() { delete clists; }
void insert( ComplexList * );
void remove( ComplexList * );
// Remove this list but don't delete its hierarchy structure, because
// it's used elsewhere.
ComplexList *find( char * );
int supports( EntNode * ) const;
ComplexList *clists;
private:
int count; // # of clist children
};
#endif