title: Determine number of bits in integral type at compile time
body: <p><strong>NOTE:</strong> I added a similar but greatly simplified version of the problem at <a href="https://stackoverflow.com/questions/10579544/ambiguous-overload-of-functions-like-msglong-with-candidates-msgint32-t">Ambiguous overload of functions like `msg(long)` with candidates `msg(int32_t)` and `msg(int64_t)`</a>. That version has the advantage of a complete compilable example in a single file.</p>
  
  <h1>Problem</h1>
  
  <p>I have a C library with functions like</p>
  
  <pre><code>obj_from_int32(int32_t&amp; i);
  obj_from_int64(int64_t&amp; i);
  obj_from_uint32(uint32_t&amp; i);
  obj_from_uint64(uint64_t&amp; i);
  </code></pre>
  
  <p>In this case the types <code>int32_t</code> etc are <em>not</em> the <code>std</code> ones - they are implementation defined, in this case an array of chars (in the following example I've omitted the conversion - it doesn't change the question which is about mapping intergral types to a particular function based on the number of bits in the integral type).</p>
  
  <p>I have a second C++ interface class, that has constructors like</p>
  
  <pre><code>MyClass(int z);
  MyClass(long z);
  MyClass(long long z);
  MyClass(unsigned int z);
  MyClass(unsigned long z);
  MyClass(unsigned long long z);
  </code></pre>
  
  <p>Note, I can't replace this interface with <code>std::int32_t</code> style types - if I could I wouldn't need to ask this question ;)</p>
  
  <p>The problem is how to call the correct <code>obj_from_</code> function based on the number of bits in the integral type. </p>
  
  <h1>Proposed Solutions</h1>
  
  <p>I'm putting two proposed solutions, since no killer solution has floated to the top of the list, and there are a few that are broken.</p>
  
  <h2>Solution 1</h2>
  
  <p>Provided by <a href="https://stackoverflow.com/users/464581/cheers-and-hth-alf">Cheers and hth. - Alf</a>. Comments from this point on are my own - feel free to comment and/or edit.</p>
  
  <p><em>Advantages</em>
   - Fairly simple (at least compared to <code>boost::enable_if</code>)
   - Doesn't rely on 3rd party library (as long as compiler supports <code>tr1</code>)</p>
  
  <p>*Disadvantages**
   - If more functions (like <code>anotherObj_from_int32</code> etc) are needed, a lot more code is required</p>
  
  <p>This solution can be found below - take a look, it's nifty!</p>
  
  <h2> Solution 2</h2>
  
  <p><em>Advantages</em></p>
  
  <ul>
  <li><p>Once the <code>ConvertFromIntegral</code> functions are done, adding new functions that need the conversion is trivial - simply write a set overloaded on <code>int32_t</code>, <code>int64_t</code> and unsigned equivalents.</p></li>
  <li><p>Keeps use of templates to one place only, they don't spread as the technique is reused.</p></li>
  </ul>
  
  <p><strong>Disadvantages</strong></p>
  
  <ul>
  <li>Might be overly complicated, using <code>boost::enable_if</code>. Somewhat mitigated by the fact this appears in once place only.</li>
  </ul>
  
  <p>Since this is my own I can't accept it, but you can upvote it if you think it's neat (and clearly some folks do <em>not</em> think it is neat at all, that's what downvote it for, I think!)
  Thanks to everyone who contributed ideas!</p>
  
  <p>The solution involves a conversion function from <code>int</code>, <code>long</code> and <code>long long</code> to <code>int32_t</code> and <code>int64_t</code> (and similar for the unsigned versions). This is combined with another set of functions overloaded on <code>int32_t</code>, <code>int64_t</code> and unsigned equivalents. The two functions could be combined, but the first conversion functions make a handy utility set that can be reused, and then the second set of functions is trivially simple.</p>
  
  <pre><code>// Utility conversion functions (reuse wherever needed)
  template &lt;class InputT&gt;
  typename boost::enable_if_c&lt;sizeof(InputT)==sizeof(int32_t) &amp;&amp; boost::is_signed&lt;InputT&gt;::value,
   int32_t&gt;::type ConvertFromIntegral(InputT z) { return static_cast&lt;int32_t&gt;(z); }
  
  template &lt;class InputT&gt;
  typename boost::enable_if_c&lt;sizeof(InputT)==sizeof(int64_t) &amp;&amp; boost::is_signed&lt;InputT&gt;::value, 
  int64_t&gt;::type ConvertFromIntegral(InputT z) { return static_cast&lt;int64_t&gt;(z); }
  
  template &lt;class InputT&gt;
  typename boost::enable_if_c&lt;sizeof(InputT)==sizeof(uint32_t) &amp;&amp; boost::is_unsigned&lt;InputT&gt;::value, 
  uint32_t&gt;::type ConvertFromIntegral(InputT z) { return static_cast&lt;uint32_t&gt;(z); }
  
  template &lt;class InputT&gt;
  typename boost::enable_if_c&lt;sizeof(InputT)==sizeof(uint64_t) &amp;&amp; boost::is_unsigned&lt;InputT&gt;::value, 
  uint64_t&gt;::type ConvertFromIntegral(InputT z) { return static_cast&lt;uint64_t&gt;(z); }
  
  // Overload set (mock implementation, depends on required return type etc)
  void* objFromInt32 (int32_t i)   { obj_from_int32(i); }
  void* objFromInt64 (int64_t&amp; i)  { obj_from_int64(i); }
  void* objFromUInt32(uint32_t&amp; i) { obj_from_uint32(i); }
  void* objFromUInt64(uint64_t&amp; i) { obj_from_uint64(i); }
  
  // Interface Implementation
  MyClass(int z) : _val(objFromInt(ConvertFromIntegral(z))) {}
  MyClass(long z): _val(objFromInt(ConvertFromIntegral(z))) {}
  MyClass(long long z): _val(objFromInt(ConvertFromIntegral(z))) {}
  MyClass(unsigned int z): _val(objFromInt(ConvertFromIntegral(z))) {}
  MyClass(unsigned long z): _val(objFromInt(ConvertFromIntegral(z))) {}
  MyClass(unsigned long long z): _val(objFromInt(ConvertFromIntegral(z))) {}
  </code></pre>
  
  <p>A simplified (single compilable <code>.cpp</code>!) version of the solution is given at <a href="https://stackoverflow.com/questions/10579544/ambiguous-overload-of-functions-like-msglong-with-candidates-msgint32-t">Ambiguous overload of functions like `msg(long)` with candidates `msg(int32_t)` and `msg(int64_t)`</a></p>