std::map::size_type for a std::map whose value_type is its own size_type





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







4















I have a std::map<std::pair<std::string, std::string>, float> that is taking up too much memory, and in order to use less memory, I've decided to map the unique strings to integers (e.g., std::map<std::string, int>, where each new unique string is mapped to the current size() of the map), and use those integer value as pairwise keys to the map, (e.g., std::map<std::pair<int, int>, float>).



Instead of int, I want to use std::map::size_type:



using map_index = std::map::size_type;
std::pair<map_index, map_index> key;


Of course, this doesn't compile because I need to supply the argument list for the map:



vector.cc:14:19: error: invalid use of template-name `std::map' without an argument list
using map_index = std::map::size_type;


And this (in theory) is what I'm trying to achieve:



using map_index = std::map<std::string, map_index>::size_type;


which gives the following (expected) compiler error:



vector.cc:15:41: error: `map_index' was not declared in this scope
using map_index = std::map<std::string, map_index>::size_type;


What is the proper way to get the compiler to infer the correct value_type for a std::map whose value_type is its own size_type?










share|improve this question

























  • minor nitpick: I think you have the last sentence the wrong way around. To know what is size_type you first need to tell what is the value_type not the other way around. Once you know the type of the map, getting its size_type is trivial

    – user463035818
    Nov 22 '18 at 12:44













  • @user463035818 The problem seems to be that the size_type is a part of value_type for the OP.

    – Some programmer dude
    Nov 22 '18 at 12:46






  • 5





    You have a circular dependency. Why can't you use size_t (which is what size_type normally will be anyway)?

    – Some programmer dude
    Nov 22 '18 at 12:47











  • can you explain why you want that? afaik map::size_type is just a typedef aliasing always the same type anyhow

    – user463035818
    Nov 22 '18 at 12:47








  • 3





    std::map<K, V>::size_type is most likely completely independent of both K and V. If you really care, you can static_assert(std::is_same_v<Map::size_type, Map::mapped_type>, "Unexpected size_type")

    – Caleth
    Nov 22 '18 at 12:59


















4















I have a std::map<std::pair<std::string, std::string>, float> that is taking up too much memory, and in order to use less memory, I've decided to map the unique strings to integers (e.g., std::map<std::string, int>, where each new unique string is mapped to the current size() of the map), and use those integer value as pairwise keys to the map, (e.g., std::map<std::pair<int, int>, float>).



Instead of int, I want to use std::map::size_type:



using map_index = std::map::size_type;
std::pair<map_index, map_index> key;


Of course, this doesn't compile because I need to supply the argument list for the map:



vector.cc:14:19: error: invalid use of template-name `std::map' without an argument list
using map_index = std::map::size_type;


And this (in theory) is what I'm trying to achieve:



using map_index = std::map<std::string, map_index>::size_type;


which gives the following (expected) compiler error:



vector.cc:15:41: error: `map_index' was not declared in this scope
using map_index = std::map<std::string, map_index>::size_type;


What is the proper way to get the compiler to infer the correct value_type for a std::map whose value_type is its own size_type?










share|improve this question

























  • minor nitpick: I think you have the last sentence the wrong way around. To know what is size_type you first need to tell what is the value_type not the other way around. Once you know the type of the map, getting its size_type is trivial

    – user463035818
    Nov 22 '18 at 12:44













  • @user463035818 The problem seems to be that the size_type is a part of value_type for the OP.

    – Some programmer dude
    Nov 22 '18 at 12:46






  • 5





    You have a circular dependency. Why can't you use size_t (which is what size_type normally will be anyway)?

    – Some programmer dude
    Nov 22 '18 at 12:47











  • can you explain why you want that? afaik map::size_type is just a typedef aliasing always the same type anyhow

    – user463035818
    Nov 22 '18 at 12:47








  • 3





    std::map<K, V>::size_type is most likely completely independent of both K and V. If you really care, you can static_assert(std::is_same_v<Map::size_type, Map::mapped_type>, "Unexpected size_type")

    – Caleth
    Nov 22 '18 at 12:59














4












4








4


2






I have a std::map<std::pair<std::string, std::string>, float> that is taking up too much memory, and in order to use less memory, I've decided to map the unique strings to integers (e.g., std::map<std::string, int>, where each new unique string is mapped to the current size() of the map), and use those integer value as pairwise keys to the map, (e.g., std::map<std::pair<int, int>, float>).



Instead of int, I want to use std::map::size_type:



using map_index = std::map::size_type;
std::pair<map_index, map_index> key;


Of course, this doesn't compile because I need to supply the argument list for the map:



vector.cc:14:19: error: invalid use of template-name `std::map' without an argument list
using map_index = std::map::size_type;


And this (in theory) is what I'm trying to achieve:



using map_index = std::map<std::string, map_index>::size_type;


which gives the following (expected) compiler error:



vector.cc:15:41: error: `map_index' was not declared in this scope
using map_index = std::map<std::string, map_index>::size_type;


What is the proper way to get the compiler to infer the correct value_type for a std::map whose value_type is its own size_type?










share|improve this question
















I have a std::map<std::pair<std::string, std::string>, float> that is taking up too much memory, and in order to use less memory, I've decided to map the unique strings to integers (e.g., std::map<std::string, int>, where each new unique string is mapped to the current size() of the map), and use those integer value as pairwise keys to the map, (e.g., std::map<std::pair<int, int>, float>).



Instead of int, I want to use std::map::size_type:



using map_index = std::map::size_type;
std::pair<map_index, map_index> key;


Of course, this doesn't compile because I need to supply the argument list for the map:



vector.cc:14:19: error: invalid use of template-name `std::map' without an argument list
using map_index = std::map::size_type;


And this (in theory) is what I'm trying to achieve:



using map_index = std::map<std::string, map_index>::size_type;


which gives the following (expected) compiler error:



vector.cc:15:41: error: `map_index' was not declared in this scope
using map_index = std::map<std::string, map_index>::size_type;


What is the proper way to get the compiler to infer the correct value_type for a std::map whose value_type is its own size_type?







c++ c++11 stl stdmap size-type






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 13:53







vallismortis

















asked Nov 22 '18 at 12:41









vallismortisvallismortis

3,743104366




3,743104366













  • minor nitpick: I think you have the last sentence the wrong way around. To know what is size_type you first need to tell what is the value_type not the other way around. Once you know the type of the map, getting its size_type is trivial

    – user463035818
    Nov 22 '18 at 12:44













  • @user463035818 The problem seems to be that the size_type is a part of value_type for the OP.

    – Some programmer dude
    Nov 22 '18 at 12:46






  • 5





    You have a circular dependency. Why can't you use size_t (which is what size_type normally will be anyway)?

    – Some programmer dude
    Nov 22 '18 at 12:47











  • can you explain why you want that? afaik map::size_type is just a typedef aliasing always the same type anyhow

    – user463035818
    Nov 22 '18 at 12:47








  • 3





    std::map<K, V>::size_type is most likely completely independent of both K and V. If you really care, you can static_assert(std::is_same_v<Map::size_type, Map::mapped_type>, "Unexpected size_type")

    – Caleth
    Nov 22 '18 at 12:59



















  • minor nitpick: I think you have the last sentence the wrong way around. To know what is size_type you first need to tell what is the value_type not the other way around. Once you know the type of the map, getting its size_type is trivial

    – user463035818
    Nov 22 '18 at 12:44













  • @user463035818 The problem seems to be that the size_type is a part of value_type for the OP.

    – Some programmer dude
    Nov 22 '18 at 12:46






  • 5





    You have a circular dependency. Why can't you use size_t (which is what size_type normally will be anyway)?

    – Some programmer dude
    Nov 22 '18 at 12:47











  • can you explain why you want that? afaik map::size_type is just a typedef aliasing always the same type anyhow

    – user463035818
    Nov 22 '18 at 12:47








  • 3





    std::map<K, V>::size_type is most likely completely independent of both K and V. If you really care, you can static_assert(std::is_same_v<Map::size_type, Map::mapped_type>, "Unexpected size_type")

    – Caleth
    Nov 22 '18 at 12:59

















minor nitpick: I think you have the last sentence the wrong way around. To know what is size_type you first need to tell what is the value_type not the other way around. Once you know the type of the map, getting its size_type is trivial

– user463035818
Nov 22 '18 at 12:44







minor nitpick: I think you have the last sentence the wrong way around. To know what is size_type you first need to tell what is the value_type not the other way around. Once you know the type of the map, getting its size_type is trivial

– user463035818
Nov 22 '18 at 12:44















@user463035818 The problem seems to be that the size_type is a part of value_type for the OP.

– Some programmer dude
Nov 22 '18 at 12:46





@user463035818 The problem seems to be that the size_type is a part of value_type for the OP.

– Some programmer dude
Nov 22 '18 at 12:46




5




5





You have a circular dependency. Why can't you use size_t (which is what size_type normally will be anyway)?

– Some programmer dude
Nov 22 '18 at 12:47





You have a circular dependency. Why can't you use size_t (which is what size_type normally will be anyway)?

– Some programmer dude
Nov 22 '18 at 12:47













can you explain why you want that? afaik map::size_type is just a typedef aliasing always the same type anyhow

– user463035818
Nov 22 '18 at 12:47







can you explain why you want that? afaik map::size_type is just a typedef aliasing always the same type anyhow

– user463035818
Nov 22 '18 at 12:47






3




3





