[/ 
  (C) Copyright Edward Diener 2011-2015
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]

[section:vmd_identity Generating emptiness and identity]

[heading Using BOOST_PP_EMPTY and BOOST_PP_IDENTITY]

Boost PP Has a macro called BOOST_PP_EMPTY() which expands to nothing.

Ordinarily this would not seem that useful, but the macro can be used
in situations where one wants to return a specific value even though
a further macro call syntax is required taking no parameters.
This sort of usefulness occurs in Boost PP when there are two paths to take depending
on the outcome of a BOOST_PP_IF or BOOST_PP_IIF logic. Here is an artificial example:

 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/preprocessor/facilities/empty.hpp>

 #define MACRO_CHOICE(parameter) \
     BOOST_PP_IIF(parameter) \
         ( \
         MACRO_CALL_IF_PARAMETER_1, \
         SOME_FIXED_VALUE BOOST_PP_EMPTY \
         ) \
     ()
     
 #define MACRO_CALL_IF_PARAMETER_1() some_processing
  
In the general logic above is: if parameter is 1 another
macro is invoked, whereas if the parameter is 0 some
fixed value is returned. The reason that this is useful
is that one may not want to code the MACRO_CHOICE macro
in this way:

 #include <boost/preprocessor/control/iif.hpp>

 #define MACRO_CHOICE(parameter) \
     BOOST_PP_IIF(parameter) \
         ( \
         MACRO_CALL_IF_PARAMETER_1(), \
         SOME_FIXED_VALUE \
         )
     
 #define MACRO_CALL_IF_PARAMETER_1() some_processing
  
because it is inefficient. The invocation of MACRO_CALL_IF_PARAMETER_1 will still
be generated even when 'parameter' is 0.

This idiom of returning a fixed value through the use of BOOST_PP_EMPTY
is so useful that Boost PP has an accompanying macro to BOOST_PP_EMPTY to
work with it. This accompanying macro is BOOST_PP_IDENTITY(value)().
Essentially BOOST_PP_IDENTITY returns its value when it is invoked.
Again, like BOOST_PP_EMPTY, the final invocation must be done with no value.

Our example from above, which originally used BOOST_PP_EMPTY to return
a fixed value, is now:
  
 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/preprocessor/facilities/identity.hpp>

 #define MACRO_CHOICE(parameter) \
     BOOST_PP_IIF(parameter) \
         ( \
         MACRO_CALL_IF_PARAMETER_1, \
         BOOST_PP_IDENTITY(SOME_FIXED_VALUE) \
         ) \
     ()
     
 #define MACRO_CALL_IF_PARAMETER_1() some_processing
 
The macro BOOST_PP_IDENTITY is actually just:

 #define BOOST_PP_IDENTITY(value) value BOOST_PP_EMPTY
 
so you can see how it is essentially a shorthand for the common
case originally shown at the top of returning a value through the
use of BOOST_PP_EMPTY.
  
[heading Using BOOST_VMD_EMPTY and BOOST_VMD_IDENTITY]

The one problem when using BOOST_PP_EMPTY and BOOST_PP_IDENTITY
is that the final invocation must be with no parameters. This is 
very limiting. If the final invocation must be with one or more parameters 
you cannot use BOOST_PP_EMPTY or BOOST_PP_IDENTITY. In other words, 
making a change to either of our two examples:

 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/preprocessor/facilities/empty.hpp>

 #define MACRO_CHOICE(parameter1,parameter2) \
     BOOST_PP_IIF(parameter1) \
         ( \
         MACRO_CALL_IF_PARAMETER_1, \
         SOME_FIXED_VALUE BOOST_PP_EMPTY \
         ) \
     (parameter2)
     
 #define MACRO_CALL_IF_PARAMETER_1(parameter2) some_processing_using_a_parameter
 
or

 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/preprocessor/facilities/identity.hpp>

 #define MACRO_CHOICE(parameter1,parameter2) \
     BOOST_PP_IIF(parameter1) \
         ( \
         MACRO_CALL_IF_PARAMETER_1, \
         BOOST_PP_IDENTITY(SOME_FIXED_VALUE) \
         ) \
     (parameter2)
     
 #define MACRO_CALL_IF_PARAMETER_1(parameter2) some_processing_using_a_parameter
 
will produce a preprocessing error since the final invocation to either
BOOST_PP_EMPTY or BOOST_PP_IDENTITY can not be done with 1 or more parameters.

It would be much more useful if the final invocation could be done with
any number of parameters. This is where using variadic macros solves the problem. 
The BOOST_VMD_EMPTY and BOOST_VMD_IDENTITY macros have the exact same 
functionality as their Boost PP counterparts but the final invocation can 
be made with any number of parameters, and those parameters are just ignored
when BOOST_VMD_EMPTY or BOOST_VMD_IDENTITY is the choice.

Now for our two examples we can have:

 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/vmd/empty.hpp>

 #define MACRO_CHOICE(parameter1,parameter2) \
     BOOST_PP_IIF(parameter1) \
         ( \
         MACRO_CALL_IF_PARAMETER_1, \
         SOME_FIXED_VALUE BOOST_VMD_EMPTY \
         ) \
     (parameter2)
     
 #define MACRO_CALL_IF_PARAMETER_1(parameter2) some_processing_using_parameters
 
or

 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/vmd/identity.hpp>

 #define MACRO_CHOICE(parameter1,parameter2) \
     BOOST_PP_IIF(parameter1) \
         ( \
         MACRO_CALL_IF_PARAMETER_1, \
         BOOST_VMD_IDENTITY(SOME_FIXED_VALUE) \
         ) \
     (parameter2)
     
 #define MACRO_CALL_IF_PARAMETER_1(parameter2) some_processing_using_parameters
 
and our macros will compile without preprocessing errors and work as expected.
Both BOOST_VMD_EMPTY and BOOST_VMD_IDENTITY will take any number of parameters
in their invocation, which makes them useful for a final invocation no matter
what is being passed.

[heading Usage for BOOST_VMD_EMPTY and BOOST_VMD_IDENTITY]

To use the BOOST_VMD_EMPTY macro either include the general header:

 #include <boost/vmd/vmd.hpp>
 
or include the specific header:

 #include <boost/vmd/empty.hpp>

To use the BOOST_VMD_IDENTITY macro either include the general header:

 #include <boost/vmd/vmd.hpp>
 
or include the specific header:

 #include <boost/vmd/identity.hpp>

[heading Using BOOST_VMD_EMPTY and BOOST_VMD_IDENTITY with VC++]

Unfortunately the Visual C++ default preprocessor has a problem when a macro
expands to something followed by a variadic macro which expands to nothing.
This is the case when using BOOST_VMD_EMPTY following some non-empty expansion, 
or the equivalent use of BOOST_VMD_IDENTITY. As strange as it sounds this VC++ default
preprocessor problem is normally solved by concatenating the result using BOOST_PP_CAT
with an empty value. But then again the many non-standard behaviors of VC++
with its default preprocessor are difficult to understand or even track. 

In order to make this technique transparent when used with a C++ standard
conforming preprocessor or the VC++ non-standard default preprocessor you can use the 
BOOST_VMD_IDENTITY_RESULT macro passing to it a single parameter which is a result 
returned from a macro which uses BOOST_VMD_IDENTITY ( or its equivalent 
'value BOOST_VMD_EMPTY' usage ).

Given our MACRO_CHOICE example above, if you have another macro invoking MACRO_CHOICE
simply enclose that invocation within BOOST_VMD_IDENTITY_RESULT. As in the very simple:

 #include <boost/vmd/identity.hpp>
 
 #define CALLING_MACRO_CHOICE(parameter1,parameter2) \
     BOOST_VMD_IDENTITY_RESULT(MACRO_CHOICE(parameter1,parameter2))
     
Alternatively you can change MACRO_CHOICE so that its implementation
and usage is:
     
 #include <boost/preprocessor/control/iif.hpp>
 #include <boost/vmd/identity.hpp>

 #define MACRO_CHOICE(parameter1,parameter2) \
     BOOST_VMD_IDENTITY_RESULT \
         ( \
         BOOST_PP_IIF(parameter1) \
             ( \
             MACRO_CALL_IF_PARAMETER_1, \
             BOOST_VMD_IDENTITY(SOME_FIXED_VALUE) \
             ) \
         (parameter2) \
         )
         
 #define CALLING_MACRO_CHOICE(parameter1,parameter2) \
     MACRO_CHOICE(parameter1,parameter2)
     
Using BOOST_VMD_EMPTY and BOOST_VMD_IDENTITY in this way will ensure they can be used
without preprocessing problems with either VC++ with its default preprocessor or any C++ standard conforming preprocessor.

[heading Usage for BOOST_VMD_IDENTITY_RESULT]

The macro BOOST_VMD_IDENTITY_RESULT is in the same header file as BOOST_VMD_IDENTITY,
so to use the BOOST_VMD_IDENTITY_RESULT macro either include the general header:

 #include <boost/vmd/vmd.hpp>
 
or include the specific header:

 #include <boost/vmd/identity.hpp>

[endsect]
