C++ foreach

アバター
lriki
記事: 88
登録日時: 14年前

C++ foreach

投稿記事 by lriki » 13年前

STL のコンテナの繰り返しをスムーズに書きたいときは BOOST_FOREACH。

でも僅かばかり「foreach だけ使いたいのにライブラリを boost 依存にするのもなぁ…」と思ってしまったのが事の始まり。
なんやかんやで書いてしまいました。
車輪?大丈夫です。問題ありません。

CODE:

//=============================================================================
// Foreach
//-----------------------------------------------------------------------------
///**
//  @file       Foreach.h
//  @brief      Foreach
//  @author     Riki
//*/
//=============================================================================

#pragma once

namespace Lumine
{
namespace Base
{
namespace Foreach
{
struct any_itr_base
{
    operator bool() const { return true; }
};

template
struct any_itr
    : any_itr_base
{
    explicit any_itr( ITR_T const &t_ )
      : Item( t_ )
    {}
    mutable ITR_T Item;
};

typedef any_itr_base const &any_itr_t;

template
struct col_type
{
    typedef typename COL_T::iterator itr_type;
};

template
inline any_itr::itr_type > begin( COL_T& col_ )
{
    return any_itr( col_.begin() );
}

template
inline any_itr::itr_type > end( COL_T& col_ )
{
    return any_itr( col_.end() );
}

template
inline typename COL_T::iterator& get_itr( any_itr_t any_itr_, COL_T& )
{
    return static_cast const& >( any_itr_ ).Item;
}

} // namespace Foreach
} // namespace Base
} // namespace Lumine

#define ln_foreach( var_, col_ ) \
    if ( Lumine::Base::Foreach::any_itr_t _ln_foreach_cur_ = Lumine::Base::Foreach::begin( col_ ) ) \
    if ( Lumine::Base::Foreach::any_itr_t _ln_foreach_end_ = Lumine::Base::Foreach::end( col_ ) ) \
    for ( \
        bool _ln_foreach_continue_ = true; \
        Lumine::Base::Foreach::get_itr( _ln_foreach_cur_, col_ ) != Lumine::Base::Foreach::get_itr( _ln_foreach_end_, col_ ); \
        ++Lumine::Base::Foreach::get_itr( _ln_foreach_cur_, col_ ), _ln_foreach_continue_ = true ) \
    for ( var_ = *Lumine::Base::Foreach::get_itr( _ln_foreach_cur_, col_ ); _ln_foreach_continue_; _ln_foreach_continue_ = false )

使い方はこんな感じ。

CODE:

void main()
{
	std::vector ary;
	ary.push_back(2);
	ary.push_back(5);
	ary.push_back(7);
	ary.push_back(8);

	ln_foreach( int a, ary )
	{
		std::cout ::iterator itr = ary.begin();
std::vector::iterator end = ary.end();
for ( ; itr != end; ++itr )
{
	int a = *itr;
	std::cout << a << std::endl;
}

とりあえず vc++ と gcc でコンパイル確認しました。
パフォーマンスもboostと変わらないはず。
普通に使っていただくもよし、template の変態な使い方を参考にするもよし(本家はもっとすごいですけどね…)。

どこかの誰かの助けになりますように。なんて。

アバター
GRAM
記事: 164
登録日時: 14年前

RE: C++ foreach

投稿記事 by GRAM » 13年前

どこかのだれかの助けになるかはわかりませんけれど、新機能のrange-based-forも書きたくなっちゃいますよね

CODE:

#include 
#include 
 
int main()
{
    std::vector ary;
    ary.push_back(2);
    ary.push_back(5);
    ary.push_back(7);
    ary.push_back(8);
 
    for( auto a : ary )
    {
        std::cout << a << std::endl;
    }
    return 0;
}
最後に編集したユーザー GRAM on 2012年10月02日(火) 00:59 [ 編集 1 回目 ]

アバター
nullptr
記事: 239
登録日時: 13年前

Re: C++ foreach

投稿記事 by nullptr » 13年前

っ【C++11】

標準STLにfor_eachが搭載されちゃってます(知ってますよねスイマセン)

アバター
lriki
記事: 88
登録日時: 14年前

Re: C++ foreach

投稿記事 by lriki » 13年前

しし、しししししし知ってるもんね!ほ、本当だからね!!ね!?


一応ゲームライブラリ作ってるっていう体、少し古い環境でもビルドできるように・・・っていう考えでいるけど、もうそんなこと考えない方がいいのかなぁ・・・。
c++0xも全然触ってないし・・・はぁ。

アバター
nullptr
記事: 239
登録日時: 13年前

Re: C++ foreach

投稿記事 by nullptr » 12年前

c++0x→C++11

まぁ確かに古い環境でも、っていうのは大事ですけどね~。
ただいずれ標準はこちらになるわけですし、プリプロセッサで対応コンパイラなら標準STL、未対応の古いコンパイラなどならboostとか分けるのが現状ではベストなのかなと