Boost logo

Boost :

From: Peder Holt (peder.holt_at_[hidden])
Date: 2004-09-02 01:38:07


On Wed, 1 Sep 2004 14:26:30 -0400, Arkadiy Vertleyb
<vertleyb_at_[hidden]> wrote:
> "Peder Holt" <peder.holt_at_[hidden]> wrote
>
> > As to the implementation of my code,
> > I got the inspiration to my implementation from Daniel Wallins post
> > some time back on compile time constants:
> > http://lists.boost.org/MailArchives/boost/msg69842.php
>
> I compiled this code in VC7.1, and it did compile although with warnings.
>
> But then I modified main to look like this:
>
> int main()
> {
> SET(X, 10);
> std::cout << CURRENT(X) << "\n";
> std::cout << VALUE(X) << "\n";
> SET(X, 15);
> std::cout << CURRENT(X) << "\n";
> std::cout << VALUE(X) << "\n";
> SET(X, 20);
> std::cout << CURRENT(X) << "\n";
> std::cout << VALUE(X) << "\n";
> SET(X, 15);
> std::cout << CURRENT(X) << "\n";
> std::cout << VALUE(X) << "\n";
> }
>
> the output was somewhat different than one would expect:
>
> 1
> 10
> 2
> 15
> 3
> 20
> 3 -- wrong
> 20 -- wrong
>
> How do you handle this in your typeof implementation? Do you reset it
> somehow between typeofs? Or do you start from the next available number?

That is because the class set_variable<X,15> has already been
instantiated. When you instantiate it again, you get the old
implementation of set_variable. To overcome this problem, you need to
add an additional template parameter to the set_variable class:

 template<int N> struct counter : counter<N - 1> {};
  template<> struct counter<0> {};

  template<int N>
  struct size_type
  {
      typedef char(&type)[N + 1];
  };

  size_type<0>::type check(...);

  template<class T, int Current, int N>
  struct set_variable
  {
      typedef counter<10> start_type;

      enum
      {
          current = Current,
          next = current + 1
      };

      friend typename size_type<next>::type check(T*, counter<next>*) {}
      friend typename size_type<N>::type value(T*, counter<current>*) {}
  };

  #define CURRENT(T) (sizeof(check((T*)0, (counter<10>*)0)) - 1)
  #define VALUE(T) (sizeof(value((T*)0, (counter<10>*)0)) - 1)
  #define SET(T, N) set_variable<T,CURRENT(T), N>()

  #include <iostream>

  struct X {};

  int main()
  {
      SET(X, 10);
      std::cout << CURRENT(X) << "\n";
      std::cout << VALUE(X) << "\n";

      SET(X, 15);
      std::cout << CURRENT(X) << "\n";
      std::cout << VALUE(X) << "\n";

      SET(X, 20);
      std::cout << CURRENT(X) << "\n";
      std::cout << VALUE(X) << "\n";

      SET(X, 15);
      std::cout << CURRENT(X) << "\n";
      std::cout << VALUE(X) << "\n";
  }

voila.

--
Peder Holt
> 
> Regards,
> Arkadiy
> 
> 
> 
> 
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk