title: Is intptr_t a signed counterpart of uintptr_t (and vice versa)?
body: <p>I'm developing some tests for the add_signed MPL class that converts the type to its signed counterpart. It is defined as follows:</p>
  
  <pre><code>template&lt;class T&gt;
  struct add_signed { 
      typedef T type;
  };
  
  template&lt;&gt;
  struct add_signed&lt;std::uint8_t&gt; { 
      typedef std::int8_t type;
  };
  
  template&lt;&gt;
  struct add_signed&lt;std::uint16_t&gt; { 
      typedef std::int16_t type;
  };
  
  template&lt;&gt;
  struct add_signed&lt;std::uint32_t&gt; { 
      typedef std::int32_t type;
  };
  
  template&lt;&gt;
  struct add_signed&lt;std::uint64_t&gt; { 
      typedef std::int64_t type;
  };
  </code></pre>
  
  <p>While testing on different types I noticed that the following evaluates to true: </p>
  
  <pre><code>std::is_same&lt;add_signed&lt;uintptr_t&gt;::type, intptr_t&gt;::value  // true
  </code></pre>
  
  <p>Similarly for the add_unsigned MPL class, the following code evaluates to true:</p>
  
  <pre><code>std::is_same&lt;add_unsigned&lt;intptr_t&gt;::type, uintptr_t&gt;::value  // true
  </code></pre>
  
  <p>My compiler is MSVC 2010.</p>
  
  <p>So the question is - can we assume that in all (sane) compilers signing intptr_t will produce uintptr_t and vice versa?</p>