September 4, 2015
Hot Topics:

The Story of a WML Generator

  • September 19, 2005
  • By Radu Braniste
  • Send Email »
  • More Articles »

Filtering was moved outside elements and is attached as a policy to GenericElement. Additional run-time safety was added via LateInsertCheck—more details when discussing the run-time features. Elements are tag typed to avoid circular dependencies and extra complexity (TagTypes.h):

struct IBreakImpl{};
struct IHeadImpl{};
struct IAnchorImpl{};
struct IParagraphImpl{};
struct ICardImpl{};

The IxxxImpl structures are not intended to be manipulated polymorphically and one might take the same precautions as with GenericElement, which has a non-virtual protected destructor.

Please note in the code above constructs of type:


This C++ lookup requirement is described in detail in [8].

Elements take as a template parameter the class they inherit from, thus allowing for different filters. Filters are defined separately (filters.h) and of course different implementations can coexist, the one to be used being selected at compile time. A filter acts mostly like an enabler—allowing or disallowing the compilation based on the filter parameter type.

struct BaseFilter
struct ParagraphFilter
   static void filter(const IAnchorImpl&){}
struct HeadFilter
   static void filter(const IBreakImpl&){}
struct CardFilter
   static void filter(const IParagraphImpl&){}
template < class P>
struct DeckFilter
   static void filter(const IHeadImpl& e)
      static void filter(const ICardImpl& e)
struct HeadBeforeBodyCheck
   static bool headIsFirstInADeck ;
   static void check(const IHeadImpl& e)
      assert (!headIsFirstInADeck && "head was used already");
      headIsFirstInADeck = true;
      static void check(const ICardImpl& e)
      assert (headIsFirstInADeck && "attempt to insert before head" );
bool HeadBeforeBodyCheck::headIsFirstInADeck = false;

DeckFilter offers a naïve example of a composite filter—checking at run-time whether a Header was inserted before the Cards in a Deck.

Here is an usage example (wmlExecution1.h):

   typedef CardImpl< GenericElement<CardFilter>, ICardImpl> Card;
   typedef HeadImpl<GenericElement<HeadFilter>, IHeadImpl> Head;
   typedef BreakImpl< GenericElement<BaseFilter>, IBreakImpl> Break;
   typedef DeckImpl< GenericElement<DeckFilter<HeadBeforeBodyCheck> >,
      IDeckImpl> Deck;
   typedef ParagraphImpl< GenericElement<ParagraphFilter>,
      IParagraphImpl> Paragraph;
   typedef AnchorImpl< GenericElement<BaseFilter>,
      IAnchorImpl> Anchor;
void doReadWML()
      typedef WML_TYPEDEF_HELPER::Card Card;
      typedef WML_TYPEDEF_HELPER::Head Head;
      typedef WML_TYPEDEF_HELPER::Break Break;
      typedef WML_TYPEDEF_HELPER::Deck Deck;
      typedef WML_TYPEDEF_HELPER::Paragraph Paragraph;
      typedef WML_TYPEDEF_HELPER::Anchor Anchor;
   Paragraph p;
   Break br;
   Head hd;
   Deck dk;
   Anchor a("href", "html");
   Card c;
   std::cout << static_cast<const std::string&>(dk) << std::endl;

WML_TYPEDEF_HELPER isolates the typedef declarations from the rest of the code, as an additional reusability unit.

Attempts like




are rejected by the compiler.

On the other hand,


raises an assertion violation at run time: failed assertion '!isClosed && "inserted after closed"'. This means that the element to be inserted has been already closed and used in a previous context.





has the same consequences as commenting out the first call to


namely: failed assertion headIsFirstInADeck && "attempt to insert before head", meaning that the header can be used only once, before inserting any card.


This article presented two flexible implementations of a compile-time safe generator for WML-like XML subsets, coded in C# and C++. Easy to configure for various validation rules, the generator offers an interesting alternative to other similar products based on XSTL workflow chains.

Download the Code

Download the C# source code here and the C++ source code here.


[1] http://www.openmobilealliance.org/tech/affiliates/wap/wapindex.html

[2] http://www.wapforum.org/DTD/

[3] mlgen.zip contains the .NET solution

[4] Implementing the entire WML specification is left as an exercise for the reader

[5] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrfusingdirective.asp

[6] http://www.objectmentor.com/resources/articles/ocp.pdf

[7] wmlgenerator.zip contains the C++ solution files

[8] http://www.comeaucomputing.com/techtalk/templates/#whythisarrow

Page 3 of 3

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel