2012-08-22 18 views
9

में एक छोटे से अभिन्न प्रकार को समझने के लिए सबसे छोटा अभिन्न प्रकार कैसे पता लगाया जा सकता है, मुझे संकलित समय में, किसी विशेष संख्या का प्रतिनिधित्व करने वाले छोटे हस्ताक्षरित अभिन्न प्रकार को समझने की आवश्यकता है। कुछ इस तरह ...संकलन समय

////////////////////////////////////////////////////////////////////////// 
template<size_t Bits> 
struct uint_least{}; 

template<> 
struct uint_least<8>{ typedef std::uint8_t type; }; 

template<> 
struct uint_least<16>{ typedef std::uint16_t type; }; 

////////////////////////////////////////////////////////////////////////// 
template<size_t max> 
struct uint_least_bits 
{ 
    static const size_t value = 14; // just a placeholder 
}; 

////////////////////////////////////////////////////////////////////////// 
template<size_t max> 
class A 
{ 
    typedef typename uint_least<uint_least_bits<max>::value>::type underlying_type; 

    underlying_type m_X; 
}; 

uint_least आप छोटी से छोटी अहस्ताक्षरित अभिन्न प्रकार है कि कम से कम Bits बड़े देना करने के लिए है और यह 64 64 (न सिर्फ 8, 16, 32 अप करने के लिए किसी भी मूल्य के लिए काम करना चाहिए लेकिन 1, 4, 13, आदि)।

uint_least_bits आपको max का प्रतिनिधित्व करने के लिए आवश्यक न्यूनतम बिट्स देने के लिए है।

  • मैं uint_least कैसे कार्यान्वित कर सकता हूं?
  • मैं uint_least_bits को कैसे कार्यान्वित कर सकता हूं?
  • किस प्रकार bits, min, और max होना चाहिए? अगर उत्तर एक टेम्पलेट प्रकार है, तो मैं अमान्य इनपुट के खिलाफ कैसे सुरक्षा कर सकता हूं?

लक्षणों की सटीक संरचना कोई फर्क नहीं पड़ता। जो मैंने प्रदान किया है उसे स्क्रैप करने के लिए स्वतंत्र महसूस करें। मुझे बस एक संख्या प्रदान करने की आवश्यकता है और इसे सबसे छोटा हस्ताक्षरित अभिन्न प्रकार वापस प्राप्त करने की आवश्यकता है जो इसे पकड़ सकता है।

+0

आप अपने अभिन्न स्थिरांक पर केवल 'decltype' का उपयोग कर सकते हैं। –

+4

'int_least_bits <255, 256> :: मान' 1 या 9 होना चाहिए? – GManNickG

+0

@GManNickG अच्छा सवाल। मैं 9 कहूंगा, हालांकि असहमत होने के लिए स्वतंत्र महसूस करें और मुझे बताएं कि – David

उत्तर

8

मैंने कल यह किया, क्या एक संयोग है। मैं इसे यहाँ छोड़ देंगे, भले ही यह नहीं है बिल्कुल आपको क्या चाहिए (यह वैसे भी सबसे अच्छा अभिन्न प्रकार बात ठीक करता है):, तब

#include <type_traits> 
#include <stdint.h> 

template<size_t i> 
struct best_type { 
    typedef typename std::conditional< 
     (i <= 8), 
     uint8_t, 
     typename std::conditional< 
      (i <= 16), 
      uint16_t, 
      typename std::conditional< 
       (i <= 32), 
       uint32_t, 
       uint64_t 
      >::type 
     >::type 
    >::type type; 
}; 

आप इसे इस प्रकार का उपयोग करेंगे:

#include <type_traits> 
#include <iostream> 
#include <stdint.h> 

template<size_t i> 
struct best_type { 
    typedef typename std::conditional< 
     (i <= 8), 
     uint8_t, 
     typename std::conditional< 
      (i <= 16), 
      uint16_t, 
      typename std::conditional< 
       (i <= 32), 
       uint32_t, 
       uint64_t 
      >::type 
     >::type 
    >::type type; 
}; 

int main() { 
    std::cout << sizeof(best_type<2>::type) << std::endl; 
    std::cout << sizeof(best_type<8>::type) << std::endl; 
    std::cout << sizeof(best_type<15>::type) << std::endl; 
    std::cout << sizeof(best_type<17>::type) << std::endl; 
} 

लाइव डेमो, here

+2

+1 लेकिन ओपी को कम से कम उम्मीद होने पर मुझे 'constexpr' का उपयोग करने के लिए क्रेडिट प्राप्त करना चाहिए। :-) –

4

आप constexpr मिल गया है, तो यह काम करेगा:

#include <climits> 
#include <cstdint> 
#include <cstddef> 

inline 
constexpr 
unsigned 
clz(unsigned x) 
{ 
    return x == 0 ? sizeof(x)*CHAR_BIT : x & 0x80000000 ? 0 : 1 + clz(x << 1); 
} 

inline 
constexpr 
unsigned 
clp2(unsigned x) 
{ 
    return x == 0 ? 0 : 1 << (sizeof(x)*CHAR_BIT - clz(x-1)); 
} 

inline 
constexpr 
unsigned 
at_least8(unsigned x) 
{ 
    return x < 8 ? 8 : x; 
} 

template<size_t Bits> 
struct uint_least{}; 

template<> 
struct uint_least<8>{ typedef std::uint8_t type; }; 

template<> 
struct uint_least<16>{ typedef std::uint16_t type; }; 

template<> 
struct uint_least<32>{ typedef std::uint32_t type; }; 

template<> 
struct uint_least<64>{ typedef std::uint64_t type; }; 

template<size_t max> 
struct uint_least_bits 
{ 
    static const size_t value = clp2(max); 
}; 

template<size_t max> 
class A 
{ 
    typedef typename uint_least<at_least8(uint_least_bits<max>::value)>::type underlying_type; 

    underlying_type m_X; 
}; 

int main() 
{ 
    A<3> a; 
} 

आप constexpr की जरूरत नहीं है, तो आप एक टेम्पलेट मेटा-समारोह में clp2 उसका अनुवाद कर सकें (और उस के लिए एक व्यायाम के रूप बचा है पाठक :-))।

ओह, अस्वीकरण: 32 बिट unsigned मानता है। यदि आवश्यक हो तो भी सामान्यीकृत किया जा सकता है।

+0

मुझे बताएं कि क्या मैं गलत हूं, लेकिन मुझे लगता है कि 'constexpr' कार्यों को परिभाषित करते समय सटीक' इनलाइन 'के लिए बेकार है। – Morwenn

+0

कंस्ट्रैक्स फ़ंक्शन अभी भी रन-टाइम पर चल सकते हैं यदि गैर-कॉन्स्टेक्सप्र तर्क के साथ बुलाया जाता है। –

+0

सी ++ 11 मानक से, धारा 7.1.5: 'constexpr फ़ंक्शंस और कंस्ट्रैक्स कन्स्ट्रक्टर निहित रूप से इनलाइन हैं'। ठीक है, वर्तमान समस्या से इसका कोई लेना-देना नहीं है। कम से कम मेरे पास एक प्रश्न का उत्तर है। परेशानी के लिए खेद हैं। – Morwenn

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