Mapping an integral template parameter value onto a primitive type












1















I want to map a number to a type. For this example I'll make a function that maps a sizeof() result onto a signed primitive type.



I am wondering if there is a better way of doing what I did below in modern C++, which is to take a templated value and convert it into a type. Right now this works in converting a size to a known type, but I can't seem to find anything in the standard library that does what I want. Have I missed something?



If not, is there a better way of doing this or cleaning up this code? For example if somehow in the future we end up having 128 bit types, this wouldn't support that.



#include <iostream>
#include <type_traits>

template <size_t S>
static constexpr auto sizeToType() {
static_assert(S == 1 or S == 2 or S == 4 or S == 8, "Bad type size");

if constexpr (S == 1)
return int8_t{};
else if constexpr (S == 2)
return int16_t{};
else if constexpr (S == 4)
return int32_t{};
else
return int64_t{};
}

int main() {
using MY_TYPE = decltype(sizeToType<2>());

MY_TYPE myType = MY_TYPE(0xFFFFFFFFFFFFFFFEUL);

std::cout << sizeof(MY_TYPE) << " bytes" << std::endl;
std::cout << "MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = " << myType << std::endl;
}


Output (as expected):



2 bytes
MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = -2









share|improve this question























  • whats wrong with the solution you have? Given that your code as written is only possible with modern c++, I wonder what the question is

    – user463035818
    Nov 26 '18 at 20:03













  • @user463035818 As said in my post, I want to know if there is a better way to do this, or possibly something that can scale to any primitive size type if new ones are introduced (ex: __int128 as seen here if supported) automatically without needing to update the code ever. I also would like to know if there's a less verbose and less brittle way of doing what I did.

    – Water
    Nov 26 '18 at 20:05













  • even the types you use in your example are just optional and are provided only if the implementation directly supports the type.

    – user463035818
    Nov 26 '18 at 20:08











  • do we agree your solution would not support any types as size is really a poor way to get type equality? that said, you could use a tuple of supported types and find in it which one match the size

    – OznOg
    Nov 26 '18 at 20:08
















1















I want to map a number to a type. For this example I'll make a function that maps a sizeof() result onto a signed primitive type.



I am wondering if there is a better way of doing what I did below in modern C++, which is to take a templated value and convert it into a type. Right now this works in converting a size to a known type, but I can't seem to find anything in the standard library that does what I want. Have I missed something?



If not, is there a better way of doing this or cleaning up this code? For example if somehow in the future we end up having 128 bit types, this wouldn't support that.



#include <iostream>
#include <type_traits>

template <size_t S>
static constexpr auto sizeToType() {
static_assert(S == 1 or S == 2 or S == 4 or S == 8, "Bad type size");

if constexpr (S == 1)
return int8_t{};
else if constexpr (S == 2)
return int16_t{};
else if constexpr (S == 4)
return int32_t{};
else
return int64_t{};
}

int main() {
using MY_TYPE = decltype(sizeToType<2>());

MY_TYPE myType = MY_TYPE(0xFFFFFFFFFFFFFFFEUL);

std::cout << sizeof(MY_TYPE) << " bytes" << std::endl;
std::cout << "MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = " << myType << std::endl;
}


Output (as expected):



2 bytes
MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = -2









share|improve this question























  • whats wrong with the solution you have? Given that your code as written is only possible with modern c++, I wonder what the question is

    – user463035818
    Nov 26 '18 at 20:03













  • @user463035818 As said in my post, I want to know if there is a better way to do this, or possibly something that can scale to any primitive size type if new ones are introduced (ex: __int128 as seen here if supported) automatically without needing to update the code ever. I also would like to know if there's a less verbose and less brittle way of doing what I did.

    – Water
    Nov 26 '18 at 20:05













  • even the types you use in your example are just optional and are provided only if the implementation directly supports the type.

    – user463035818
    Nov 26 '18 at 20:08











  • do we agree your solution would not support any types as size is really a poor way to get type equality? that said, you could use a tuple of supported types and find in it which one match the size

    – OznOg
    Nov 26 '18 at 20:08














1












1








1


1






I want to map a number to a type. For this example I'll make a function that maps a sizeof() result onto a signed primitive type.



I am wondering if there is a better way of doing what I did below in modern C++, which is to take a templated value and convert it into a type. Right now this works in converting a size to a known type, but I can't seem to find anything in the standard library that does what I want. Have I missed something?



If not, is there a better way of doing this or cleaning up this code? For example if somehow in the future we end up having 128 bit types, this wouldn't support that.



#include <iostream>
#include <type_traits>

template <size_t S>
static constexpr auto sizeToType() {
static_assert(S == 1 or S == 2 or S == 4 or S == 8, "Bad type size");

if constexpr (S == 1)
return int8_t{};
else if constexpr (S == 2)
return int16_t{};
else if constexpr (S == 4)
return int32_t{};
else
return int64_t{};
}

int main() {
using MY_TYPE = decltype(sizeToType<2>());

MY_TYPE myType = MY_TYPE(0xFFFFFFFFFFFFFFFEUL);

std::cout << sizeof(MY_TYPE) << " bytes" << std::endl;
std::cout << "MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = " << myType << std::endl;
}


Output (as expected):



2 bytes
MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = -2









share|improve this question














I want to map a number to a type. For this example I'll make a function that maps a sizeof() result onto a signed primitive type.



I am wondering if there is a better way of doing what I did below in modern C++, which is to take a templated value and convert it into a type. Right now this works in converting a size to a known type, but I can't seem to find anything in the standard library that does what I want. Have I missed something?



If not, is there a better way of doing this or cleaning up this code? For example if somehow in the future we end up having 128 bit types, this wouldn't support that.



#include <iostream>
#include <type_traits>

template <size_t S>
static constexpr auto sizeToType() {
static_assert(S == 1 or S == 2 or S == 4 or S == 8, "Bad type size");

if constexpr (S == 1)
return int8_t{};
else if constexpr (S == 2)
return int16_t{};
else if constexpr (S == 4)
return int32_t{};
else
return int64_t{};
}

int main() {
using MY_TYPE = decltype(sizeToType<2>());

MY_TYPE myType = MY_TYPE(0xFFFFFFFFFFFFFFFEUL);

std::cout << sizeof(MY_TYPE) << " bytes" << std::endl;
std::cout << "MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = " << myType << std::endl;
}


Output (as expected):



2 bytes
MY_TYPE(0xFFFFFFFFFFFFFFFEUL) = -2






c++ templates c++17






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 26 '18 at 19:59









WaterWater

91211232




91211232













  • whats wrong with the solution you have? Given that your code as written is only possible with modern c++, I wonder what the question is

    – user463035818
    Nov 26 '18 at 20:03













  • @user463035818 As said in my post, I want to know if there is a better way to do this, or possibly something that can scale to any primitive size type if new ones are introduced (ex: __int128 as seen here if supported) automatically without needing to update the code ever. I also would like to know if there's a less verbose and less brittle way of doing what I did.

    – Water
    Nov 26 '18 at 20:05













  • even the types you use in your example are just optional and are provided only if the implementation directly supports the type.

    – user463035818
    Nov 26 '18 at 20:08











  • do we agree your solution would not support any types as size is really a poor way to get type equality? that said, you could use a tuple of supported types and find in it which one match the size

    – OznOg
    Nov 26 '18 at 20:08



















  • whats wrong with the solution you have? Given that your code as written is only possible with modern c++, I wonder what the question is

    – user463035818
    Nov 26 '18 at 20:03













  • @user463035818 As said in my post, I want to know if there is a better way to do this, or possibly something that can scale to any primitive size type if new ones are introduced (ex: __int128 as seen here if supported) automatically without needing to update the code ever. I also would like to know if there's a less verbose and less brittle way of doing what I did.

    – Water
    Nov 26 '18 at 20:05













  • even the types you use in your example are just optional and are provided only if the implementation directly supports the type.

    – user463035818
    Nov 26 '18 at 20:08











  • do we agree your solution would not support any types as size is really a poor way to get type equality? that said, you could use a tuple of supported types and find in it which one match the size

    – OznOg
    Nov 26 '18 at 20:08

















whats wrong with the solution you have? Given that your code as written is only possible with modern c++, I wonder what the question is

– user463035818
Nov 26 '18 at 20:03







whats wrong with the solution you have? Given that your code as written is only possible with modern c++, I wonder what the question is

– user463035818
Nov 26 '18 at 20:03















@user463035818 As said in my post, I want to know if there is a better way to do this, or possibly something that can scale to any primitive size type if new ones are introduced (ex: __int128 as seen here if supported) automatically without needing to update the code ever. I also would like to know if there's a less verbose and less brittle way of doing what I did.

– Water
Nov 26 '18 at 20:05







@user463035818 As said in my post, I want to know if there is a better way to do this, or possibly something that can scale to any primitive size type if new ones are introduced (ex: __int128 as seen here if supported) automatically without needing to update the code ever. I also would like to know if there's a less verbose and less brittle way of doing what I did.

– Water
Nov 26 '18 at 20:05















even the types you use in your example are just optional and are provided only if the implementation directly supports the type.

– user463035818
Nov 26 '18 at 20:08





even the types you use in your example are just optional and are provided only if the implementation directly supports the type.

– user463035818
Nov 26 '18 at 20:08













do we agree your solution would not support any types as size is really a poor way to get type equality? that said, you could use a tuple of supported types and find in it which one match the size

– OznOg
Nov 26 '18 at 20:08





do we agree your solution would not support any types as size is really a poor way to get type equality? that said, you could use a tuple of supported types and find in it which one match the size

– OznOg
Nov 26 '18 at 20:08












2 Answers
2






active

oldest

votes


















7














I would not use C++17 if constexpr for this, instead I'd use template specialization, as it looks more declarative to me.



Something along the following lines:



template<size_t S> struct SizeToType {static_assert(S != S, "Wrong size"); };

template<> struct SizeToType<1> { using type = uint8_t; };
template<> struct SizeToType<2> { using type = uint16_t; };
template<> struct SizeToType<4> { using type = uint32_t; };
template<> struct SizeToType<8> { using type = uint64_t; };

template<size_t S>
using SizeToToTypeT = typename SizeToType<S>::type;


Adding more types would be just adding more specializations (one-liners) here.






share|improve this answer





















  • 3





    The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

    – StoryTeller
    Nov 26 '18 at 20:31











  • @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

    – SergeyA
    Nov 26 '18 at 20:34






  • 3





    Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

    – StoryTeller
    Nov 26 '18 at 20:37













  • @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

    – SergeyA
    Nov 26 '18 at 20:39











  • I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

    – StoryTeller
    Nov 26 '18 at 20:43



















2














Not a great solution... but just for fun...



I propose a type traits (with helper and using to select the internal type) that, given a number (the number of bytes) and a list of types select the first type of the list with sizeof() greater or equal (or nothing if there is no such type)



template <std::size_t, typename, typename = std::true_type>
struct sizeTypeH;

template <std::size_t Dim>
struct sizeTypeH<Dim, std::tuple<>, std::true_type>
{ }; // no type found

template <std::size_t Dim, typename T0, typename ... Ts>
struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
std::integral_constant<bool, (sizeof(T0) >= Dim)>>
{ using type = T0; };

template <std::size_t Dim, typename T0, typename ... Ts>
struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
std::integral_constant<bool, (sizeof(T0) < Dim)>>
: public sizeTypeH<Dim, std::tuple<Ts...>>
{ };

template <std::size_t Dim, typename ... Ts>
struct sizeType : public sizeTypeH<Dim, std::tuple<Ts...>>
{ };

template <std::size_t Dim, typename ... Ts>
using sizeType_t = typename sizeType<Dim, Ts...>::type;


Now another using that, receiving a integer, call this type traits with the ordered list of intX_t types



template <std::size_t Dim>
using intType_t = sizeType_t<Dim, std::int8_t, std::int16_t, std::int32_t,
std::int64_t>;


