2011-02-25 16 views
5

मैंने एक फैक्टरियल फ़ंक्शन के लिए लुकअप टेबल के रूप में उपयोग करने के लिए boost::mpl::vector उत्पन्न करने के लिए कुछ कोड लिखा, एक सामान्य लाइब्रेरी फ़ंक्शन के लिए एक परीक्षण के रूप में, जिसके साथ कोई डेवलपर लुकअप उत्पन्न कर सकता है primitives की एक स्थिर सरणी के रूप में तालिका। समारोह (जो संभवत: एक पूर्वप्रक्रमक मैक्रो परिभाषा के रूप में लागू किया जाएगा) नाम और सरणी के आकार को स्वीकार करेंगे प्रारंभ करने के लिए, साथ ही एक वर्ग टेम्पलेट के नाम प्रत्येक तत्व मैं की प्रारंभ करने में metafunction के रूप में प्रयोग की जाने वाली सरणीएक एमपीएल वेक्टर को एक स्टेटिक ऐरे में परिवर्तित करना

मैंने सोचा था कि सबसे अच्छा तरीका है बाहरी स्क्रिप्ट के उपयोग के बिना यह कर

  1. होगा एक boost::mpl::vector बनाएं के बारे में जाना है कि करने के लिए, के रूप में कोड में नीचे सूचीबद्ध किया जाता है, और के रिटर्न मान धक्का वेक्टर के पीछे सरणी के प्रत्येक तत्व के लिए उपयोगकर्ता द्वारा आपूर्ति मेटाफंक्शन;
  2. वेक्टर के तत्वों का प्रयोग करें स्थिर सरणी प्रारंभ (शायद मैक्रो, जिनमें से आखिरी यह पूरा करने का प्रयोग करेंगे __VARARGS__ मैक्रो की एक श्रृंखला का उपयोग करके)।

मुझे नहीं पता कि मैं कैसे पूरा करूंगा (2) और न ही मैं जो प्रक्रिया का वर्णन करता हूं वह है जो मैं चाहता हूं वह करने का एक अच्छा तरीका है। यहां निम्न प्रश्न दिए गए हैं जिनके लिए मुझे उत्तर चाहिए:

  1. क्या मेरी प्रक्रिया मेरी इच्छाओं को पूरा करने का एक अच्छा तरीका है? यदि नहीं, तो कृपया एक बेहतर प्रक्रिया का वर्णन करें जो बाहरी स्क्रिप्ट के उपयोग के बिना एक ही चीज़ को पूरा करेगा।
  2. यदि मेरे प्रक्रिया वास्तव में मैं क्या तलाश को पूरा करने का एक अच्छा तरीका है, मैं कैसे लागू होगा (2)?

    मैं स्रोत पुस्तकालय समारोह जो मैं एक बार का वर्णन मैं इसे लागू युक्त फ़ाइल के लिए लिंक पोस्ट करने के लिए सुनिश्चित हो जाएगा। कोड लिस्टिंग नीचे दी गई है।

    नाम स्थान एमपीएल = बढ़ावा देने :: एमपीएल;

    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

स्थिर सरणी से आपका क्या मतलब है? 'स्थिर int foo []'? – Anycorn

उत्तर

1

यहाँ पुस्तकालय समारोह युक्त फ़ाइल के लिए स्रोत कोड है, वादा किया था के रूप में; कृपया कोड सूची के नीचे किए गए टिप्पणियों को पढ़ना सुनिश्चित करें। मुझे दिखा कैसे BOOST_PP_ENUM का उपयोग कर एक स्थिर सरणी प्रारंभ करने में aaa उसकी मदद के लिए लिए फिर से धन्यवाद! xi के लिए

स्रोत कोड/एमपीएल/lut.h:

#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; 

} 

मैं के लिए फ़ाइल का URL उपलब्ध कराने से बचना होगा: एक उपयोगी परीक्षण फ़ाइल के लिए

#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 

स्रोत कोड अब मैं कोड सूची संपादित करना जारी रख सकता हूं। मुझे विश्वास है कि संगतता के प्रयोजनों के लिए कोड में सुधार किया जा सकता है, इसलिए यह निश्चित रूप से अंतिम स्थिति में नहीं है। यहाँ कुछ ज्ञात समस्या:

  1. कोड MSVC 9.0 पर संकलन नहीं होंगे।
  2. एक के बाद किसी भी आकार के मेटाफंक्शन नाम के लिए किसी विशेष आकार की लुकअप तालिका बनाने का प्रयास पहले से ही उसी आकार के लिए बनाया गया है और उसी मेटाफंक्शन नाम के लिए एक त्रुटि होगी, क्योंकि इन पैरामीटरों के लिए संबंधित प्रकार और टेम्पलेट परिभाषित किए जाएंगे । मैं इस समस्या को कम करने के लिए __COUNTER__ का उपयोग नहीं करना चाहता क्योंकि यह एक गैर-मानक मैक्रो परिभाषा है।

मैं आईसीसी और MSCV को छोड़कर किसी भी अन्य compilers पर इस कोड संकलन प्रयास नहीं किया है, और पता है कि कैसे जीसीसी यह संभालती चाहते होगा - मुझे किसी भी मुद्दे हैं जो इसलिए उठता है कि उचित सहारा लिया जा सकता है की हमें बताएं । एक बार जब कोड सबसे प्रमुख कंपेलरों पर थोड़ी परेशानी के साथ काम करता है तो मैं फ़ाइल में एक यूआरएल पोस्ट करूंगा। किसी भी प्रतिक्रिया की काफी सराहना की जाएगी!

संबंधित मुद्दे