FOREACH 宏之GCC实现

这个FOREACH使用了GCC的扩展特性typeof和({}),所以只保证能在linux下玩哦。

 

源程序 foreach.h

 

 

#ifndef _MACRO_FOREACH_H_
#define _MACRO_FOREACH_H_


#define FOREACH_USE_ITERATOR(each_var, it_begin, it_end) \
    if(int is_break_used_for_foreach=0){}else\
    for(typeof(it_begin) it = it_begin, iend = it_end; \
        (!is_break_used_for_foreach && (it!=iend)); ++it)\
        for(typeof(*it) each_var = *it; 1; __extension__({break;}))


#define FOREACH_USE_STL_CONTAINER(each_var, container) \
            FOREACH_USE_ITERATOR(each_var, container.begin(), container.end())

#define BREAK ({is_break_used_for_foreach = 1; break;})
#define CONTINUE ({continue;})

#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
#define ARRAY_BEGIN(array) (array+0)
#define ARRAY_END(array) (array+ARRAY_SIZE(array))

#define EACH_ARRAY(each_var, array)\
            FOREACH_USE_ITERATOR(each_var, ARRAY_BEGIN(array), ARRAY_BEGIN(array))


#define FOREACH FOREACH_USE_STL_CONTAINER
#define foreach FOREACH

#define EACH_RANGE(var, it_begin, it_end)\
    for(typeof(it_begin) it = it_begin, iend = it_end; (it!=iend); ++it)\
        for(typeof(*it) each_var = *it; 1; __extension__({break;}))

#define EACH(var, container) EACH_RANGE(var, container.begin(), container.end())

#define FOR_RANGE(var, start, end)\
    for(typeof(start) var = start, iend = end; var != end; ++var)

#define FOR(var, container) FOR_RANGE(var, container.begin(), contianer.end())

#define MAP_USE_ITERATOR(begin, end, result,  var, func)\
   FOREACH_USE_ITERATOR(var, begin, end){ \
    result.push_back((func));\
   }

#define MAP_USE_STL_CONTAINER(container, result, var, func) MAP_USE_ITERATOR(container.begin(), container.end(), result,  var, func)

#define MAP MAP_USE_STL_CONTAINER


#define FILTER_USE_ITERATOR(begin, end, result,  var, func)\
   FOREACH_USE_ITERATOR(var, begin, end){ \
    if((func)) \
     result.push_back(*cur);\
   };

#define FILTER_USE_STL_CONTAINER(container, result, var, func) FILTER_USE_ITERATOR(container.begin(), container.end(), result,  var, func)

#define FILTER FILTER_USE_STL_CONTAINER

#endif //_MACRO_FOREACH_H_


 

 

 

测试代码 foreach.test.cpp

 

#include <map>
#include "foreach.h"

using namespace std;

void test1(int);
void test2(int);

map<int, int> c;

int main(int argc, char **argv) {
    if(argc<4) {
        printf("too less param, input 3 params!\n");
        return 0;
    }

    int sel = atoi(argv[1]);
    void (*test)(int) = NULL;
    switch(sel) {
    case 1:
        test = test1;
        break;
    case 2:
        test = test2;
        break;
    }

    int num = atoi(argv[2]);
    for(int i =0; i<num; ++i) {
        c[i]=i;
    }

    int len = atoi(argv[3]);
    for(int i =0; i<len; ++i) {
        test(num);
    }
}

void test1(int num){
    int s = 0;
    foreach(const & a, c)
    {
        s+=(a.first+a.second);

    }
}

void test2(int num){
    int s = 0;
    map<int, int>::iterator it = c.begin(), iend = c.end();
    for(;it!=iend; ++it)
    {
        pair<int, int> const &a = *it;
        s+=(it->first + it->second);
    }
}

编译

    g++ -O2 ./foreach.test.cpp -o foreach

测试

foreach宏: time ./foreach 1 10000 50000

real  0m5.288s

user 0m5.241s

sys  0m0.015s

标准for循环:  time ./foreach 2 10000 50000

real  0m5.600s

user 0m5.533s

sys  0m0.031s

 

测试结果很让人吃惊,竟然宏版本还更快。 有时间要用 IDA看一下反汇编代码了。

 

早期实现

一开始不知道gcc 的 __extension__ 关键字,FOREACH_USE_ITERATOR实现的方式如下:


#define FOREACH_USE_ITERATOR(each_var, it_begin, it_end) \
    typeof(it_begin) FOREACH_VAR(it) = it_begin;\
    typeof(it_end) FOREACH_VAR(iend) = it_end; \
    if(likely(FOREACH_VAR(it)!=FOREACH_VAR(iend))){ \
        goto FOREACH_LABLE( into ); \
    }else {\
        goto FOREACH_LABLE( exit );\
    }\
    FOREACH_LABLE( exit ) :\
    if(0)\
    FOREACH_LABLE( into ) :\
    for(typeof(*FOREACH_VAR(it)) each_var = *FOREACH_VAR(it);\
        1;\
        ({\
            ++FOREACH_VAR(it);\
            if(likely(FOREACH_VAR(it) != FOREACH_VAR(iend))){ \
                goto FOREACH_LABLE( into );\
            }else {\
                goto FOREACH_LABLE( exit );\
            }; 1;\
        })\
    )

posted @ 2010-11-20 01:57  napoleon_liu  阅读(2499)  评论(3编辑  收藏  举报