Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r69370 - in sandbox/local: . boost/local/aux_ boost/local/aux_/function_macros libs/local/example
From: lorcaminiti_at_[hidden]
Date: 2011-02-27 20:18:04


Author: lcaminiti
Date: 2011-02-27 20:17:55 EST (Sun, 27 Feb 2011)
New Revision: 69370
URL: http://svn.boost.org/trac/boost/changeset/69370

Log:
Removed all done TODOs.
Made local functor `const` so programmers cannot re-assign it but they can only call its `operator()`.
Removed:
   sandbox/local/libs/local/example/factorial_nomacros.cpp
Text files modified:
   sandbox/local/TODO.txt | 79 ++-------------------------------------
   sandbox/local/boost/local/aux_/function.hpp | 2
   sandbox/local/boost/local/aux_/function_macros/name.hpp | 20 ++++++---
   3 files changed, 19 insertions(+), 82 deletions(-)

Modified: sandbox/local/TODO.txt
==============================================================================
--- sandbox/local/TODO.txt (original)
+++ sandbox/local/TODO.txt 2011-02-27 20:17:55 EST (Sun, 27 Feb 2011)
@@ -1,78 +1,18 @@
 
 
-* Rework a no-macro version of the factorial example.
- >> Ask boost about inline -- is it useful?
- >> Tell boost that split-macros can support recursion at the cost of
- allowing `this` within the function body (so no error if used instead
- of `this_`).
-
-
-* Rename function_ref to function (because it now has a default constructor so it's not a reference anymore).
-
-* Document that PARAMS cannot appear on same line because they use __LINE__ to generate unique IDs (there's no way around this because this macro doesn't know the function name).
-
-
-* Double check all local function syntax elements (from Grammar) -- auto, register, etc.
-
-* Provide bound parameter types within the body (via private typdefs in the functor class) as `BOUND_PARAM_NAME>_type` -- these can be used for concept checking, etc. Actually, provide access to the bind types via a macro BOOST_LOCAL_TYPEOF() so to hide the type name and to strip eventual const& (Vicente's idea).
-
-* In docs that local functions cannot appear on same line (because __LINE__ is used to generate unique symbols).
-
-* Ask Paul why nil-seq are not part of pp-lib.
-
-* Try to use PP_LIST instead of nil-seq.
-
-* Ask (Paul) for interest in addition PP_KEYWORD to pp-lib.
-
-* Rename is_xxx.hpp to xxx.hpp for all PP_KEYWORD and add REMOVE and ADD macros:
-> #include <boost/preprocessor.hpp>
-> #include <boost/preprocessor/detail/is_unary.hpp>
->
-> #define IS_AUTO_auto (1) /* must expand to unary */
-> #define IS_AUTO(tokens) BOOST_PP_IS_UNARY(BOOST_PP_CAT(IS_AUTO_, tokens))
->
-> #define REMOVE_AUTO_STRIP_auto /* must expand to nothing */
-> #define REMOVE_AUTO_(tokens) BOOST_PP_CAT(REMOVE_AUTO_STRIP_, tokens)
-> #define REMOVE_AUTO(tokens) \
-> BOOST_PP_IIF(IS_AUTO(tokens), \
-> REMOVE_AUTO_ \
-> , \
-> tokens BOOST_PP_TUPLE_EAT(1) \
-> )(tokens)
->
-> #define ADD_AUTO(tokens) \
-> BOOST_PP_EXPR_IIF(BOOST_PP_NOT(IS_AUTO(tokens)), auto) tokens
->
-> IS_AUTO(auto int x) // 1
-> IS_AUTO(int x) // 0
->
-> REMOVE_AUTO(auto int x) // int x
-> REMOVE_AUTO(int x) // int x
->
-> ADD_AUTO(auto int x) // auto int x
-> ADD_AUTO(int x) // auto int x
-The names should actually be AUTO_IN_FRONT, AUTO_ADD_FRONT, AUTO_REMOVE_FRONT, AUTO_IN_BACK, AUTO_ADD_BACK, AUTO_REMOVE_BACK (the general stuff could go into keyword/utility/in.hpp, add.hpp, remove.hpp).
+* Docs: The simplified syntax removes the function name repetition. However, to supoprt recursion the body cannot be static (to access the member functor variable with the local function name defined by the NAME macro). Therefore the limitation that no compiler error if `this` is used instead of `this_` as a pointer within the body (if not used as pointer, compiler will most likely error because `this` is the functor which has a rather different structure than the user's object `this_`).
 
-* Add to docs that this can never be bound by ref (as in C++).
+* Docs: `inline` does not apply to local function which are already inlined (because they are defined where they are declared).
 
-* Add to docs that MSVC is not C99 because it does not support empty params (so `()` can't be used for empty params and `void` -- or `(void)` -- should be used. However, MSVC supports variadics you can use `..., ...` to separate params instead of parenthesis `(...)...`.
+* Docs: PARAMS cannot appear on same line because they use __LINE__ to generate unique IDs (there's no way around this because this macro doesn't know the function name).
 
-* Add to docs that if `, default ...` syntax seems strange for C99, programmers can always #define and use the following macro (or somenthing similar).
-> #define WITH_DEFAULT(x) , default x
+* Docs: `this` can never be bound by ref (as usual in C++).
 
+* Docs: If `, default ...` syntax seems strange for C99, programmers can always use `#define WITH_DEFAULT(x) , default x` or similar macro instead.
 
 
 * Try seriously to make nested locals to work...
 
-* Add to docs that object `this` can never be bound by reference `&this` (as usual in C++ it is not legal to get a reference to the `this` pointer).
-
-* Make sure that non of the binding (outside and inside the functor) code is generated when no param is bound.
-
-* Rename `function_base` to `abstract_function` (because it's abstract) and `function_ref` to `function` (as for Boost.Function because it's no longer a ref since it can be init empty and uses ptr internally).
-
-
-* Send comments on variadic_macro_data:
-
 * Optimize macro expansion code for C++0x, C++03, etc. From John Bytheway:
> Yes, in C++0x local structs can be passed as template parameters.
> Obviously, in C++0x there are lambdas too, so you might think your
@@ -83,13 +23,4 @@
> C++03, with the virtual function business in only those compilers/modes
> where it is necessary.
 
-* See if the two local functors `functor_factorial` and `factorial` can be declared `const`.
-
-* Make sure that when no bound params, none of the binding overhead code is generated by the macro expansion.
-
-* Add comparison with Look at Alex-Steven's syntax to docs:
- http://thread.gmane.org/gmane.comp.lib.boost.devel/168612/focus=168694
- >> This syntax uses same typeof trick to deduce result type.
- >> This syntax uses a strange macro-into-macro for bind. I don't.
-
 

Modified: sandbox/local/boost/local/aux_/function.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/function.hpp (original)
+++ sandbox/local/boost/local/aux_/function.hpp 2011-02-27 20:17:55 EST (Sun, 27 Feb 2011)
@@ -41,7 +41,7 @@
                 
 #define BOOST_LOCAL_AUX_concrete_operator_call(z, defaults_n, arity) \
     inline R operator()(BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
- BOOST_LOCAL_AUX_arg, ~)) { \
+ BOOST_LOCAL_AUX_arg, ~)) const { \
         assert(ptr_); \
         return (*ptr_)(BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
                 BOOST_LOCAL_AUX_arg_name, ~)); \

Modified: sandbox/local/boost/local/aux_/function_macros/name.hpp
==============================================================================
--- sandbox/local/boost/local/aux_/function_macros/name.hpp (original)
+++ sandbox/local/boost/local/aux_/function_macros/name.hpp 2011-02-27 20:17:55 EST (Sun, 27 Feb 2011)
@@ -12,9 +12,11 @@
     /* `PARAMS() { ... }` expandsion here -- still within functor class */ \
     /* class functor ## __LINE__ { ... */ \
     public: \
- /* member var with function name for recursive calls (must be */ \
- /* public because is it also used by this macro but outside */ \
- /* the functor class to deduce the functor type */ \
+ /* member var with function name for recursive calls; must be */ \
+ /* `public` because is it also used by this macro but outside */ \
+ /* the functor class to deduce the functor type; it cannot be */ \
+ /* `const` because it is init after construction (because */ \
+ /* constructor doesn't know local function name) */ \
         BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_TYPE local_function_name; \
     private: \
         /* called by the constructor to init member variable for recursion */ \
@@ -22,14 +24,18 @@
             local_function_name = *this; \
         } \
     /* declares object for local class functor (but this functor cannot be */ \
- /* passed as template parameter) */ \
+ /* passed as template parameter); cannot be `const` `abstract_function` */ \
+ /* is not passed as const to `function` to make the function call */ \
     } BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME(local_function_name)( \
             BOOST_LOCAL_AUX_SYMBOL_ARGS_VARIABLE_NAME.value); \
     /* declares actual functor for the local function (of type */ \
- /* local::function which can be passed as template parameter */ \
+ /* local::function which can be passed as template parameter); this */ \
+ /* is correctly `const` because it is directly visible to programmers */ \
+ /* which cannot re-assign the local functor (they can only call it) */ \
     BOOST_TYPEOF(BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME( \
- local_function_name).local_function_name) local_function_name( \
- BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME(local_function_name));
+ local_function_name).local_function_name) const \
+ local_function_name(BOOST_LOCAL_AUX_SYMBOL_FUNCTOR_OBJECT_NAME( \
+ local_function_name));
 
 // PUBLIC //
 

Deleted: sandbox/local/libs/local/example/factorial_nomacros.cpp
==============================================================================
--- sandbox/local/libs/local/example/factorial_nomacros.cpp 2011-02-27 20:17:55 EST (Sun, 27 Feb 2011)
+++ (empty file)
@@ -1,210 +0,0 @@
-
-// Copyright (C) 2009-2011 Lorenzo Caminiti
-// Use, modification, and distribution is subject to the
-// Boost Software License, Version 1.0
-// (see accompanying file LICENSE_1_0.txt or a copy at
-// http://www.boost.org/LICENSE_1_0.txt).
-
-// Use recursion, default parameters, and bind by non-const reference.
-
-//[ factorial_cpp
-#include <boost/local/function.hpp>
-#include <boost/type_tratis.hpp>
-#include <iostream>
-#include <sstream>
-#include <algorithm>
-#include <vector>
-
-int main () {
- std::ostringstream output;
-
- int // Result type (outside the `PARAMS` macro).
-
- // On all C++ preprocessors (including C99 preprocessors) the macro:
- //
- // int BOOST_LOCAL_FUNCTION_PARAMS(
- // (int n) (bool recursion)(default false) (bind& output) )
- //
- // Or, on C99 preprocessors only the macro:
- //
- // int BOOST_LOCAL_FUNCTION_PARAMS(
- // int n, bool recursion, default false, bind& output)
- //
- // Expands to code equivalent to the following.
- //
- // NOTE:
- // * Use line number `__LINE__` (e.g., `..._29`) to generate unique symbols.
- // * Parameter name not available separately from its type.
- // * Function name NOT available.
-
-// In actual expansion, the following tokens are made available as macro
-// parameters (and not as macro symbols) by the `PARAMS` macro:
-#define PARAMS_arg_0 auto int n
-#define PARAMS_arg_with_dflt_0 PARAMS_arg_0 // No default.
-#define PARAMS_arg_1 register bool recursion
-#define PARAMS_arg_with_dflt_1 PARAMS_arg_1 = false
-#define PARAMS_bind_0 &output
-#define PARAMS_is_const_bind_0 0 // Not a constant bind.
-
- // Function traits.
- // NOTE: Following result type specified just before the `PARAMS` macro.
- // Default parameter values need to be separated from their parameter types
- // and names because they are not part of the function type so they cannot
- // be used by the following expressions and their number cannot be count
- // at compile-time using template metaprogramming.
- ERROR_missing_result_type_at_line_29(PARAMS_arg_0, PARAMS_arg_1);
- /** @todo This typeof requires registration of result, arg, etc type? */
- typedef BOOST_TYPEOF(ERROR_missing_result_type_at_line_29) function_type_29;
- typedef boost::function_traits<function_type_29>::result_type
- result_type_29;
- typedef boost::function_traits<function_type_29>::arg1_type arg_type_0_29;
- typedef boost::function_traits<function_type_29>::arg2_type arg_type_1_29;
-
- // Handle bound parameters as done by Boost.ScopeEixt, deducing their types
- // (using Boost.Typeof) and storing them by reference or by value.
- typedef void (*bind_deduce_type_0_29)(int PARAMS_bind_0);
- typedef BOOST_TYPEOF(
- boost::scope_exit::aux::wrap(boost::scope_exit::aux::deref(
- PARAMS_bind_0, static_cast<bind_deduce_type_0_29>(0))))
- bind_wrapped_type_0_29;
- typedef bind_wrapped_type_0_29::type capture_bind_type_0_29;
- // Hold bound parameter types and values.
- struct binds_29 {
- typedef capture_bind_type_0_29 bind_type_0_29;
- boost::scope_exit::aux::member<bind_type_0_29, bind_deduce_type_0_29>
- bind_value_0_29;
- } params_29 = { // Must use this initializer because reference members.
-#if defined(__GNUC__)
- { // NOTE: Curly brakets are required by GCC but not supported by MSVC.
-#endif
- boost::scope_exit::aux::deref(PARAMS_bind_0,
- static_cast<bind_deduce_type_0_29>(0))
-#if defined(__GNUC__)
- } // NOTE: Curly brakets are required by GCC but not supported by MSVC.
-#endif
- };
- // NOTE: The `args` variable is declared globally and not prefixed with
- // __LINE__ so it can be used by both the `PARAMS` and `NAME`. The special
- // template declaration type prevents this variable to be declared multiple
- // times within the same scope.
- boost::scope_exit::aux::declared<boost::scope_exit::aux::resolve<
- sizeof(boost_local_auxXargs)>::cmp1<0>::cmp2> boost_local_auxXargs;
- boost_local_auxXargs.value = &params_29;
-
- // Functor for local function.
- class functor_29:
- // Base used to assign local functions to `function_ref` which can
- // then be passed as template parameter.
- public ::boost::local::aux::function_base<function_type_29, 1> {
- public:
- explicit functor_29(void* binds):
- binds_(static_cast<binds_29*>(binds)) {
- init_recursion();
- }
- result_type_29 operator()(arg_type_0_29 arg_0, arg_type_1_29 arg_1) {
- assert(binds_);
- return body(
- binds_->bind_value_0_29.value
- // Using general names `arg_i` because parameter types and
- // names are not separated by the preprocessor so the actual
- // argument name (e.g., `n`) is not available here.
- , arg_0, arg_1
- );
- }
- // Overloads to support default parameters.
- result_type_29 operator()(arg_type_0_29 arg_0) {
- assert(binds_);
- return body(
- binds_->bind_value_0_29.value
- , arg_0
- );
- }
- private:
- // Non local functor type that can be passed as template parameter.
- typedef ::boost::local::function_ref<function_type_29, 1> functor_type;
- // Hold bound parameter values.
- binds_29* binds_;
- // LIMITATION: Body cannot be static because it has to access the
- // member named after the function name for recursive calls (the
- // function name is not know to this macro). However, ideally the body
- // will be static so to prevent using `this` instead of `this_` by
- // mistake (in most cases this will still cause a compile-time error
- // because when functor has a different structure than the bound object
- // `this_` -- but that is not the case if `this` is mistakenly used
- // instead of `this` to do pointer operations). Programmers need to
- // inspect the local function body code by eye and make sure that
- // `this` is not used by the body code.
- result_type_29 body(
-#if PARAMS_is_const_bind_0
- ::boost::add_const< // Handle constant binding.
-#endif
- binds_29::bind_type_0_29
-#if PARAMS_is_const_bind_0
- >::type
-#endif
- PARAMS_bind_0
- , PARAMS_arg_with_dflt_0
- , PARAMS_arg_with_dflt_1)
-
- // Local function body (specified by programmers outside the macros).
-
- {
- int result = 0;
- if (n < 2 ) result = 1;
- else result = n * factorial(n - 1, true); // Recursive call.
-
- if (!recursion) output << result << " ";
- return result;
- }
-
-// All `..._29` and `PARAMS_...` symbols are only available for within `PARAMS`
-// macro expansion for the code above.
-#undef PARAMS_arg0
-#undef PARAMS_dflt0
-#undef PARAMS_arg1
-#undef PARAMS_dflt1
-#undef PARAMS_bind0
-
- // The macro:
- //
- // BOOST_LOCAL_FUNCTION_NAME(factorial)
- //
- // Expands to code equivalent to the following. Note:
- //
- // * Use function name `factorial` and/or line number `__LINE__`
- // (e.g., `..._31`) to generate unique symbols.
- // * Function name `factorial` available.
- // * None of the `..._29` symbols are available (different `__LINE__`).
-
- // Cannot be programmed in the constructor because it sets the
- // `factorial` member with name only known in this macro expansion.
- void init_recursion() { factorial = *this; }
-
- public:
- // Member with function name for recursive calls. This cannot be
- // defined sooner because the function name is only available here.
- // Also, it is public so it can be used to deduce the functor type
- // outside the expansion of the PARAMS macro (where the PARAMS symbols
- // are no longer available because of the different __LINE__ number).
- functor_type factorial;
- } functor_factorial(boost_local_auxXargs.value);
- // The struct type cannot be passed as template parameter but the function
- // type `function_ref<...>` deduced here can.
- BOOST_TYPEOF(functor_factorial.factorial) factorial(functor_factorial);
-
- // Rest of the program.
-
- // Factorial of a single number.
- factorial(3); // Call local function.
-
- std::vector<int> v;
- v.resize(3);
- v[0] = 1; v[1] = 4; v[2] = 7;
- // Factorials of all vector's elements.
- std::for_each(v.begin(), v.end(), factorial); // Pass as template parameter.
-
- std::cout << output.str() << std::endl;
- return 0;
-}
-//]
-


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk