Re: Preprocessor directive for a sequence that differs only in datatype

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Preprocessor directive for a sequence that differs only in datatype

Boost - Dev mailing list
On 11/07/2017 19:22, Rishabh Arora wrote:

> I was trying to use the boost.preprocessor to write some code which
> otherwise needs to be written for all the cases.
> Here's the code:
> https://github.com/BoostGSoC17/dataframe/blob/master/include/df.cpp 
> (line no. 430 and 431).
> But on compilation it gives the error:
> error: macro "BOOST_PP_SEQ_ELEM_III" requires 2 arguments, but only 1 given
>       print_column <BOOST_PP_SEQ_ELEM(type, INNER_TYPE) >(i);
>
> I didn't understand the reason as when I wrote: print_column
> <BOOST_PP_SEQ_ELEM(any_numerical_value(0, 1, ...), INNER_TYPE) >(i); it
> works fine.
> Can anyone help me understand the error or provide an alternative way to
> do the same thing?

BOOST_PP_SEQ_ELEM's first parameter must be an expression resolvable at
preprocessing time (usually a constant).

"type" doesn't exist until runtime.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Preprocessor directive for a sequence that differs only in datatype

Boost - Dev mailing list
Thank you, Gavin Lambert.
I don't think any of the preprocessor directives will work then? because
type cannot be determined at comile time? Is there any other way to do
that?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Preprocessor directive for a sequence that differs only in datatype

Boost - Dev mailing list
On 07/11/2017 03:09 AM, Rishabh Arora via Boost wrote:
> Thank you, Gavin Lambert.
> I don't think any of the preprocessor directives will work then? because
> type cannot be determined at comile time? Is there any other way to do
> that?
>
What about replacing the switch with an index into a vector
of function pointers?  Something like:

#include <iostream>
template < class T >
void print_column(std::size_t col) {
   T dummy;
   std::cout <<dummy<< std::endl;
   return;
}
using fptr=void (*)(std::size_t);
fptr printers[]=
{ print_column<int>
, print_column<float>
};
int main()
{
   unsigned ncol_=2;
   for(unsigned i=0; i<ncol_; ++i)
   {
     printers[i](0);
   }
   return 0;
}



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Preprocessor directive for a sequence that differs only in datatype

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On 11/07/2017 20:09, Rishabh Arora wrote:
> I don't think any of the preprocessor directives will work then? because
> type cannot be determined at comile time? Is there any other way to do
> that?

You might want to look at the Boost.Fusion library
(http://www.boost.org/doc/libs/1_64_0/libs/fusion/doc/html/).

Or if this is C++11+ code, at std::tuple and std::get.  Though some of
these might still require values known at compile time; depending on
your usage you might be able to use constexpr methods for that, however.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Preprocessor directive for a sequence that differs only in datatype

Boost - Dev mailing list
On Wed, Jul 12, 2017 at 4:47 AM, Gavin Lambert via Boost <
[hidden email]> wrote:

> On 11/07/2017 20:09, Rishabh Arora wrote:
>
>> I don't think any of the preprocessor directives will work then? because
>> type cannot be determined at comile time? Is there any other way to do
>> that?
>>
>
> You might want to look at the Boost.Fusion library (
> http://www.boost.org/doc/libs/1_64_0/libs/fusion/doc/html/).
>
> How Can I use boost.fustion library as it requires compile time
computations if I am not wrong. Please correct me if I am.


> Or if this is C++11+ code, at std::tuple and std::get.  Though some of
> these might still require values known at compile time; depending on your
> usage you might be able to use constexpr methods for that, however.
>
> Can you please elaborate?

>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman
> /listinfo.cgi/boost
>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Preprocessor directive for a sequence that differs only in datatype

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On 07/11/2017 06:17 AM, Larry Evans via Boost wrote:

> On 07/11/2017 03:09 AM, Rishabh Arora via Boost wrote:
>> Thank you, Gavin Lambert.
>> I don't think any of the preprocessor directives will work then? because
>> type cannot be determined at comile time? Is there any other way to do
>> that?
>>
> What about replacing the switch with an index into a vector
> of function pointers?  Something like:
>
> #include <iostream>
> template < class T >
> void print_column(std::size_t col) {
>    T dummy;
>    std::cout <<dummy<< std::endl;
>    return;
> }
> using fptr=void (*)(std::size_t);
> fptr printers[]=
> { print_column<int>
> , print_column<float>
> };
> int main()
> {
>    unsigned ncol_=2;
>    for(unsigned i=0; i<ncol_; ++i)
>    {
>      printers[i](0);
>    }
>    return 0;
> }
>

More specifically:

#ifdef USE_PRINTER_TYPES
   template<typename... Types>
   struct printers
   {
     using fptr = void(data_frame::*)(size_t);
     static constexpr fptr _[sizeof...(Types)]=
     { &data_frame::print_column<Types>...
     };
   };
   using printer_types=printers<COLUMN_DATA_TYPES>;
#endif//USE_PRINTER_TYPES

Then, use printer_types in the data_frame::print function as:


   std::cout << "[" << column_headers_(i) << "]" << ": ";
   auto const itype=base_::operator[](column_headers_(i)).type();
#ifdef USE_PRINTER_TYPES
   printer_types::fptr printer=printer_types::_[itype];
   (this->*printer)(i);
#else
   switch(itype) {
.
.
.
#endif//USE_PRINTER_TYPES

HTH.

-regards,
Larry


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Loading...