title: std::enable_if type checking
body: <p>I am trying to write a function that can convert a buffer of type <code>T2</code> into a buffer of type <code>T1</code>. Much of the code that sits around this function is very C-like, so I have to accept raw pointers to the buffers. The buffers contain digital samples. For floating point buffers (<code>float</code>, <code>double</code>, etc.) the smallest possible value is -1.0 and the largest value is 1.0. For integer types, the samples span the range of the type. For example, <code>int16_t</code> samples run from -32,768 to 32,767. As a result, there is more going on than a type conversion, usually a multiplication with a scaling factor is needed to get the samples into the correct range.</p>
  
  <p>In the past, I have encountered libraries that write specialized conversions for each possible sample type. I'll be honest and admit that I come from an embedded background and I would normally do the same (I'm trying to learn more modern C++ techniques and not just treating the language as "C with classes"), however I can see that this approach leads to a good amount of code that's copy-pasted and only slightly edited.</p>
  
  <p>So far I think my templated approach seems to work, but I would like to enforce my type checks with <code>std::enable_if</code> at compile time (I want the compiler to error out if someone tries to convert types that aren't used for samples). The code I have so far is reproduced below.</p>
  
  <pre><code>template &lt;class T&gt;
  struct is_sample_type : std::integral_constant &lt;
      bool,
      (std::is_floating_point&lt;T&gt;::value || std::is_integral&lt;T&gt;::value)&gt; {};
  
  template &lt;typename T1, typename T2&gt;
  void convertSamples(T1* const dst, const T2* const src,
                      const size_t num_samples, const double scalar) {
    if ((!is_sample_type&lt;T1&gt;::value) || (!is_sample_type&lt;T2&gt;::value))
      throw std::invalid_argument("Invalid sample type passed in.");
    if (std::is_same&lt;T1, T2&gt;::value) return;  // nothing to convert
  
    // Do conversion...
  }
  </code></pre>
  
  <p>I have several questions:</p>
  
  <ol>
  <li><p>How can I convert the logic inside <code>convertSamples()</code> to perform the checks at compile time using <code>std::enable_if</code>? I want to error out at compile time if the types passed in are the same or if either is not a type used for samples. I have tried to follow many examples, but the syntax still feels foreign to me.</p></li>
  <li><p>Does <code>std::is_integral</code> return true for the integer types defined in <code>stdint.h</code>? I figured this is true since these are just aliases.</p></li>
  <li><p>What is the compiler doing under the hood to "fill in" the type and when does this happen? Namely, I am trying to use OpenMP to perform the conversion steps using SIMD instructions, so I'm hoping that the template type is selected before any other optimizations are done.</p></li>
  </ol>