std::map<K, V>::size_type is most likely completely independent of both K and V. If you really care, you can static_assert(std::is_same_v<Map::size_type, Map::mapped_type>, "Unexpected size_type")

– Caleth
Nov 22 '18 at 12:59





std::map<K, V>::size_type is most likely completely independent of both K and V. If you really care, you can static_assert(std::is_same_v<Map::size_type, Map::mapped_type>, "Unexpected size_type")

– Caleth
Nov 22 '18 at 12:59












7 Answers
7






active

oldest

votes


















1














What you are looking for is, generally speaking, impossible.



It's conceivable (though far-fetched) that std::map<int, long>::size_type is int and std::map<int, int>::size_type is long (and similarly for other integer types), in which case there is no possible way to satisfy std::map<int, T>::size_type being T.



Conversely, it could be that std::map<int, T>::size_type is defined as T for all T, in which case there is no unique T satisfying your "requirement".



As mentioned by several answers (and your own reference link), in practice it's unlikely to be anything else than size_t.






share|improve this answer
























  • This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

    – vallismortis
    Nov 22 '18 at 13:27



















5














size_t should be good enough for such case.



But if you insist, you can do like this:



#include <type_traits>
#include <map>

template <class Key, class Value = size_t, size_t depth = 0, class = void>
struct GetSizeType {
using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
};

template <class Key, class Value, size_t depth>
struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
using type = typename std::map<Key, Value>::size_type;
};

template <class Key, class Value>
struct GetSizeType<Key, Value, 100, void> {};

int main() {
using X = GetSizeType<int>::type;

return 0;
}


It will run recursively on GetSizeType, the recursive call will stop upon




  • reaching the recursive call depth limitation (there will be no member type in this case), or

  • finding a specialization of std::map of which the mapped_type and size_type is identical (the member type aliases size_type).






share|improve this answer


























  • Technical thug approach of the first order - brilliant!

    – Toby Speight
    Nov 22 '18 at 13:02






  • 1





    i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

    – user463035818
    Nov 22 '18 at 13:06






  • 2





    @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

    – felix
    Nov 22 '18 at 13:07






  • 1





    @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

    – Toby Speight
    Nov 22 '18 at 13:08








  • 1





    @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

    – Acorn
    Nov 22 '18 at 13:22





















4














Disclaimer: this solution is pretty dumb. We're just going to solve the equation by repeatedly (typically once) trying to instantiate std::map until we find one that has the requested key and its own size_type as value.



template <class T>
struct identity {
using type = T;
};

template <class K, class V = char>
struct auto_map {
using map_type = std::map<K, V>;
using type = typename std::conditional_t<
std::is_same_v<
typename map_type::mapped_type,
typename map_type::size_type
>,
identity<map_type>,
auto_map<K, typename map_type::size_type>
>::type;
};

template <class K>
using auto_map_t = typename auto_map<K>::type;


If the metafunction can't find such a map, it will either error out because type ends up defined to itself, or break the recursion limit.






share|improve this answer
























  • Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

    – Acorn
    Nov 22 '18 at 13:24











  • @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

    – Quentin
    Nov 22 '18 at 13:27






  • 1





    @Quentin same here, cheers.

    – felix
    Nov 22 '18 at 13:31



















2














Use std::size_t. The unsigned integer std::map::size_type won't be bigger than std::size_t and will, in practice, be the same type.



If you want to be sure, assert it:



static_assert(std::is_same_v<
std::size_t,
std::map<std::string, std::size_t>::size_type
>);





