Topic: Do we need a standard isPointer() function?


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/10/05
Raw View
Distribution:
Newsgroups: comp.std.c++
Path: munta.cs.mu.OZ.AU!fjh
From: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Subject: Re: Do we need a standard isPointer() function?
Message-ID: <9527818.9819@mulga.cs.mu.OZ.AU>
Sender: news@cs.mu.OZ.AU (CS-Usenet)
Organization: Computer Science, University of Melbourne, Australia
References: <439kkn$n81@caesar.ultra.net> <9525806.29066@mulga.cs.mu.OZ.AU> <44hevp$ofa@caesar.ultra.net>
Date: Thu, 5 Oct 1995 08:48:30 GMT
Lines: 34

phalpern@truffle.ultranet.com (Pablo Halpern) writes:

>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
>
>> template <class T>
>> struct ext_type_info {
>>  enum { is_pointer = false }; // assume T is not a pointer...
>> }
>
>> // define a partial specialization
>> template <class U>
>> struct ext_type_info<U *> {  // ... unless it matches this
>>  enum { is_pointer = true }; // partial specialization
>> }
>
>>[This is now legal C++, but I don't know of any compilers that
>>support partial specialization yet.]
>
>This does not look like partial specialization to me. Partial
>specialization, as I understand it, is where you specify implementation
>details for a template where one or more of the template paramters are
>known at compile time. The code above does not use compile-time
>parameters but uses a notation to *imply* that the "partialy
>specialized" template is for pointer parameters only. Is this really
>legal in the current WP?

Yes, it really is legal.  See section 14.6 [temp.class.spec] of the
draft standard.

--
Fergus Henderson             |  "Australia is the richest country in the world,
fjh@cs.mu.oz.au              |   according to a new system of measuring wealth
http://www.cs.mu.oz.au/~fjh  |   announced by the World Bank yesterday."
PGP: finger fjh@128.250.37.3 |  - Melbourne newspaper "The Age", 18 Sept 1995.

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: phalpern@truffle.ultranet.com (Pablo Halpern)
Date: 1995/09/29
Raw View
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:

>phalpern@truffle.ultranet.com (Pablo Halpern) writes:

>>What I would like is some
>>operation which tells me whether a type is a built-in type and/or a
>>pointer type.

>Try the following:

> template <class T>
> struct ext_type_info {
>  enum { is_pointer = false }; // assume T is not a pointer...
> }

> // define a partial specialization
> template <class U>
> struct ext_type_info<U *> {  // ... unless it matches this
>  enum { is_pointer = true }; // partial specialization
> }


>[This is now legal C++, but I don't know of any compilers that
>support partial specialization yet.]

This does not look like partial specialization to me. Partial
specialization, as I understand it, is where you specify implementation
details for a template where one or more of the template paramters are
known at compile time. The code above does not use compile-time
parameters but uses a notation to *imply* that the "partialy
specialized" template is for pointer parameters only. Is this really
legal in the current WP? If not, my initial problem remains: is there a
way to tell if a template parameter is a pointer and/or built-in type
without extending the language?
-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1995/09/30
Raw View
>>>>> "PH" == Pablo Halpern <phalpern@truffle.ultranet.com> writes:
In article <44hevp$ofa@caesar.ultra.net> phalpern@truffle.ultranet.com (Pablo Halpern) writes:
PH> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
[...]
>> phalpern@truffle.ultranet.com (Pablo Halpern) writes:
>> template <class T>
>> struct ext_type_info {
>> enum { is_pointer = false }; // assume T is not a pointer...
>> }

>> // define a partial specialization
>> template <class U>
>> struct ext_type_info<U *> {  // ... unless it matches this
>> enum { is_pointer = true }; // partial specialization
>> }
[...]
PH> This does not look like partial specialization to me. Partial

Many things could be called ``partial specialization''; e.g.:

 template<typename X>
 struct A { /* ... */ };

 template<typename T>
 struct A<vector<T> > { /* ... */ };

I believe (from hearsay :) that when partial specialization of class
templates was proposed, it was considered making my example legal.
To ensure realizability however, the committee chose to only accept
a subset of the proposal. This  subset includes what you mention
below, what Fergus Henderson proposes above (``pointer templates'')...
but not my example.

PH> specialization, as I understand it, is where you specify implementation
PH> details for a template where one or more of the template paramters are
PH> known at compile time. The code above does not use compile-time
PH> parameters but uses a notation to *imply* that the "partialy
PH> specialized" template is for pointer parameters only. Is this really
PH> legal in the current WP? If not, my initial problem remains: is there a
PH> way to tell if a template parameter is a pointer and/or built-in type
PH> without extending the language?

It's in the DWP, according to my (incomplete) copy here, it should be
in Section 14.6 [templ.spec].

 Daveed


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: phalpern@truffle.ultranet.com (Pablo Halpern)
Date: 1995/09/14
Raw View
I am trying to optimize a template for use with built-in types and
pointers. I have a function that moves objects within or between arrays.
The first cut is simply:

  template <class type>
  void List<type>::move_elems(type *dest, const type *src, int numelems)
  {
    // Copy elements one at a time using type's assignment operator
    while (numelems-- > 0)
      *dest++ = *src++;
  }

This will work for any type with a canonical operator=(). However, this
is not efficient for built-in types and pointers, which are better
copied with the following expression:

  memmove(dest, src, sizeof(type) * numelems);

I was able to specialize the template easily enough for the built-in
types e.g.:

  void List<int>::move_elems(int *dest, const int *src, int numelems)
  {
    memmove(dest, src, sizeof(int) * numelems);
  }

However, this is tedious (I counted 11 built-in types, not counting
const- and volatile-qualified versions) and doesn't work for pointers,
which should also be copied with memmove. What I would like is some
operation which tells me whether a type is a built-in type and/or a
pointer type. An extention to the type_info class something like the
following would help:

  class type_info
  {
    // ...
    int isBuiltin() const;
    int isPointer() const;
  };

So I would write:

  void List<type>::move_elems(type *dest, const type *src, int numelems)
  {
    if (typeid(type).isBuiltin() || typeid(type).isPointer())
      // Copy elements in bulk
      memmove(dest, src, sizeof(type) * numelems);
    else
      // Copy elements one at a time using type's assignment operator
      while (numelems-- > 0)
        *dest++ = *src++;
  }

My first attempt at solving this problem without language extentions was
the following macro:

#define IS_POINTER(T) \
  (typeid(T).name()[strlen(typeid(T).name()) - 1] == '*')

This actually works on the Borland 4.02 compiler for most pointer types
or pointer objects. A set of template functions with a macro could
provide a IS_BUILTIN(T) utility. However, my IS_PTR_TYPE(T) macro does
not work for const of volatile pointers:

  int * const p;
  if (IS_PTR_TYPE(p))
    // This code will not execute

Of course I could extend my macro to call functions that strip off
trailing type qualifiers, whitespace, etc. but:

  1) Is the format of the returned value of type_info::name() standard
     enough for me to depend on it for this purpose?
  2) If so, are macros like IS_POINTER(T) and IS_BUILTIN(T) usefull
     enough to be added to a standard library file?
  3) Regardless of whether it can be finessed with the preprocessor,
     do people think the extentions to type_info I propose make sense?
  4) Is there another way to skin this cat?

Thanks.
-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/09/14
Raw View
phalpern@truffle.ultranet.com (Pablo Halpern) writes:

>What I would like is some
>operation which tells me whether a type is a built-in type and/or a
>pointer type.

Try the following:

 template <class T>
 struct ext_type_info {
  enum { is_pointer = false }; // assume T is not a pointer...
 }

 // define a partial specialization
 template <class U>
 struct ext_type_info<U *> {  // ... unless it matches this
  enum { is_pointer = true }; // partial specialization
 }

 #include <assert.h>
 main() {
  assert(ext_type_info<int>::is_pointer == false);
  assert(ext_type_info<int*>::is_pointer == true);
 }

[This is now legal C++, but I don't know of any compilers that
support partial specialization yet.]

Also check out the numeric_limits class in the draft standard.
You can use `numeric_limits<T>::is_specialised' to determine
whether a type T is one of the fundamental numeric types.

[Similarly, numeric_limits<T> is not yet supported by most implementations.]

>  1) Is the format of the returned value of type_info::name() standard
>     enough for me to depend on it for this purpose?

No.

--
Fergus Henderson             |  #define x t=a[i],a[i]=a[m],a[m]=t/* use -O */
                             |  char a[]=" 12345678";main(m,i,j,t){for(i=m;i<
fjh@cs.mu.oz.au              |  9;x,i++)for(x,j=m;--j?(t=a[m-j]-a[m])-j&&t+j:
http://www.cs.mu.oz.au/~fjh  |  main(m+1)*0;);m-9||puts(a+1);} /* 8 queens */
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]