Jump to content
  • Advertisement
Sign in to follow this  
Shamino

Lots of Macros, can someone explain what these do?

This topic is 4630 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Whole bunch of macro's ment for repeating code
///////////////////////////////////////////////////////////////////////////////
// 
// MacroRepeat
// 
// This header provides macros for repeating code.
// 
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004 Robert Geiman.
//
// Permission to copy, modify, and use this code for personal and commercial
// software is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without any expressed or implied warranty.
//
// Any comments or questions can be sent to: rgeiman@buckeye-express.com
//
///////////////////////////////////////////////////////////////////////////////

#ifndef MACRO_REPEAT_H
#define MACRO_REPEAT_H


///////////////////////////////////////////////////////////////////////////////
// The MACRO_EMPTY_SEPERATOR should be left empty, but Visual C++ 6.0 chokes on
// passing empty defines to macros, so to get around deficiency we define this
// macro as an empty comment section (/**/).  Note that this is NOT valid with
// a standard compliant compiler 
///////////////////////////////////////////////////////////////////////////////
#define MACRO_EMPTY_SEPERATOR /##**/
#define MACRO_COMMA_SEPERATOR ,
#define MACRO_SEMICOLAN_SEPERATOR ;
#define MACRO_BEGIN_PAREN_SEPERATOR (
#define MACRO_END_PAREN_SEPERATOR )


#define MACRO_EMPTY_MACRO(num)
#define MACRO_TEMPLATE_PARAMETER(num) typename A##num
#define MACRO_TEMPLATE_ARGUMENT(num) A##num
#define MACRO_FUNCTION_PARAMETER(num) A##num a##num
#define MACRO_FUNCTION_ARGUMENT(num) a##num


#define MACRO_REPEAT_0(begin_seperator, seperator, macro, end_seperator) 
#define MACRO_REPEAT_1(begin_seperator, seperator, macro, end_seperator) begin_seperator macro(0) end_seperator
#define MACRO_REPEAT_2(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_1(begin_seperator, seperator, macro, end_seperator) seperator macro(1) end_seperator
#define MACRO_REPEAT_3(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_2(begin_seperator, seperator, macro, end_seperator) seperator macro(2) end_seperator
#define MACRO_REPEAT_4(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_3(begin_seperator, seperator, macro, end_seperator) seperator macro(3) end_seperator
#define MACRO_REPEAT_5(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_4(begin_seperator, seperator, macro, end_seperator) seperator macro(4) end_seperator
#define MACRO_REPEAT_6(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_5(begin_seperator, seperator, macro, end_seperator) seperator macro(5) end_seperator
#define MACRO_REPEAT_7(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_6(begin_seperator, seperator, macro, end_seperator) seperator macro(6) end_seperator
#define MACRO_REPEAT_8(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_7(begin_seperator, seperator, macro, end_seperator) seperator macro(7) end_seperator
#define MACRO_REPEAT_9(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_8(begin_seperator, seperator, macro, end_seperator) seperator macro(8) end_seperator
#define MACRO_REPEAT_10(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_9(begin_seperator, seperator, macro, end_seperator) seperator macro(9) end_seperator
#define MACRO_REPEAT_11(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_10(begin_seperator, seperator, macro, end_seperator) seperator macro(10) end_seperator
#define MACRO_REPEAT_12(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_11(begin_seperator, seperator, macro, end_seperator) seperator macro(11) end_seperator
#define MACRO_REPEAT_13(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_12(begin_seperator, seperator, macro, end_seperator) seperator macro(12) end_seperator
#define MACRO_REPEAT_14(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_13(begin_seperator, seperator, macro, end_seperator) seperator macro(13) end_seperator
#define MACRO_REPEAT_15(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_14(begin_seperator, seperator, macro, end_seperator) seperator macro(14) end_seperator
#define MACRO_REPEAT_16(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_15(begin_seperator, seperator, macro, end_seperator) seperator macro(15) end_seperator
#define MACRO_REPEAT_17(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_16(begin_seperator, seperator, macro, end_seperator) seperator macro(16) end_seperator
#define MACRO_REPEAT_18(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_17(begin_seperator, seperator, macro, end_seperator) seperator macro(17) end_seperator
#define MACRO_REPEAT_19(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_18(begin_seperator, seperator, macro, end_seperator) seperator macro(18) end_seperator
#define MACRO_REPEAT_20(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_19(begin_seperator, seperator, macro, end_seperator) seperator macro(19) end_seperator
#define MACRO_REPEAT_21(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_20(begin_seperator, seperator, macro, end_seperator) seperator macro(20) end_seperator
#define MACRO_REPEAT_22(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_21(begin_seperator, seperator, macro, end_seperator) seperator macro(21) end_seperator
#define MACRO_REPEAT_23(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_22(begin_seperator, seperator, macro, end_seperator) seperator macro(22) end_seperator
#define MACRO_REPEAT_24(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_23(begin_seperator, seperator, macro, end_seperator) seperator macro(23) end_seperator
#define MACRO_REPEAT_25(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_24(begin_seperator, seperator, macro, end_seperator) seperator macro(24) end_seperator
#define MACRO_REPEAT_26(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_25(begin_seperator, seperator, macro, end_seperator) seperator macro(25) end_seperator
#define MACRO_REPEAT_27(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_26(begin_seperator, seperator, macro, end_seperator) seperator macro(26) end_seperator
#define MACRO_REPEAT_28(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_27(begin_seperator, seperator, macro, end_seperator) seperator macro(27) end_seperator
#define MACRO_REPEAT_29(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_28(begin_seperator, seperator, macro, end_seperator) seperator macro(28) end_seperator
#define MACRO_REPEAT_30(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_29(begin_seperator, seperator, macro, end_seperator) seperator macro(29) end_seperator
#define MACRO_REPEAT_31(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_30(begin_seperator, seperator, macro, end_seperator) seperator macro(30) end_seperator
#define MACRO_REPEAT_32(begin_seperator, seperator, macro, end_seperator) MACRO_REPEAT_31(begin_seperator, seperator, macro, end_seperator) seperator macro(31) end_seperator


#define MACRO_LIST(num, macro) MACRO_REPEAT_##num(MACRO_EMPTY_SEPERATOR, MACRO_COMMA_SEPERATOR, macro, MACRO_EMPTY_SEPERATOR)
#define MACRO_LIST_APPEND(num, macro) MACRO_REPEAT_##num(MACRO_COMMA_SEPERATOR, MACRO_COMMA_SEPERATOR, macro, MACRO_EMPTY_SEPERATOR)
#define MACRO_LIST_PREPEND(num, macro) MACRO_REPEAT_##num(MACRO_EMPTY_SEPERATOR, MACRO_COMMA_SEPERATOR, macro, MACRO_COMMA_SEPERATOR)
#define MACRO_BEGIN_PAREN(num, macro) MACRO_REPEAT_##num(MACRO_BEGIN_PAREN_SEPERATOR, MACRO_EMPTY_SEPERATOR, macro, MACRO_EMPTY_SEPERATOR)
#define MACRO_END_PAREN(num, macro) MACRO_REPEAT_##num(MACRO_END_PAREN_SEPERATOR, MACRO_EMPTY_SEPERATOR, macro, MACRO_EMPTY_SEPERATOR)
#define MACRO_REPEAT(num, macro) MACRO_REPEAT_##num(MACRO_EMPTY_SEPERATOR, MACRO_EMPTY_SEPERATOR, macro, MACRO_EMPTY_SEPERATOR)



#endif