In my platform I have that the following static_assert() are verified.



   using t8  = intType_t<1u>;
using t16 = intType_t<2u>;
using t32 = intType_t<4u>;
using t64 = intType_t<8u>;

static_assert( std::is_same<t8, std::int8_t>{}, "!" );
static_assert( std::is_same<t16, std::int16_t>{}, "!" );
static_assert( std::is_same<t32, std::int32_t>{}, "!" );
static_assert( std::is_same<t64, std::int64_t>{}, "!" );


If, tomorrow, is introduced a int128_t, you can simply add it in intType_t using definition.



Attention, please: there is no guaranties that the preceding static_assert() are satisfied.



First of all because the standard guaranties that a byte is at least of 8 bits; but can be more that 8 bits. If a byte is of 16 bits, from



using t16 = intType_t<2u>;


you get a type of 32 bits.



Second because intX_t types are optionals.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53488151%2fmapping-an-integral-template-parameter-value-onto-a-primitive-type%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    7














    I would not use C++17 if constexpr for this, instead I'd use template specialization, as it looks more declarative to me.



    Something along the following lines:



    template<size_t S> struct SizeToType {static_assert(S != S, "Wrong size"); };

    template<> struct SizeToType<1> { using type = uint8_t; };
    template<> struct SizeToType<2> { using type = uint16_t; };
    template<> struct SizeToType<4> { using type = uint32_t; };
    template<> struct SizeToType<8> { using type = uint64_t; };

    template<size_t S>
    using SizeToToTypeT = typename SizeToType<S>::type;


    Adding more types would be just adding more specializations (one-liners) here.






    share|improve this answer





















    • 3





      The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

      – StoryTeller
      Nov 26 '18 at 20:31











    • @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

      – SergeyA
      Nov 26 '18 at 20:34






    • 3





      Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

      – StoryTeller
      Nov 26 '18 at 20:37













    • @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

      – SergeyA
      Nov 26 '18 at 20:39











    • I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

      – StoryTeller
      Nov 26 '18 at 20:43
















    7














    I would not use C++17 if constexpr for this, instead I'd use template specialization, as it looks more declarative to me.



    Something along the following lines:



    template<size_t S> struct SizeToType {static_assert(S != S, "Wrong size"); };

    template<> struct SizeToType<1> { using type = uint8_t; };
    template<> struct SizeToType<2> { using type = uint16_t; };
    template<> struct SizeToType<4> { using type = uint32_t; };
    template<> struct SizeToType<8> { using type = uint64_t; };

    template<size_t S>
    using SizeToToTypeT = typename SizeToType<S>::type;


    Adding more types would be just adding more specializations (one-liners) here.






    share|improve this answer





















    • 3





      The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

      – StoryTeller
      Nov 26 '18 at 20:31











    • @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

      – SergeyA
      Nov 26 '18 at 20:34






    • 3





      Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

      – StoryTeller
      Nov 26 '18 at 20:37













    • @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

      – SergeyA
      Nov 26 '18 at 20:39











    • I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

      – StoryTeller
      Nov 26 '18 at 20:43














    7












    7








    7







    I would not use C++17 if constexpr for this, instead I'd use template specialization, as it looks more declarative to me.



    Something along the following lines:



    template<size_t S> struct SizeToType {static_assert(S != S, "Wrong size"); };

    template<> struct SizeToType<1> { using type = uint8_t; };
    template<> struct SizeToType<2> { using type = uint16_t; };
    template<> struct SizeToType<4> { using type = uint32_t; };
    template<> struct SizeToType<8> { using type = uint64_t; };

    template<size_t S>
    using SizeToToTypeT = typename SizeToType<S>::type;


    Adding more types would be just adding more specializations (one-liners) here.






    share|improve this answer















    I would not use C++17 if constexpr for this, instead I'd use template specialization, as it looks more declarative to me.



    Something along the following lines:



    template<size_t S> struct SizeToType {static_assert(S != S, "Wrong size"); };

    template<> struct SizeToType<1> { using type = uint8_t; };
    template<> struct SizeToType<2> { using type = uint16_t; };
    template<> struct SizeToType<4> { using type = uint32_t; };
    template<> struct SizeToType<8> { using type = uint64_t; };

    template<size_t S>
    using SizeToToTypeT = typename SizeToType<S>::type;


    Adding more types would be just adding more specializations (one-liners) here.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 26 '18 at 20:37

























    answered Nov 26 '18 at 20:09









    SergeyASergeyA

    43.1k53886




    43.1k53886








    • 3





      The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

      – StoryTeller
      Nov 26 '18 at 20:31











    • @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

      – SergeyA
      Nov 26 '18 at 20:34






    • 3





      Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

      – StoryTeller
      Nov 26 '18 at 20:37













    • @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

      – SergeyA
      Nov 26 '18 at 20:39











    • I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

      – StoryTeller
      Nov 26 '18 at 20:43














    • 3





      The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

      – StoryTeller
      Nov 26 '18 at 20:31











    • @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

      – SergeyA
      Nov 26 '18 at 20:34






    • 3





      Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

      – StoryTeller
      Nov 26 '18 at 20:37













    • @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

      – SergeyA
      Nov 26 '18 at 20:39











    • I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

      – StoryTeller
      Nov 26 '18 at 20:43








    3




    3





    The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

    – StoryTeller
    Nov 26 '18 at 20:31





    The primary is too close to being ill-formed NDR. It might be better to simply leave it undefined.

    – StoryTeller
    Nov 26 '18 at 20:31













    @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

    – SergeyA
    Nov 26 '18 at 20:34





    @StoryTeller I wanted meaningful diagnostics. But I am not sure, why would it be NDR? (Other than the type in S == S which I am correcting right now).

    – SergeyA
    Nov 26 '18 at 20:34




    3




    3





    Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

    – StoryTeller
    Nov 26 '18 at 20:37







    Like 90% of those cases. It's [temp.res]/8. That condition is not entirely dependant. So a clever implementation might diagnose the primary outright. It's a dark corner.

    – StoryTeller
    Nov 26 '18 at 20:37















    @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

    – SergeyA
    Nov 26 '18 at 20:39





    @StoryTeller it has a bunch of cases. Can you point to the one which is violated?

    – SergeyA
    Nov 26 '18 at 20:39













    I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

    – StoryTeller
    Nov 26 '18 at 20:43





    I'm on mobile, so I can't do it easily (cxxdraft-gen is hard to navigate). I would have done it already otherwise. I like the tabular approach.

    – StoryTeller
    Nov 26 '18 at 20:43













    2














    Not a great solution... but just for fun...



    I propose a type traits (with helper and using to select the internal type) that, given a number (the number of bytes) and a list of types select the first type of the list with sizeof() greater or equal (or nothing if there is no such type)



    template <std::size_t, typename, typename = std::true_type>
    struct sizeTypeH;

    template <std::size_t Dim>
    struct sizeTypeH<Dim, std::tuple<>, std::true_type>
    { }; // no type found

    template <std::size_t Dim, typename T0, typename ... Ts>
    struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
    std::integral_constant<bool, (sizeof(T0) >= Dim)>>
    { using type = T0; };

    template <std::size_t Dim, typename T0, typename ... Ts>
    struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
    std::integral_constant<bool, (sizeof(T0) < Dim)>>
    : public sizeTypeH<Dim, std::tuple<Ts...>>
    { };

    template <std::size_t Dim, typename ... Ts>
    struct sizeType : public sizeTypeH<Dim, std::tuple<Ts...>>
    { };

    template <std::size_t Dim, typename ... Ts>
    using sizeType_t = typename sizeType<Dim, Ts...>::type;


    Now another using that, receiving a integer, call this type traits with the ordered list of intX_t types



    template <std::size_t Dim>
    using intType_t = sizeType_t<Dim, std::int8_t, std::int16_t, std::int32_t,
    std::int64_t>;


    In my platform I have that the following static_assert() are verified.



       using t8  = intType_t<1u>;
    using t16 = intType_t<2u>;
    using t32 = intType_t<4u>;
    using t64 = intType_t<8u>;

    static_assert( std::is_same<t8, std::int8_t>{}, "!" );
    static_assert( std::is_same<t16, std::int16_t>{}, "!" );
    static_assert( std::is_same<t32, std::int32_t>{}, "!" );
    static_assert( std::is_same<t64, std::int64_t>{}, "!" );


    If, tomorrow, is introduced a int128_t, you can simply add it in intType_t using definition.



    Attention, please: there is no guaranties that the preceding static_assert() are satisfied.



    First of all because the standard guaranties that a byte is at least of 8 bits; but can be more that 8 bits. If a byte is of 16 bits, from



    using t16 = intType_t<2u>;


    you get a type of 32 bits.



    Second because intX_t types are optionals.






    share|improve this answer




























      2














      Not a great solution... but just for fun...



      I propose a type traits (with helper and using to select the internal type) that, given a number (the number of bytes) and a list of types select the first type of the list with sizeof() greater or equal (or nothing if there is no such type)



      template <std::size_t, typename, typename = std::true_type>
      struct sizeTypeH;

      template <std::size_t Dim>
      struct sizeTypeH<Dim, std::tuple<>, std::true_type>
      { }; // no type found

      template <std::size_t Dim, typename T0, typename ... Ts>
      struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
      std::integral_constant<bool, (sizeof(T0) >= Dim)>>
      { using type = T0; };

      template <std::size_t Dim, typename T0, typename ... Ts>
      struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
      std::integral_constant<bool, (sizeof(T0) < Dim)>>
      : public sizeTypeH<Dim, std::tuple<Ts...>>
      { };

      template <std::size_t Dim, typename ... Ts>
      struct sizeType : public sizeTypeH<Dim, std::tuple<Ts...>>
      { };

      template <std::size_t Dim, typename ... Ts>
      using sizeType_t = typename sizeType<Dim, Ts...>::type;


      Now another using that, receiving a integer, call this type traits with the ordered list of intX_t types



      template <std::size_t Dim>
      using intType_t = sizeType_t<Dim, std::int8_t, std::int16_t, std::int32_t,
      std::int64_t>;


      In my platform I have that the following static_assert() are verified.



         using t8  = intType_t<1u>;
      using t16 = intType_t<2u>;
      using t32 = intType_t<4u>;
      using t64 = intType_t<8u>;

      static_assert( std::is_same<t8, std::int8_t>{}, "!" );
      static_assert( std::is_same<t16, std::int16_t>{}, "!" );
      static_assert( std::is_same<t32, std::int32_t>{}, "!" );
      static_assert( std::is_same<t64, std::int64_t>{}, "!" );


      If, tomorrow, is introduced a int128_t, you can simply add it in intType_t using definition.



      Attention, please: there is no guaranties that the preceding static_assert() are satisfied.



      First of all because the standard guaranties that a byte is at least of 8 bits; but can be more that 8 bits. If a byte is of 16 bits, from



      using t16 = intType_t<2u>;


      you get a type of 32 bits.



      Second because intX_t types are optionals.






      share|improve this answer


























        2












        2








        2







        Not a great solution... but just for fun...



        I propose a type traits (with helper and using to select the internal type) that, given a number (the number of bytes) and a list of types select the first type of the list with sizeof() greater or equal (or nothing if there is no such type)



        template <std::size_t, typename, typename = std::true_type>
        struct sizeTypeH;

        template <std::size_t Dim>
        struct sizeTypeH<Dim, std::tuple<>, std::true_type>
        { }; // no type found

        template <std::size_t Dim, typename T0, typename ... Ts>
        struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
        std::integral_constant<bool, (sizeof(T0) >= Dim)>>
        { using type = T0; };

        template <std::size_t Dim, typename T0, typename ... Ts>
        struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
        std::integral_constant<bool, (sizeof(T0) < Dim)>>
        : public sizeTypeH<Dim, std::tuple<Ts...>>
        { };

        template <std::size_t Dim, typename ... Ts>
        struct sizeType : public sizeTypeH<Dim, std::tuple<Ts...>>
        { };

        template <std::size_t Dim, typename ... Ts>
        using sizeType_t = typename sizeType<Dim, Ts...>::type;


        Now another using that, receiving a integer, call this type traits with the ordered list of intX_t types



        template <std::size_t Dim>
        using intType_t = sizeType_t<Dim, std::int8_t, std::int16_t, std::int32_t,
        std::int64_t>;


        In my platform I have that the following static_assert() are verified.



           using t8  = intType_t<1u>;
        using t16 = intType_t<2u>;
        using t32 = intType_t<4u>;
        using t64 = intType_t<8u>;

        static_assert( std::is_same<t8, std::int8_t>{}, "!" );
        static_assert( std::is_same<t16, std::int16_t>{}, "!" );
        static_assert( std::is_same<t32, std::int32_t>{}, "!" );
        static_assert( std::is_same<t64, std::int64_t>{}, "!" );


        If, tomorrow, is introduced a int128_t, you can simply add it in intType_t using definition.



        Attention, please: there is no guaranties that the preceding static_assert() are satisfied.



        First of all because the standard guaranties that a byte is at least of 8 bits; but can be more that 8 bits. If a byte is of 16 bits, from



        using t16 = intType_t<2u>;


        you get a type of 32 bits.



        Second because intX_t types are optionals.






        share|improve this answer













        Not a great solution... but just for fun...



        I propose a type traits (with helper and using to select the internal type) that, given a number (the number of bytes) and a list of types select the first type of the list with sizeof() greater or equal (or nothing if there is no such type)



        template <std::size_t, typename, typename = std::true_type>
        struct sizeTypeH;

        template <std::size_t Dim>
        struct sizeTypeH<Dim, std::tuple<>, std::true_type>
        { }; // no type found

        template <std::size_t Dim, typename T0, typename ... Ts>
        struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
        std::integral_constant<bool, (sizeof(T0) >= Dim)>>
        { using type = T0; };

        template <std::size_t Dim, typename T0, typename ... Ts>
        struct sizeTypeH<Dim, std::tuple<T0, Ts...>,
        std::integral_constant<bool, (sizeof(T0) < Dim)>>
        : public sizeTypeH<Dim, std::tuple<Ts...>>
        { };

        template <std::size_t Dim, typename ... Ts>
        struct sizeType : public sizeTypeH<Dim, std::tuple<Ts...>>
        { };

        template <std::size_t Dim, typename ... Ts>
        using sizeType_t = typename sizeType<Dim, Ts...>::type;


        Now another using that, receiving a integer, call this type traits with the ordered list of intX_t types



        template <std::size_t Dim>
        using intType_t = sizeType_t<Dim, std::int8_t, std::int16_t, std::int32_t,
        std::int64_t>;


        In my platform I have that the following static_assert() are verified.



           using t8  = intType_t<1u>;
        using t16 = intType_t<2u>;
        using t32 = intType_t<4u>;
        using t64 = intType_t<8u>;

        static_assert( std::is_same<t8, std::int8_t>{}, "!" );
        static_assert( std::is_same<t16, std::int16_t>{}, "!" );
        static_assert( std::is_same<t32, std::int32_t>{}, "!" );
        static_assert( std::is_same<t64, std::int64_t>{}, "!" );


        If, tomorrow, is introduced a int128_t, you can simply add it in intType_t using definition.



        Attention, please: there is no guaranties that the preceding static_assert() are satisfied.



        First of all because the standard guaranties that a byte is at least of 8 bits; but can be more that 8 bits. If a byte is of 16 bits, from



        using t16 = intType_t<2u>;


        you get a type of 32 bits.



        Second because intX_t types are optionals.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 26 '18 at 20:33









        max66max66

        36.6k74165




        36.6k74165






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53488151%2fmapping-an-integral-template-parameter-value-onto-a-primitive-type%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Contact image not getting when fetch all contact list from iPhone by CNContact

            count number of partitions of a set with n elements into k subsets

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks