2011-02-25 7 views
5

階乗関数のルックアップテーブルとして使用するboost::mpl::vectorを生成するコードを書きました。これは、開発者がルックアップを生成するためのより一般的なライブラリ関数のテストですテーブルを、基本配列の静的配列の形で格納します。関数(プリプロセッサマクロ定義として実装される可能性が最も高い)は、初期化される配列の名前とサイズ、各要素を初期化するためのメタ関数として使用されるクラステンプレートの名前を受け入れます。i配列。MPLベクトルを静的配列に変換する

私は、外部スクリプトを使用せずにこれを行うことについて移動する最良の方法は、以下のリストのコードで行われているように、boost::mpl::vectorを作成し、の戻り値をプッシュし

  1. になるだろうと思いました配列の各要素のベクトルの後部へのユーザ提供のメタ機能。
  2. ベクトルの要素を使用して、静的配列を初期化します(一連のマクロを使用して、最後には__VARARGS__マクロを使用します)。

私はどのように達成するのか(2)、また私が説明した手順が私が求めるものを行う良い方法ではないことを知っています。以下は、私が回答を希望する質問です:

  1. 私の手続きは、私が求めるものを達成する良い方法ですか?そうでない場合は、外部スクリプトを使用せずに、同じことを達成するより良い手順を記述してください。
  2. 私の手続きが確かに私が求めるものを達成するための良い方法であれば、どうすれば実装できますか(2)?

    私は一度実装すると、私が記述するライブラリ関数を含むソースファイルへのリンクを必ず投稿します。コードリストは以下の通りです。

    名前空間mpl = boost :: mpl;約束としてここ

    template <typename x> 
    struct factorial: 
        mpl::if_<mpl::greater<x, mpl::int_<1>>, 
         mpl::multiplies<x, factorial<x::prior>>, 
         mpl::int_<1> 
        >::type 
    {}; 
    
    template <typename sequence, typename size> 
    struct compileTable: 
        mpl::if_<mpl::greater<size, mpl::int_<0>>, 
         compileTable< 
          mpl::push_front<sequence, factorial<size>>::type, 
          size::prior 
         >, 
         sequence 
        >::type 
    {}; 
    
    static const int TABLE_SIZE = 13; 
    
    typedef compileTable< 
        mpl::vector<>, 
        mpl::int_<TABLE_SIZE> 
    >::type factorialTable; 
    
    /* 
    ** This is where I am stuck; how would I use the elements 
    ** of factorialTable to initialize a static array? 
    */ 
    
+0

使用http://www.boost.org/doc/libs/1_45_0/libs/mpl/doc/refmanual/for-each.html – Anycorn

+0

ここで私はちょっと混乱しています。これはそれぞれがランタイムアルゴリズムなので、静的配列を初期化するためにどのように使用しますか? –

+0

静的配列とはどういう意味ですか? 'static int foo []'? – Anycorn

答えて

1

は、ライブラリ機能を含むファイルのソースコードです。私がコードリストの下で行った発言を必ず読んでください。 BOOST_PP_ENUMを使用して静的配列を初期化する方法を教えてくれてありがとう、aaaにもう一度感謝します!私は、ファイルへのURLを提供する控える

#include <boost/mpl/greater.hpp> 
#include <boost/mpl/if.hpp> 
#include <boost/mpl/int.hpp> 
#include <boost/mpl/multiplies.hpp> 
#include <boost/mpl/placeholders.hpp> 
#include <cstdio> 
#include <xi/mpl/lut.hpp> 

namespace mpl = boost::mpl; 

template <typename x> 
struct factorial: 
    mpl::if_<mpl::greater<x, mpl::int_<1>>, 
     mpl::multiplies<x, factorial<x::prior>>, 
     mpl::int_<1> 
    >::type 
{}; 

XI_GENERATE_LUT(factorial, int, FACTORIAL_TABLE, 4); 

int main(int argc, char ** argv) { 

    // This should print '24:' 
    printf("Result: %d.\n", FACTORIAL_TABLE[3]); 
    return 0; 

} 

:便利なテストファイルのための

#ifndef __XI_LUT_INCLUDED__ 
#define __XI_LUT_INCLUDED__ 

#ifndef __cplusplus 
    #error The file __FILE__ requires a C++ compiler in order to be successfully compiled. 
#endif 

#include <boost/mpl/apply.hpp> 
#include <boost/mpl/at.hpp> 
#include <boost/mpl/greater.hpp> 
#include <boost/mpl/if.hpp> 
#include <boost/mpl/int.hpp> 
#include <boost/mpl/multiplies.hpp> 
#include <boost/mpl/placeholders.hpp> 
#include <boost/mpl/push_front.hpp> 
#include <boost/mpl/vector.hpp> 
#include <boost/preprocessor/repetition/enum.hpp> 

#define __XI_LUT_SET_INDEX(z, n, sequence) \ 
    mpl::at_c<sequence, n>::type::value 

#define __XI_GENERATE_LUT_IMPL(function, tableType, tableName, tableSize) \ 
    \ 
    template <typename sequence, typename size> \ 
    struct __compileTable_##function##_##tableSize##: \ 
     mpl::if_<mpl::greater<size, mpl::int_<0>>, \ 
      __compileTable_##function##_##tableSize##< \ 
       mpl::push_front<sequence, \ 
        mpl::apply< \ 
         function##<mpl::_>, \ 
         size \ 
        >::type>::type, \ 
       size::prior \ 
      >, \ 
      sequence \ 
     >::type \ 
    {}; \ 
    \ 
    typedef __compileTable_##function##_##tableSize##< \ 
     mpl::vector<>, \ 
     mpl::int_<##tableSize##> \ 
    >::type __compiledTable_##function##_##tableSize##; \ 
    \ 
    static const tableType tableName##[] = { \ 
     BOOST_PP_ENUM(\ 
      tableSize##, \ 
      __XI_LUT_SET_INDEX, \ 
      __compiledTable_##function##_##tableSize## \ 
     ) \ 
    } 

#define XI_GENERATE_LUT(function, tableType, tableName, tableSize) \ 
    __XI_GENERATE_LUT_IMPL(function, tableType, tableName, tableSize) 

#endif 

ソースコード:XI/MPL/lut.hため

ソースコードコードリストを編集できるようになりました。互換性のためにコードを改善することができると確信しています。したがって、最終的な状態ではありません。いくつかの既知の問題があります:

  1. コードはMSVC 9.0でコンパイルされません。
  2. メタファンクション名に同じサイズと同じメタファンクション名をすでに作成した後に、特定のサイズのルックアップ・テーブルを作成しようとすると、対応するタイプとテンプレートがこれらのパラメータに定義されるため、エラーになります。私は__COUNTER__を使用して非標準マクロ定義なので、この問題を軽減したくありません。

私はICCとMSCV以外の任意の他のコンパイラでこのコードをコンパイルしようとしていない、と GCCがそれをどのように処理するかを知りたいのですが - 私は、適切な遡及権を取ることができるように発生するすべての問題を教えてください。ほとんどのメジャーなコンパイラにはほとんど問題なく動作していれば、ファイルにURLを投稿します。どんなフィードバックでも大歓迎です!

関連する問題