share|improve this answer































    2














    All C++ implementations in the wild I have used use the same size type for all maps.



    So;



    using map_size_type = std::map<int, int>::size_type;
    using my_map = std::map<std::string, map_size_type>;
    static_assert(std::is_same<map_size_type, my_map::size_type);


    this just forces a compilation error if the (reasonable) assumption fails.






    share|improve this answer


























    • I'm linking another question here because your answer seems relevant to it as well.

      – vallismortis
      Nov 22 '18 at 13:44



















    1














    The only way to break the circular dependency is to use a specific type. I recommend that you simply make map_index be a std::size_t - C++ strongly implies that a std::size_t will be assignable to the map::size_type.






    share|improve this answer































      1














      But are you sure that the size_type of a std::map depends from the key/value types?



      If so, I don't see a way to get it.



      But the size_type shouldn't depends from key/value types and usually is std::size_t.



      I suggest



      using Index0 = typename std::map<std::string, std::size_t>::size_type;

      using mapIndex = typename std::map<std::string, Index0>::size_type;


      You can check you've gotten the right type with



      static_assert( std::is_same_v<Index0, mapIndex>, "no right type");





      share|improve this answer





















      • 1





        The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

        – Toby Speight
        Nov 22 '18 at 12:53











      • @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

        – vallismortis
        Nov 22 '18 at 12:59








      • 1





        @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

        – max66
        Nov 22 '18 at 13:04






      • 1





        @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

        – max66
        Nov 22 '18 at 13:06












      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%2f53431281%2fstdmapsize-type-for-a-stdmap-whose-value-type-is-its-own-size-type%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      What you are looking for is, generally speaking, impossible.



      It's conceivable (though far-fetched) that std::map<int, long>::size_type is int and std::map<int, int>::size_type is long (and similarly for other integer types), in which case there is no possible way to satisfy std::map<int, T>::size_type being T.



      Conversely, it could be that std::map<int, T>::size_type is defined as T for all T, in which case there is no unique T satisfying your "requirement".



      As mentioned by several answers (and your own reference link), in practice it's unlikely to be anything else than size_t.






      share|improve this answer
























      • This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

        – vallismortis
        Nov 22 '18 at 13:27
















      1














      What you are looking for is, generally speaking, impossible.



      It's conceivable (though far-fetched) that std::map<int, long>::size_type is int and std::map<int, int>::size_type is long (and similarly for other integer types), in which case there is no possible way to satisfy std::map<int, T>::size_type being T.



      Conversely, it could be that std::map<int, T>::size_type is defined as T for all T, in which case there is no unique T satisfying your "requirement".



      As mentioned by several answers (and your own reference link), in practice it's unlikely to be anything else than size_t.






      share|improve this answer
























      • This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

        – vallismortis
        Nov 22 '18 at 13:27














      1












      1








      1







      What you are looking for is, generally speaking, impossible.



      It's conceivable (though far-fetched) that std::map<int, long>::size_type is int and std::map<int, int>::size_type is long (and similarly for other integer types), in which case there is no possible way to satisfy std::map<int, T>::size_type being T.



      Conversely, it could be that std::map<int, T>::size_type is defined as T for all T, in which case there is no unique T satisfying your "requirement".



      As mentioned by several answers (and your own reference link), in practice it's unlikely to be anything else than size_t.






      share|improve this answer













      What you are looking for is, generally speaking, impossible.



      It's conceivable (though far-fetched) that std::map<int, long>::size_type is int and std::map<int, int>::size_type is long (and similarly for other integer types), in which case there is no possible way to satisfy std::map<int, T>::size_type being T.



      Conversely, it could be that std::map<int, T>::size_type is defined as T for all T, in which case there is no unique T satisfying your "requirement".



      As mentioned by several answers (and your own reference link), in practice it's unlikely to be anything else than size_t.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 22 '18 at 13:24









      Max LanghofMax Langhof

      12.3k22241




      12.3k22241













      • This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

        – vallismortis
        Nov 22 '18 at 13:27



















      • This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

        – vallismortis
        Nov 22 '18 at 13:27

















      This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

      – vallismortis
      Nov 22 '18 at 13:27





      This is the answer I was looking for, it just isn't the one I was hoping for. The specific examples you provide illustrate the problem perfectly.

      – vallismortis
      Nov 22 '18 at 13:27













      5














      size_t should be good enough for such case.



      But if you insist, you can do like this:



      #include <type_traits>
      #include <map>

      template <class Key, class Value = size_t, size_t depth = 0, class = void>
      struct GetSizeType {
      using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
      };

      template <class Key, class Value, size_t depth>
      struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
      using type = typename std::map<Key, Value>::size_type;
      };

      template <class Key, class Value>
      struct GetSizeType<Key, Value, 100, void> {};

      int main() {
      using X = GetSizeType<int>::type;

      return 0;
      }


      It will run recursively on GetSizeType, the recursive call will stop upon




      • reaching the recursive call depth limitation (there will be no member type in this case), or

      • finding a specialization of std::map of which the mapped_type and size_type is identical (the member type aliases size_type).






      share|improve this answer


























      • Technical thug approach of the first order - brilliant!

        – Toby Speight
        Nov 22 '18 at 13:02






      • 1





        i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

        – user463035818
        Nov 22 '18 at 13:06






      • 2





        @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

        – felix
        Nov 22 '18 at 13:07






      • 1





        @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

        – Toby Speight
        Nov 22 '18 at 13:08








      • 1





        @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

        – Acorn
        Nov 22 '18 at 13:22


















      5














      size_t should be good enough for such case.



      But if you insist, you can do like this:



      #include <type_traits>
      #include <map>

      template <class Key, class Value = size_t, size_t depth = 0, class = void>
      struct GetSizeType {
      using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
      };

      template <class Key, class Value, size_t depth>
      struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
      using type = typename std::map<Key, Value>::size_type;
      };

      template <class Key, class Value>
      struct GetSizeType<Key, Value, 100, void> {};

      int main() {
      using X = GetSizeType<int>::type;

      return 0;
      }


      It will run recursively on GetSizeType, the recursive call will stop upon




      • reaching the recursive call depth limitation (there will be no member type in this case), or

      • finding a specialization of std::map of which the mapped_type and size_type is identical (the member type aliases size_type).






      share|improve this answer


























      • Technical thug approach of the first order - brilliant!

        – Toby Speight
        Nov 22 '18 at 13:02






      • 1





        i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

        – user463035818
        Nov 22 '18 at 13:06






      • 2





        @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

        – felix
        Nov 22 '18 at 13:07






      • 1





        @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

        – Toby Speight
        Nov 22 '18 at 13:08








      • 1





        @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

        – Acorn
        Nov 22 '18 at 13:22
















      5












      5








      5







      size_t should be good enough for such case.



      But if you insist, you can do like this:



      #include <type_traits>
      #include <map>

      template <class Key, class Value = size_t, size_t depth = 0, class = void>
      struct GetSizeType {
      using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
      };

      template <class Key, class Value, size_t depth>
      struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
      using type = typename std::map<Key, Value>::size_type;
      };

      template <class Key, class Value>
      struct GetSizeType<Key, Value, 100, void> {};

      int main() {
      using X = GetSizeType<int>::type;

      return 0;
      }


      It will run recursively on GetSizeType, the recursive call will stop upon




      • reaching the recursive call depth limitation (there will be no member type in this case), or

      • finding a specialization of std::map of which the mapped_type and size_type is identical (the member type aliases size_type).






      share|improve this answer















      size_t should be good enough for such case.



      But if you insist, you can do like this:



      #include <type_traits>
      #include <map>

      template <class Key, class Value = size_t, size_t depth = 0, class = void>
      struct GetSizeType {
      using type = typename GetSizeType<Key, typename std::map<Key, Value>::size_type, depth + 1>::type;
      };

      template <class Key, class Value, size_t depth>
      struct GetSizeType<Key, Value, depth, std::enable_if_t<std::is_same_v<Value, typename std::map<Key, Value>::size_type>>> {
      using type = typename std::map<Key, Value>::size_type;
      };

      template <class Key, class Value>
      struct GetSizeType<Key, Value, 100, void> {};

      int main() {
      using X = GetSizeType<int>::type;

      return 0;
      }


      It will run recursively on GetSizeType, the recursive call will stop upon




      • reaching the recursive call depth limitation (there will be no member type in this case), or

      • finding a specialization of std::map of which the mapped_type and size_type is identical (the member type aliases size_type).







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 22 '18 at 15:28

























      answered Nov 22 '18 at 13:01









      felixfelix

      1,510314




      1,510314













      • Technical thug approach of the first order - brilliant!

        – Toby Speight
        Nov 22 '18 at 13:02






      • 1





        i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

        – user463035818
        Nov 22 '18 at 13:06






      • 2





        @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

        – felix
        Nov 22 '18 at 13:07






      • 1





        @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

        – Toby Speight
        Nov 22 '18 at 13:08








      • 1





        @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

        – Acorn
        Nov 22 '18 at 13:22





















      • Technical thug approach of the first order - brilliant!

        – Toby Speight
        Nov 22 '18 at 13:02






      • 1





        i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

        – user463035818
        Nov 22 '18 at 13:06






      • 2





        @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

        – felix
        Nov 22 '18 at 13:07






      • 1





        @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

        – Toby Speight
        Nov 22 '18 at 13:08








      • 1





        @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

        – Acorn
        Nov 22 '18 at 13:22



















      Technical thug approach of the first order - brilliant!

      – Toby Speight
      Nov 22 '18 at 13:02





      Technical thug approach of the first order - brilliant!

      – Toby Speight
      Nov 22 '18 at 13:02




      1




      1





      i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

      – user463035818
      Nov 22 '18 at 13:06





      i dont completely agree with " You will run out of memory before running out of size_t.". Something like my_map.size() * 2; is a sensible operation that can overflow long before you run out of memory

      – user463035818
      Nov 22 '18 at 13:06




      2




      2





      @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

      – felix
      Nov 22 '18 at 13:07





      @user463035818 Thanks, I have removed that part. I wrongly simplified the usage.

      – felix
      Nov 22 '18 at 13:07




      1




      1





      @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

      – Toby Speight
      Nov 22 '18 at 13:08







      @user463035818 - in the context set by the question, there's no arithmetic involved - the result of size() is simply being used as an opaque identifier.

      – Toby Speight
      Nov 22 '18 at 13:08






      1




      1





      @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

      – Acorn
      Nov 22 '18 at 13:22







      @vallismortis What do you mean by "more extreme cases"? If you use std::size_t, there is no way it won't work where another type would, because that should be able to address even objects of size 1.

      – Acorn
      Nov 22 '18 at 13:22













      4














      Disclaimer: this solution is pretty dumb. We're just going to solve the equation by repeatedly (typically once) trying to instantiate std::map until we find one that has the requested key and its own size_type as value.



      template <class T>
      struct identity {
      using type = T;
      };

      template <class K, class V = char>
      struct auto_map {
      using map_type = std::map<K, V>;
      using type = typename std::conditional_t<
      std::is_same_v<
      typename map_type::mapped_type,
      typename map_type::size_type
      >,
      identity<map_type>,
      auto_map<K, typename map_type::size_type>
      >::type;
      };

      template <class K>
      using auto_map_t = typename auto_map<K>::type;


      If the metafunction can't find such a map, it will either error out because type ends up defined to itself, or break the recursion limit.






      share|improve this answer
























      • Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

        – Acorn
        Nov 22 '18 at 13:24











      • @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

        – Quentin
        Nov 22 '18 at 13:27






      • 1





        @Quentin same here, cheers.

        – felix
        Nov 22 '18 at 13:31
















      4














      Disclaimer: this solution is pretty dumb. We're just going to solve the equation by repeatedly (typically once) trying to instantiate std::map until we find one that has the requested key and its own size_type as value.



      template <class T>
      struct identity {
      using type = T;
      };

      template <class K, class V = char>
      struct auto_map {
      using map_type = std::map<K, V>;
      using type = typename std::conditional_t<
      std::is_same_v<
      typename map_type::mapped_type,
      typename map_type::size_type
      >,
      identity<map_type>,
      auto_map<K, typename map_type::size_type>
      >::type;
      };

      template <class K>
      using auto_map_t = typename auto_map<K>::type;


      If the metafunction can't find such a map, it will either error out because type ends up defined to itself, or break the recursion limit.






      share|improve this answer
























      • Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

        – Acorn
        Nov 22 '18 at 13:24











      • @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

        – Quentin
        Nov 22 '18 at 13:27






      • 1





        @Quentin same here, cheers.

        – felix
        Nov 22 '18 at 13:31














      4












      4








      4







      Disclaimer: this solution is pretty dumb. We're just going to solve the equation by repeatedly (typically once) trying to instantiate std::map until we find one that has the requested key and its own size_type as value.



      template <class T>
      struct identity {
      using type = T;
      };

      template <class K, class V = char>
      struct auto_map {
      using map_type = std::map<K, V>;
      using type = typename std::conditional_t<
      std::is_same_v<
      typename map_type::mapped_type,
      typename map_type::size_type
      >,
      identity<map_type>,
      auto_map<K, typename map_type::size_type>
      >::type;
      };

      template <class K>
      using auto_map_t = typename auto_map<K>::type;


      If the metafunction can't find such a map, it will either error out because type ends up defined to itself, or break the recursion limit.






      share|improve this answer













      Disclaimer: this solution is pretty dumb. We're just going to solve the equation by repeatedly (typically once) trying to instantiate std::map until we find one that has the requested key and its own size_type as value.



      template <class T>
      struct identity {
      using type = T;
      };

      template <class K, class V = char>
      struct auto_map {
      using map_type = std::map<K, V>;
      using type = typename std::conditional_t<
      std::is_same_v<
      typename map_type::mapped_type,
      typename map_type::size_type
      >,
      identity<map_type>,
      auto_map<K, typename map_type::size_type>
      >::type;
      };

      template <class K>
      using auto_map_t = typename auto_map<K>::type;


      If the metafunction can't find such a map, it will either error out because type ends up defined to itself, or break the recursion limit.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Nov 22 '18 at 13:02









      QuentinQuentin

      47.1k692148




      47.1k692148













      • Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

        – Acorn
        Nov 22 '18 at 13:24











      • @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

        – Quentin
        Nov 22 '18 at 13:27






      • 1





        @Quentin same here, cheers.

        – felix
        Nov 22 '18 at 13:31



















      • Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

        – Acorn
        Nov 22 '18 at 13:24











      • @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

        – Quentin
        Nov 22 '18 at 13:27






      • 1





        @Quentin same here, cheers.

        – felix
        Nov 22 '18 at 13:31

















      Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

      – Acorn
      Nov 22 '18 at 13:24





      Both recursive solutions shown are cool, but I am unsure why one would use this. It still does not guarantee you will find one that works in a broken environment, as you say, so it is cleaner and faster to compile to simply pick one and assert the condition we actually need, no?

      – Acorn
      Nov 22 '18 at 13:24













      @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

      – Quentin
      Nov 22 '18 at 13:27





      @Acorn yes. I just needed something to do while I'm doing a full rebuild ;)

      – Quentin
      Nov 22 '18 at 13:27




      1




      1





      @Quentin same here, cheers.

      – felix
      Nov 22 '18 at 13:31





      @Quentin same here, cheers.

      – felix
      Nov 22 '18 at 13:31











      2














      Use std::size_t. The unsigned integer std::map::size_type won't be bigger than std::size_t and will, in practice, be the same type.



      If you want to be sure, assert it:



      static_assert(std::is_same_v<
      std::size_t,
      std::map<std::string, std::size_t>::size_type
      >);





      share|improve this answer




























        2














        Use std::size_t. The unsigned integer std::map::size_type won't be bigger than std::size_t and will, in practice, be the same type.



        If you want to be sure, assert it:



        static_assert(std::is_same_v<
        std::size_t,
        std::map<std::string, std::size_t>::size_type
        >);





        share|improve this answer


























          2












          2








          2







          Use std::size_t. The unsigned integer std::map::size_type won't be bigger than std::size_t and will, in practice, be the same type.



          If you want to be sure, assert it:



          static_assert(std::is_same_v<
          std::size_t,
          std::map<std::string, std::size_t>::size_type
          >);





          share|improve this answer













          Use std::size_t. The unsigned integer std::map::size_type won't be bigger than std::size_t and will, in practice, be the same type.



          If you want to be sure, assert it:



          static_assert(std::is_same_v<
          std::size_t,
          std::map<std::string, std::size_t>::size_type
          >);






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 22 '18 at 13:04









          AcornAcorn

          6,71411442




          6,71411442























              2














              All C++ implementations in the wild I have used use the same size type for all maps.



              So;



              using map_size_type = std::map<int, int>::size_type;
              using my_map = std::map<std::string, map_size_type>;
              static_assert(std::is_same<map_size_type, my_map::size_type);


              this just forces a compilation error if the (reasonable) assumption fails.






              share|improve this answer


























              • I'm linking another question here because your answer seems relevant to it as well.

                – vallismortis
                Nov 22 '18 at 13:44
















              2














              All C++ implementations in the wild I have used use the same size type for all maps.



              So;



              using map_size_type = std::map<int, int>::size_type;
              using my_map = std::map<std::string, map_size_type>;
              static_assert(std::is_same<map_size_type, my_map::size_type);


              this just forces a compilation error if the (reasonable) assumption fails.






              share|improve this answer


























              • I'm linking another question here because your answer seems relevant to it as well.

                – vallismortis
                Nov 22 '18 at 13:44














              2












              2








              2







              All C++ implementations in the wild I have used use the same size type for all maps.



              So;



              using map_size_type = std::map<int, int>::size_type;
              using my_map = std::map<std::string, map_size_type>;
              static_assert(std::is_same<map_size_type, my_map::size_type);


              this just forces a compilation error if the (reasonable) assumption fails.






              share|improve this answer















              All C++ implementations in the wild I have used use the same size type for all maps.



              So;



              using map_size_type = std::map<int, int>::size_type;
              using my_map = std::map<std::string, map_size_type>;
              static_assert(std::is_same<map_size_type, my_map::size_type);


              this just forces a compilation error if the (reasonable) assumption fails.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 22 '18 at 13:45









              vallismortis

              3,743104366




              3,743104366










              answered Nov 22 '18 at 13:33









              Yakk - Adam NevraumontYakk - Adam Nevraumont

              190k21200385




              190k21200385













              • I'm linking another question here because your answer seems relevant to it as well.

                – vallismortis
                Nov 22 '18 at 13:44



















              • I'm linking another question here because your answer seems relevant to it as well.

                – vallismortis
                Nov 22 '18 at 13:44

















              I'm linking another question here because your answer seems relevant to it as well.

              – vallismortis
              Nov 22 '18 at 13:44





              I'm linking another question here because your answer seems relevant to it as well.

              – vallismortis
              Nov 22 '18 at 13:44











              1














              The only way to break the circular dependency is to use a specific type. I recommend that you simply make map_index be a std::size_t - C++ strongly implies that a std::size_t will be assignable to the map::size_type.






              share|improve this answer




























                1














                The only way to break the circular dependency is to use a specific type. I recommend that you simply make map_index be a std::size_t - C++ strongly implies that a std::size_t will be assignable to the map::size_type.






                share|improve this answer


























                  1












                  1








                  1







                  The only way to break the circular dependency is to use a specific type. I recommend that you simply make map_index be a std::size_t - C++ strongly implies that a std::size_t will be assignable to the map::size_type.






                  share|improve this answer













                  The only way to break the circular dependency is to use a specific type. I recommend that you simply make map_index be a std::size_t - C++ strongly implies that a std::size_t will be assignable to the map::size_type.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 22 '18 at 13:00









                  Toby SpeightToby Speight

                  17.6k134469




                  17.6k134469























                      1














                      But are you sure that the size_type of a std::map depends from the key/value types?



                      If so, I don't see a way to get it.



                      But the size_type shouldn't depends from key/value types and usually is std::size_t.



                      I suggest



                      using Index0 = typename std::map<std::string, std::size_t>::size_type;

                      using mapIndex = typename std::map<std::string, Index0>::size_type;


                      You can check you've gotten the right type with



                      static_assert( std::is_same_v<Index0, mapIndex>, "no right type");





                      share|improve this answer





















                      • 1





                        The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

                        – Toby Speight
                        Nov 22 '18 at 12:53











                      • @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

                        – vallismortis
                        Nov 22 '18 at 12:59








                      • 1





                        @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

                        – max66
                        Nov 22 '18 at 13:04






                      • 1





                        @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

                        – max66
                        Nov 22 '18 at 13:06
















                      1














                      But are you sure that the size_type of a std::map depends from the key/value types?



                      If so, I don't see a way to get it.



                      But the size_type shouldn't depends from key/value types and usually is std::size_t.



                      I suggest



                      using Index0 = typename std::map<std::string, std::size_t>::size_type;

                      using mapIndex = typename std::map<std::string, Index0>::size_type;


                      You can check you've gotten the right type with



                      static_assert( std::is_same_v<Index0, mapIndex>, "no right type");





                      share|improve this answer





















                      • 1





                        The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

                        – Toby Speight
                        Nov 22 '18 at 12:53











                      • @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

                        – vallismortis
                        Nov 22 '18 at 12:59








                      • 1





                        @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

                        – max66
                        Nov 22 '18 at 13:04






                      • 1





                        @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

                        – max66
                        Nov 22 '18 at 13:06














                      1












                      1








                      1







                      But are you sure that the size_type of a std::map depends from the key/value types?



                      If so, I don't see a way to get it.



                      But the size_type shouldn't depends from key/value types and usually is std::size_t.



                      I suggest



                      using Index0 = typename std::map<std::string, std::size_t>::size_type;

                      using mapIndex = typename std::map<std::string, Index0>::size_type;


                      You can check you've gotten the right type with



                      static_assert( std::is_same_v<Index0, mapIndex>, "no right type");





                      share|improve this answer















                      But are you sure that the size_type of a std::map depends from the key/value types?



                      If so, I don't see a way to get it.



                      But the size_type shouldn't depends from key/value types and usually is std::size_t.



                      I suggest



                      using Index0 = typename std::map<std::string, std::size_t>::size_type;

                      using mapIndex = typename std::map<std::string, Index0>::size_type;


                      You can check you've gotten the right type with



                      static_assert( std::is_same_v<Index0, mapIndex>, "no right type");






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 22 '18 at 13:10

























                      answered Nov 22 '18 at 12:49









                      max66max66

                      39.6k74575




                      39.6k74575








                      • 1





                        The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

                        – Toby Speight
                        Nov 22 '18 at 12:53











                      • @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

                        – vallismortis
                        Nov 22 '18 at 12:59








                      • 1





                        @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

                        – max66
                        Nov 22 '18 at 13:04






                      • 1





                        @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

                        – max66
                        Nov 22 '18 at 13:06














                      • 1





                        The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

                        – Toby Speight
                        Nov 22 '18 at 12:53











                      • @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

                        – vallismortis
                        Nov 22 '18 at 12:59








                      • 1





                        @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

                        – max66
                        Nov 22 '18 at 13:04






                      • 1





                        @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

                        – max66
                        Nov 22 '18 at 13:06








                      1




                      1





                      The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

                      – Toby Speight
                      Nov 22 '18 at 12:53





                      The compiler has no way to know that the map's size type is always the same - as far as it's concerned, there could legitimately be a specialization that's different.

                      – Toby Speight
                      Nov 22 '18 at 12:53













                      @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

                      – vallismortis
                      Nov 22 '18 at 12:59







                      @TobySpeight Yes, that is exactly what prompted me to ask this question. It is that "usually the same as size_t" clause from the C++ map documentation that really got me thinking about this.

                      – vallismortis
                      Nov 22 '18 at 12:59






                      1




                      1





                      @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

                      – max66
                      Nov 22 '18 at 13:04





                      @vallismortis - from theoretical point of view, you're right (as far I know). I don't see a way to break the circular dependency but adding static_assert( std::is_same_v<Index0, mapIndex>, "no right type"); you can check that the selected type is the right one.

                      – max66
                      Nov 22 '18 at 13:04




                      1




                      1





                      @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

                      – max66
                      Nov 22 '18 at 13:06





                      @TobySpeight - you're right (as far I know); but through a static_assert() (see my modified answer) we can check if we have gotten the right type.

                      – max66
                      Nov 22 '18 at 13:06


















                      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%2f53431281%2fstdmapsize-type-for-a-stdmap-whose-value-type-is-its-own-size-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

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)