Template instantiation, function arguments and Boost.Preprocessor

hi,
i have a template function, the arguments of which i wish to have depend on a non-type int template argument:
template<int n>
double f<n>( double arg0, double arg1, ..., double argn ) // ... is not the variadic notation for var number of args
{
// for(int i=0; i

AMDG Hicham Mouline wrote:
hi,
i have a template function, the arguments of which i wish to have depend on a non-type int template argument:
template<int n> double f<n>( double arg0, double arg1, ..., double argn ) // ... is not the variadic notation for var number of args { // for(int i=0; i
int main() { return x = f<3>( 1.0, 2.0, 3.0 ); }
BOOST_PP_REPEAT can't seem to do the job as the template argument n needs to be known at the preprocessing stage, which happens before the template instantiation stage ( this is part of compilation)
I don't understand why you want n to be passed explicitly. Can't it be deduced from the number of arguments (warning untested): #define SUM_IMPL(z, n, data) + arg ## n #define F_DEF(z, n, data) double f(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { return(0.0 BOOST_PP_REPEAT_ ## z(n, SUM_IMPL, ~)); } BOOST_PP_REPEAT(MAX_ARITY, F_DEF, ~) In Christ, Steven Watanabe

hi,
i have a template function, the arguments of which i wish to have depend on a non-type int template argument:
template<int n> double f<n>( double arg0, double arg1, ..., double argn ) // ... is not
After some though, here is more precisely what I'd like to have... I apologize that it is quite different from the initial problem: template<int n> class Tree { static double sum(); // }; If the user instantiates tree<2>, he should get: template<> class Tree<2> { static double sum(double d1, double d2); }; template<> class Tree<3> { static double sum(double d1, double d2, double d3); }; etc etc... so that in user code, for e.g.: double d= Tree<4>::sum(d1, d2, d3, d4); should compile. Is it possible for me to just define the template Tree for the n-case without the 2- and 3- specializations? Rds, -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Steven Watanabe Sent: 28 January 2008 16:42 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Template instantiation function arguments and Boost.Preprocessor AMDG Hicham Mouline wrote: the variadic notation for var number of args
{ // for(int i=0; i
int main() { return x = f<3>( 1.0, 2.0, 3.0 ); }
BOOST_PP_REPEAT can't seem to do the job as the template argument n needs to be known at the preprocessing stage, which happens before the template instantiation stage ( this is part of compilation)
I don't understand why you want n to be passed explicitly. Can't it be deduced from the number of arguments (warning untested): #define SUM_IMPL(z, n, data) + arg ## n #define F_DEF(z, n, data) double f(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { return(0.0 BOOST_PP_REPEAT_ ## z(n, SUM_IMPL, ~)); } BOOST_PP_REPEAT(MAX_ARITY, F_DEF, ~) In Christ, Steven Watanabe _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users -- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.516 / Virus Database: 269.19.14/1247 - Release Date: 1/28/2008 10:59 AM

Hi,
besides the more complex possibility to use boost::tuple and generate
recursive Tree<X> List : derived from Tree<X-1> ...: derived from Tree<0>
specialization, why not using a boost::array instead?
Here an example:
template
After some though, here is more precisely what I'd like to have... I apologize that it is quite different from the initial problem:
template<int n> class Tree { static double sum(); // };
If the user instantiates tree<2>, he should get:
template<> class Tree<2> { static double sum(double d1, double d2); };
template<> class Tree<3> { static double sum(double d1, double d2, double d3); }; etc etc...
so that in user code, for e.g.:
double d= Tree<4>::sum(d1, d2, d3, d4);
should compile.
Is it possible for me to just define the template Tree for the n-case without the 2- and 3- specializations?
Rds,
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Steven Watanabe Sent: 28 January 2008 16:42 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Template instantiation function arguments and Boost.Preprocessor
AMDG
hi,
i have a template function, the arguments of which i wish to have depend on a non-type int template argument:
template<int n> double f<n>( double arg0, double arg1, ..., double argn ) // ... is not
Hicham Mouline wrote: the variadic notation for var number of args
{ // for(int i=0; i
int main() { return x = f<3>( 1.0, 2.0, 3.0 ); }
BOOST_PP_REPEAT can't seem to do the job as the template argument n needs to be known at the preprocessing stage, which happens before the template instantiation stage ( this is part of compilation)
I don't understand why you want n to be passed explicitly. Can't it be deduced from the number of arguments (warning untested):
#define SUM_IMPL(z, n, data) + arg ## n #define F_DEF(z, n, data) double f(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { return(0.0 BOOST_PP_REPEAT_ ## z(n, SUM_IMPL, ~)); }
BOOST_PP_REPEAT(MAX_ARITY, F_DEF, ~)
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.516 / Virus Database: 269.19.14/1247 - Release Date: 1/28/2008 10:59 AM
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

hi,
i have a template function, the arguments of which i wish to have depend on a non-type int template argument:
template<int n> double f<n>( double arg0, double arg1, ..., double argn ) // ... is not
Hi, thanks for your answers,
Because I had tested just with :
1. static double sum(double d1, double d2, double d3)
{
return d1+d2+d3;
}
vs
2. static double sum(double d[3])
{
return d[0]+d[1]+d[2];
}
with calls to sum() in a tight loop.
I suspect boost::array is equivalent to 2.
was some 40% faster than 2 with advanced intel optimization.
Could you elaborate on the recursive generation?
Rds,
template
{ // for(int i=0; i
int main() { return x = f<3>( 1.0, 2.0, 3.0 ); }
BOOST_PP_REPEAT can't seem to do the job as the template argument n needs to be known at the preprocessing stage, which happens before the template instantiation stage ( this is part of compilation)
I don't understand why you want n to be passed explicitly. Can't it be deduced from the number of arguments (warning untested): #define SUM_IMPL(z, n, data) + arg ## n #define F_DEF(z, n, data) double f(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { return(0.0 BOOST_PP_REPEAT_ ## z(n, SUM_IMPL, ~)); } BOOST_PP_REPEAT(MAX_ARITY, F_DEF, ~) In Christ, Steven Watanabe _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users -- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.516 / Virus Database: 269.19.14/1247 - Release Date: 1/28/2008 10:59 AM _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Sorry, but your test was wrong. Try to pass the array to sum as const
reference. In your case you always copy the array!!! It should not be
faster.
On Jan 28, 2008 9:55 PM, Hicham Mouline
Hi, thanks for your answers,
Because I had tested just with :
1. static double sum(double d1, double d2, double d3) { return d1+d2+d3; }
vs
2. static double sum(double d[3]) { return d[0]+d[1]+d[2];
}
with calls to sum() in a tight loop.
I suspect boost::array is equivalent to 2.
was some 40% faster than 2 with advanced intel optimization.
Could you elaborate on the recursive generation?
Rds,
template
struct Tree { typedef boost::array parameters_types; };
*From:* boost-users-bounces@lists.boost.org [mailto: boost-users-bounces@lists.boost.org] *On Behalf Of *Ovanes Markarian *Sent:* 28 January 2008 21:27
*To:* boost-users@lists.boost.org *Subject:* Re: [Boost-users] Template instantiation function arguments and Boost.Preprocessor
Hi,
besides the more complex possibility to use boost::tuple and generate recursive Tree<X> List : derived from Tree<X-1> ...: derived from Tree<0> specialization, why not using a boost::array instead?
Here an example:
template
struct Tree { typedef boost::array parameters_types; T sum(parameters_type const& p) { return std::accumulate(p.begin(), p.end(), 0); }
};
This is type safe and fast ;) and your users can initialize boost array with an initializer list like:
parameters_type x = { 1, 2, 3, 4, 5... };
Regards, Ovanes
On Jan 28, 2008 8:26 PM, Hicham Mouline
wrote: After some though, here is more precisely what I'd like to have... I apologize that it is quite different from the initial problem:
template<int n> class Tree { static double sum(); // };
If the user instantiates tree<2>, he should get:
template<> class Tree<2> { static double sum(double d1, double d2); };
template<> class Tree<3> { static double sum(double d1, double d2, double d3); }; etc etc...
so that in user code, for e.g.:
double d= Tree<4>::sum(d1, d2, d3, d4);
should compile.
Is it possible for me to just define the template Tree for the n-case without the 2- and 3- specializations?
Rds,
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Steven Watanabe Sent: 28 January 2008 16:42 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Template instantiation function arguments and Boost.Preprocessor
AMDG
hi,
i have a template function, the arguments of which i wish to have depend on a non-type int template argument:
template<int n> double f<n>( double arg0, double arg1, ..., double argn ) // ... is not
Hicham Mouline wrote: the variadic notation for var number of args
{ // for(int i=0; i
int main() { return x = f<3>( 1.0, 2.0, 3.0 ); }
BOOST_PP_REPEAT can't seem to do the job as the template argument n needs to be known at the preprocessing stage, which happens before the template instantiation stage ( this is part of compilation)
I don't understand why you want n to be passed explicitly. Can't it be deduced from the number of arguments (warning untested):
#define SUM_IMPL(z, n, data) + arg ## n #define F_DEF(z, n, data) double f(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { return(0.0 BOOST_PP_REPEAT_ ## z(n, SUM_IMPL, ~)); }
BOOST_PP_REPEAT(MAX_ARITY, F_DEF, ~)
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.516 / Virus Database: 269.19.14/1247 - Release Date: 1/28/2008 10:59 AM
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

AMDG Ovanes Markarian wrote:
Sorry, but your test was wrong. Try to pass the array to sum as const reference. In your case you always copy the array!!! It should not be faster.
Wrong. An array argument to a function is really a pointer. In Christ, Steven Watanabe
On Jan 28, 2008 9:55 PM, Hicham Mouline
mailto:hicham@mouline.org> wrote: Hi, thanks for your answers,
Because I had tested just with :
1. static double sum(double d1, double d2, double d3) { return d1+d2+d3; }
vs
2. static double sum(double d[3]) { return d[0]+d[1]+d[2];
}

AMDG Hicham Mouline wrote:
After some though, here is more precisely what I'd like to have... I apologize that it is quite different from the initial problem:
template<int n> class Tree { static double sum(); // };
If the user instantiates tree<2>, he should get:
template<> class Tree<2> { static double sum(double d1, double d2); };
template<> class Tree<3> { static double sum(double d1, double d2, double d3); }; etc etc...
so that in user code, for e.g.:
double d= Tree<4>::sum(d1, d2, d3, d4);
should compile.
Is it possible for me to just define the template Tree for the n-case without the 2- and 3- specializations?
Ah. You still need the preprocessor, but you can rearrange the definitions slightly. (untested) template<int N> struct TreeSumImpl; #define TREE_SUM_DEF(z, n, data)\ template<>\ struct TreeSumImpl<n> {\ static double sum(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { ... }\ }; BOOST_PP_REPEAT(20, TREE_SUM_DEF, ~) template<int N> struct Tree : TreeSumImpl<N> { // other code }; In Christ, Steven Watanabe

Great. This works. -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Steven Watanabe Sent: 28 January 2008 22:39 To: boost-users@lists.boost.org Subject: Re: [Boost-users] Template instantiation function arguments and Boost.Preprocessor AMDG Ah. You still need the preprocessor, but you can rearrange the definitions slightly. (untested) template<int N> struct TreeSumImpl; #define TREE_SUM_DEF(z, n, data)\ template<>\ struct TreeSumImpl<n> {\ static double sum(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { ... }\ }; BOOST_PP_REPEAT(20, TREE_SUM_DEF, ~) template<int N> struct Tree : TreeSumImpl<N> { // other code }; In Christ, Steven Watanabe

sorry, I have overseen it somehow... Probably too late already... That's
true, that array argument to a function is a pointer. Sorry.
I have tested the code with gcc under MacOS X, the function with arguments
as 3 doubles was NOT necesserely faster as the boost::array param. It might
be not worse implementing the macro based approach...
Here is my test app compiled with O3 optimization flags. (Below are the
timing on a Dual Core 2.4 processor machine with 4 gb ram)
//============================================================================
// Name : CppTest.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <numeric>
#include
AMDG
Hicham Mouline wrote:
After some though, here is more precisely what I'd like to have... I apologize that it is quite different from the initial problem:
template<int n> class Tree { static double sum(); // };
If the user instantiates tree<2>, he should get:
template<> class Tree<2> { static double sum(double d1, double d2); };
template<> class Tree<3> { static double sum(double d1, double d2, double d3); }; etc etc...
so that in user code, for e.g.:
double d= Tree<4>::sum(d1, d2, d3, d4);
should compile.
Is it possible for me to just define the template Tree for the n-case without the 2- and 3- specializations?
Ah. You still need the preprocessor, but you can rearrange the definitions slightly. (untested)
template<int N> struct TreeSumImpl;
#define TREE_SUM_DEF(z, n, data)\ template<>\ struct TreeSumImpl<n> {\ static double sum(BOOST_PP_ENUM_PARAMS_Z(z, n, double arg)) { ... }\ };
BOOST_PP_REPEAT(20, TREE_SUM_DEF, ~)
template<int N> struct Tree : TreeSumImpl<N> { // other code };
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

AMDG Ovanes Markarian wrote:
array_type::value_type sum_carr_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0); }
array_type::value_type sum_arr_copy_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0); }
Please take a look, that accumulate produced wrong result.
Of course. The results are being collected in an int... In Christ, Steven Watanabe

Seven,
thanks a lot for pointing it out. That was a classical error!! :(
Anyway I re-ran the test, with corrected accumulate calls:
corrected calls:
array_type::value_type sum_carr_accumulate(array_type const& a)
{
return std::accumulate(a.begin(), a.end(), 0.0);
}
array_type::value_type sum_arr_copy_accumulate(array_type const& a)
{
return std::accumulate(a.begin(), a.end(), 0.0);
}
Results (which would be expected from std lib ;)
Running each test 4294967295 of times:
--------------------------
sum_arr_copy
64.79 s
result: 2.84756e+10
--------------------------
sum_carr
14.91 s
result: 2.84756e+10
--------------------------
sum_arr_copy_accumulate
14.91 s
result: 2.84756e+10
--------------------------
sum_carr_temp_result
14.91 s
result: 2.84756e+10
--------------------------
sum_carr_accumulate
14.91 s
result: 2.84756e+10
--------------------------
sum_doubles_copy
15.00 s
result: 2.84756e+10
--------------------------
sum_doubles_copy_optimized
14.96 s
result: 2.84756e+10
--------------------------
sum_doubles_copy_temp_result
14.92 s
result: 2.84756e+10
--------------------------
sum_doubles_ref_temp_result
14.97 s
result: 2.84756e+10
tests done
Regards,
Ovanes
On Jan 29, 2008 5:42 AM, Steven Watanabe
AMDG
Ovanes Markarian wrote:
array_type::value_type sum_carr_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0); }
array_type::value_type sum_arr_copy_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0); }
Please take a look, that accumulate produced wrong result.
Of course. The results are being collected in an int...
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

sum_arr_copy_accumulate is wrong. Array should be passed as copy. (I don't
know what's going on with me these days). Sorry for spamming the group...
Timing of copying the array and calling accumulate:
sum_arr_copy_accumulate
50.15 s
result: 2.84756e+10
Best Regards,
Ovanes
On Jan 29, 2008 9:25 AM, Ovanes Markarian
Seven,
thanks a lot for pointing it out. That was a classical error!! :(
Anyway I re-ran the test, with corrected accumulate calls:
corrected calls: array_type::value_type sum_carr_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0.0); }
array_type::value_type sum_arr_copy_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0.0); }
Results (which would be expected from std lib ;)
Running each test 4294967295 of times: -------------------------- sum_arr_copy 64.79 s
result: 2.84756e+10 -------------------------- sum_carr 14.91 s
result: 2.84756e+10 -------------------------- sum_arr_copy_accumulate 14.91 s
result: 2.84756e+10 -------------------------- sum_carr_temp_result 14.91 s
result: 2.84756e+10 -------------------------- sum_carr_accumulate 14.91 s
result: 2.84756e+10 -------------------------- sum_doubles_copy 15.00 s
result: 2.84756e+10 -------------------------- sum_doubles_copy_optimized 14.96 s
result: 2.84756e+10 -------------------------- sum_doubles_copy_temp_result 14.92 s
result: 2.84756e+10 -------------------------- sum_doubles_ref_temp_result 14.97 s
result: 2.84756e+10 tests done
Regards, Ovanes
On Jan 29, 2008 5:42 AM, Steven Watanabe
wrote: AMDG
Ovanes Markarian wrote:
array_type::value_type sum_carr_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0); }
array_type::value_type sum_arr_copy_accumulate(array_type const& a) { return std::accumulate(a.begin(), a.end(), 0); }
Please take a look, that accumulate produced wrong result.
Of course. The results are being collected in an int...
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hello, Is there any implementation of a priority queue, that is not thread-safe (lock-free), where the caller has the responsibility to check for thread safety? Regards,

Hello Hicham,
On 2/19/08, Hicham Mouline
Is there any implementation of a priority queue, that is not thread-safe (lock-free), where the caller has the responsibility to check for thread safety?
This is actually a part of the C++ standard: http://www.cppreference.com/cpppriority_queue/ -- Leon Mergen http://www.solatis.com
participants (4)
-
Hicham Mouline
-
Leon Mergen
-
Ovanes Markarian
-
Steven Watanabe