And here is how they're implemented
#define OBJECT_FACTORY(num)                                                                                 
   template<typename BaseClassType MACRO_LIST_APPEND(num, MACRO_TEMPLATE_PARAMETER), typename UniqueIdType> 
   class ObjectFactory##num                                                                                 
   {                                                                                                        
   protected:                                                                                               
      class CreateObjectBase                                                                                
      {                                                                                                     
      public:                                                                                               
         virtual ~CreateObjectBase() {}                                                                     
         virtual BaseClassType *operator()(MACRO_LIST(num, MACRO_FUNCTION_PARAMETER)) = 0;                  
      };                                                                                                    
                                                                                                            
      template<typename ClassType>                                                                          
      class CreateObject : public CreateObjectBase                                                          
      {                                                                                                     
      public:                                                                                               
         BaseClassType *operator()(MACRO_LIST(num, MACRO_FUNCTION_PARAMETER))                               
         {                                                                                                  
			return new ClassType MACRO_BEGIN_PAREN(num, MACRO_EMPTY_MACRO) MACRO_LIST(num, MACRO_FUNCTION_ARGUMENT) MACRO_END_PAREN(num, MACRO_EMPTY_MACRO);
         }                                                                                                  
      };                                                                                                    
                                                                                                            
   public:                                                                                                  
      typedef typename std::map<UniqueIdType, CreateObjectBase*>::const_iterator ConstIterator;             
      typedef typename std::map<UniqueIdType, CreateObjectBase*>::iterator Iterator;                        
                                                                                                            
      ~ObjectFactory##num()                                                                                 
      {                                                                                                     
         Iterator iter = m_object_creator.begin();                                                          
                                                                                                            
         while (iter != m_object_creator.end())                                                             
         {                                                                                                  
            delete (*iter).second;                                                                          
            ++iter;                                                                                         
         }                                                                                                  
      }                                                                                                     
                                                                                                            
      template<typename ClassType>                                                                          
      bool Register(UniqueIdType unique_id, Type2Type<ClassType>)                                           
      {                                                                                                     
         if (m_object_creator.find(unique_id) != m_object_creator.end())                                    
            return false;                                                                                   
                                                                                                            
         m_object_creator[unique_id] = new CreateObject<ClassType>;                                         
                                                                                                            
         return true;                                                                                       
      }                                                                                                     
                                                                                                            
      bool Unregister(UniqueIdType unique_id)                                                               
      {                                                                                                     
         Iterator iter = m_object_creator.find(unique_id);                                                  
                                                                                                            
         if (iter != m_object_creator.end())                                                                
         {                                                                                                  
            delete (*iter).second;                                                                          
            m_object_creator.erase(iter);                                                                   
                                                                                                            
            return true;                                                                                    
         }                                                                                                  
                                                                                                            
         return false;                                                                                      
      }                                                                                                     
                                                                                                            
      BaseClassType *Create(UniqueIdType unique_id MACRO_LIST_APPEND(num, MACRO_FUNCTION_PARAMETER))        
      {                                                                                                     
         Iterator iter = m_object_creator.find(unique_id);                                                  
                                                                                                            
         if (iter == m_object_creator.end())                                                                
            return NULL;                                                                                    
                                                                                                            
         return ((*iter).second)->operator()(MACRO_LIST(num, MACRO_FUNCTION_ARGUMENT));                     
      }                                                                                                     
                                                                                                            
      ConstIterator GetBegin() const                                                                        
      {                                                                                                     
         return m_object_creator.begin();                                                                   
      }                                                                                                     
                                                                                                            
      Iterator GetBegin()                                                                                   
      {                                                                                                     
         return m_object_creator.begin();                                                                   
      }                                                                                                     
                                                                                                            
      ConstIterator GetEnd() const                                                                          
      {                                                                                                     
         return m_object_creator.end();                                                                     
      }                                                                                                     
                                                                                                            
      Iterator GetEnd()                                                                                     
      {                                                                                                     
         return m_object_creator.end();                                                                     
      }                                                                                                     
                                                                                                            
   protected:                                                                                               
      std::map<UniqueIdType, CreateObjectBase*> m_object_creator;                                           
   };                                                                                                       

MACRO_REPEAT(16, OBJECT_FACTORY)
#undef OBJECT_FACTORY

#endif

Can someone like, cut lines and snippets out of the implementation and write out longhand what you would put instead of the macro? I'm very unfamiliar with macro's and exactly how to declare them and how to use them n stuff, thanks.

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
I just want to say thats some of the ugliest macroing Ive seen - good luck on deciphering it. Damn you Robert Geiman! You could always email this guy and ask him, seeing how all the macros seem to be undocumented in code. ALl I can tell you is that they apparently repeat something.

Share this post


Link to post
Share on other sites
The macros are in fact an unrolled recursive definition. It says that, to repeat "FOO" X times,
- if X=1 then you write "FOO"
- otherwise, you repeat "FOO" (X-1) times, then you write "FOO"

With some additional information (like repeating slightly different things each time by writing FOO(X) instead of FOO, which assumes FOO is a macro), and separators.

In the end, it uses ## to transform a numeric argument into a hardcoded macro name corresponding with a given amount of repetitions. This results in:

MACRO_REPEAT(num,macro)

Being evaluated to:

macro(num-1) macro(num-2) ... macro(0)

Which in turn is evaluated into whatever macro becomes. This is truly ugly, by the way.

Share this post


Link to post
Share on other sites
Lol, if I could get him to rewrite it without the macro's do you think I could understand what the fudge that template does?

Share this post


Link to post
Share on other sites
Quote:
Original post by Shamino
Can someone like, cut lines and snippets out of the implementation and write out longhand what you would put instead of the macro? I'm very unfamiliar with macro's and exactly how to declare them and how to use them n stuff, thanks.
Most compilers can do this for you. Check your compiler's options, there should be one for invoking the preprocessor separately.
The output will probably be huge and generally unmaintainable though, so you probably want to keep the macros around and just use the preprocessor output for debugging purposes.

Share this post


Link to post
Share on other sites
He's pretty much trying to repeat a macro (that takes a number as an argument) some number of times, and expanding them in increasing order (not decreasing)

For example:

#define MY_NUM(n) n
MACRO_REPEAT(MY_NUM, 5)

Will result in something like

"MY_NUM(0) MY_NUM(1) ... MY_NUM(4)"

which then translates into

"0 1 ... 4"

No, he goes the extra step and adds seperators and stuff into that, so that he can generate parameter lists. Notice the "begin_seperator, seperator, macro, end_seperator" stuff? That's just dictates what needs to go between the generated macros. For example, if I did the following

MACRO_LIST(MY_NUM, 5)

it'll translate into "0, 1, 2, 3, 4", since the macro uses no begin and end seperators, but just shoves a comma between the 'terms' I guess you could say.

The other macros use variations of the repeat macro to constructed lists and nested lists, though they look like they need to be used in conjunction with one another.

Blegh. That's real nasty. I have no real problem with macros when used "correctly", but that's just plain old crazy.

Edit:

Oh, and as far as the class is concerned, he's just trying to make a bunch of factories for some object type (which gets registered at some point by the factory itself). I guess he ended up having to write a lot of duplicate factories that look "almost" the same for similar objects (maybe?), and got tired of it. His final goal you can see at the bottom when he does this:

"MACRO_REPEAT(16, OBJECT_FACTORY)"

He wants to make 16 factories, and wants to be able to quickly change that number whenever he feels frisky.

*shrugs*

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
"MACRO_REPEAT(16, OBJECT_FACTORY)"

He wants to make 16 factories, and wants to be able to quickly change that number whenever he feels frisky.

*shrugs*


Actually that cleared that up alot..

Share this post


Link to post
Share on other sites
Quote:
Original post by Shamino
Question though, why does he need 16 factories?
To forward a variable number of parameters to the templated class's constructor.
Yes, it's an ugly hack. But it's the best solution the language provides to the forwarding problem.

Take a look at boost::preprocessor for further details, it's basically just an advanced version of the code above but at least it's decently documented.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!