Interpreting #define statement

Discussion in 'C++' started by psundara@gmail.com, Oct 31, 2005.

  1. Guest

    Hi,

    I'm facing a peculiar problem of finding a way to interpret header
    information in a smart way.

    I have this header file that is shared by many users, which contains,
    among things, a few #define statements that associate GUIDs wih a
    friendly name. For e.g. consider the file zoo.h:

    ....
    #define tiger GUID1
    #define lion GUID2
    #define striped_cat tiger
    ....

    This file can be updated - i.e. #define statements are
    added/removed/modified.

    Now, I want to accept the animal type as input from the user, switch
    based on the GUID, and print animal specific information to the user.
    Is it posible for me to have a user specify the animal type as name
    (i.e. tiger, lion etc.) instead of GUID? It would make it very
    convenient to the user.

    I have a few ideas, but they don't seem to be very elegant:

    1. Have the user specify name-to-GUID mappings in a separate file.

    2. Parse zoo.h and do create a string-to-GUID internally. However this
    is quite cumbersome as #define statements occur all over the place in
    different formats.

    Any pointers in this regard will be greatly appreciated!

    Thanks,
    Palani
     
    , Oct 31, 2005
    #1
    1. Advertising

  2. Chinchilla Guest

    I don't think using the preprocessor to define aliases for the user is
    elegant to begin with. If you want to make it friendly for the user and
    easier for you to update what you can do is use your idea of having a
    name-to-GUID mapping in a seperate file, and make a simple interface
    which the user can freely translate between name's and GUID's.
    ex:
    _GUID ntoguid(const char*);

    than the user can do something like ntoguid("lion"); and it'll return
    the correct one.

    It entirely depends on what you want to do. I personally would force
    users to memorize things. :)
     
    Chinchilla, Oct 31, 2005
    #2
    1. Advertising

  3. mlimber Guest

    wrote:
    > Hi,
    >
    > I'm facing a peculiar problem of finding a way to interpret header
    > information in a smart way.
    >
    > I have this header file that is shared by many users, which contains,
    > among things, a few #define statements that associate GUIDs wih a
    > friendly name. For e.g. consider the file zoo.h:
    >
    > ...
    > #define tiger GUID1
    > #define lion GUID2
    > #define striped_cat tiger
    > ...
    >
    > This file can be updated - i.e. #define statements are
    > added/removed/modified.
    >
    > Now, I want to accept the animal type as input from the user, switch
    > based on the GUID, and print animal specific information to the user.
    > Is it posible for me to have a user specify the animal type as name
    > (i.e. tiger, lion etc.) instead of GUID? It would make it very
    > convenient to the user.


    You can use a standard map to associate the two (I'll assume your GUIDs
    are ints):

    #include <map>
    #include <string>
    #include <cassert>
    #include "guid.h" // Your GUIDs in here

    namespace
    {
    std::map<std::string,int> zooMap;
    }

    void InitMap()
    {
    zooMap[ "Lion" ] = GUID1;
    zooMap[ "Tiger" ] = GUID2;
    // ...
    }

    // Use the map elsewhere in the file
    void Foo( const std::string& name )
    {
    // Make sure map is initialized
    assert( map.size() != 0 );

    // Lookup name; might want to use map<>::find() for error checking
    const int id = zooMap[ name ];
    // ...
    }

    Alternately, an OO approach might use a factory a la _Modern C++
    Design_'s Factory (library source at sourceforge.net/projects/loki-lib
    ):

    #include <iostream>
    #include <string>
    #include <memory> // for auto_ptr
    #include "loki/Singleton.h"
    #include "loki/Factory.h"

    using namespace std;
    using namepsace Loki;

    struct Animal
    {
    virtual ~Animal() {}
    virtual void Print( ostream& ) = 0;
    };

    struct Lion : Animal
    {
    void Print( ostream& ) { /* ... */ }
    };

    struct Tiger : Animal
    {
    void Print( ostream& ) { /* ... */ }
    };

    // Make the factory a singleton since there should be only one.
    typedef Singleton< Factory<Animal, string> > theAnimalFactory;

    // Register all our particular animals
    namespace
    {
    Animal CreateLion() { return new Lion; }
    Animal CreateTiger() { return new Tiger; }

    const bool lionRegistered = theAnimalFactory::Instance()
    .Register( "Lion", CreateLion );

    const bool tigerRegistered = theAnimalFactory::Instance()
    .Register( "Tiger", CreateTiger );
    }

    // User takes over management of the animal
    auto_ptr<Animal> PrintAnimal( const string id )
    {
    auto_ptr<Animal> animal( theAnimalFactory.CreateObject( id ) );
    animal->Print( cout );
    return animal;
    }

    Factory is in essence a snazzy front end for a map because it
    associates an ID of some type with a creation function.

    >
    > I have a few ideas, but they don't seem to be very elegant:
    >
    > 1. Have the user specify name-to-GUID mappings in a separate file.


    This idea makes it sound like the list can change at run-time or start
    time, independent of the program (e.g., the user can add new animals).
    If that's so, you cannot use a static list in a .h file to begin with.
    You'll want to use some sort of config file (e.g., .ini file on
    Windows). Then you build your map or register with factory as the
    program is starting up (or as the user makes changes). See the code
    above; the map/factory can be updated at any point during program
    operation.

    > 2. Parse zoo.h and do create a string-to-GUID internally. However this
    > is quite cumbersome as #define statements occur all over the place in
    > different formats.


    It sounds you are suggesting that your C++ program would parse the .h
    file to create a map between IDs and strings. This is a bad idea,
    especially if the list is changeable by the user. Prefer a file format
    that is simpler, as suggested above.

    >
    > Any pointers in this regard will be greatly appreciated!
    >
    > Thanks,
    > Palani


    Cheers! --M
     
    mlimber, Oct 31, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rob Meade

    Interpreting the error message?

    Rob Meade, Jan 27, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    392
    Rob Meade
    Jan 28, 2004
  2. =?Utf-8?B?QWxleCBNYWdoZW4=?=

    Pre-Interpreting a Request

    =?Utf-8?B?QWxleCBNYWdoZW4=?=, Nov 14, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    324
    John Saunders
    Nov 14, 2004
  3. theotyflos
    Replies:
    3
    Views:
    474
    Thomas Matthews
    Feb 19, 2004
  4. robin liu
    Replies:
    3
    Views:
    825
    Robin Liu
    Apr 21, 2006
  5. Brian Takita

    #define _ and #define __

    Brian Takita, Jan 23, 2006, in forum: Ruby
    Replies:
    0
    Views:
    468
    Brian Takita
    Jan 23, 2006
Loading...

Share This Page