Recognizing integer template classes...

Hey all. Another weird question from me. (Do I ask any other?)

I am writing an Algorithm V Huffman compressor (something I have always wanted to play around with), and I want to be able to encode arbitrary symbols (not just chars).

Due to technical details (which I can replicate for you if you all really care, but for now I'll assume you don't), I need to distinguish between simple integer types and complex types when processing the datastream into a bitstream.

So I made myself a little template class to help:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// isinteger.hpp

//                  Copyright Michael Thomas Greer 2010
//         Distributed under the Boost Software License, Version 1.0.           
//            ( See accompanying file LICENSE_1_0.txt or copy at
//                  http://www.boost.org/LICENSE_1_0.txt )

#pragma once
#ifndef DUTHOMHAS_ISINTEGER_HPP
#define DUTHOMHAS_ISINTEGER_HPP

#include <climits>

namespace duthomhas
  {

  template <typename T>
  bool isinteger()
    {
    return false;
    }

  template <> bool isinteger <char>               () { return true; }
  template <> bool isinteger <signed char>        () { return true; }
  template <> bool isinteger <unsigned char>      () { return true; }
  template <> bool isinteger <signed short>       () { return true; }
  template <> bool isinteger <unsigned short>     () { return true; }
  template <> bool isinteger <signed int>         () { return true; }
  template <> bool isinteger <unsigned int>       () { return true; }
  template <> bool isinteger <signed long>        () { return true; }
  template <> bool isinteger <unsigned long>      () { return true; }
  #ifdef ULLONG_MAX
  template <> bool isinteger <signed long long>   () { return true; }
  template <> bool isinteger <unsigned long long> () { return true; }
  #endif

  } // namespace duthomhas

#endif

// end isinteger.hpp 

And, of course, a little test program (in my library "tests" subdirectory):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// test-isinteger.cpp

//                  Copyright Michael Thomas Greer 2010
//         Distributed under the Boost Software License, Version 1.0.           
//            ( See accompanying file LICENSE_1_0.txt or copy at
//                  http://www.boost.org/LICENSE_1_0.txt )

#include <iostream>
#include <string>
using namespace std;

#include "isinteger.hpp"
using namespace duthomhas;

template <typename T>
struct point
  {
  T x;
  T y;
  point( const T& x = T(), const T& y = T() ): x( x ), y( y ) { }
  };

template <typename T>
ostream& operator << ( ostream& outs, const point <T> & p )
  {
  outs << "point <";
  outs << (isinteger <T> () ? "integer> (" : "not-int> (");
  outs << p.x << ", " << p.y << ")";
  return outs;
  }

int main()
  {
  point <int>    ip( -7, 42 );
  point <string> sp( "Hello", "world" );

  cout << ip << endl;
  cout << sp << endl;

  return 0;
  }

// end test-isinteger.cpp 

Naturally, I compile with
g++ -Wall -ansi -pedantic test-isinteger.cpp -I..
and get an obnoxious error message I can't really figure out how to get rid of:
In file included from test-isinteger.cpp:12:
../isinteger.hpp:33: warning: ISO C++ 1998 does not support 'long long'
../isinteger.hpp:34: warning: ISO C++ 1998 does not support 'long long'

This, of course, is reasonable, but I'd like to get rid of the warnings in some portable way. Is this possible? (I initially had the simple thought that the macro [line 32] would fix it...)

Thanks!
Obviously, compiling with different flags doesn't change the macros that are defined in code.
I see only two ways out of this. Either you ignore the warning and use everything the compiler provides, or you use no more than the standard allows and screw whoever likes long long.

Don't forget about wchar_t.
Why not just use the boost::type_traits library? It already has an is_integral template
that does this.

1
2
3
#include <type_traits/is_integral.hpp>

is_integral<T>::value evaluates to boolean true if T is integral.


http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference/is_integral.html
Topic archived. No new replies allowed.