$ g++ find.mytree.cpp
find.mytree.cpp:141:2: warning: no newline at end of file
find.mytree.cpp:123: internal compiler error: in output_constant, at
varasm.c:38
43
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.


$ g++ -v
Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
Configured with: /gcc/gcc-3.4.4/gcc-3.4.4-1/configure --verbose --prefix=/usr
--
exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib
--man
dir=/usr/share/man --infodir=/usr/share/info
--enable-languages=c,ada,c++,d,f77,
java,objc --enable-nls --without-included-gettext
--enable-version-specific-runt
ime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib
--ena
ble-interpreter --disable-libgcj-debug --enable-threads=posix
--enable-java-gc=b
oehm --disable-win32-registry --enable-sjlj-exceptions
--enable-hash-synchroniza
tion --enable-libstdcxx-debug : (reconfigured)
Thread model: posix
gcc version 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125)

find.mytree.cpp
========================
#include <iostream>
#include <string>
#include <map>
#include <vector>
#define OUTPUT(x) std::cout << x << std::endl;

template <typename C>
class mytree {
        public:
        typedef  mytree<C> MYTREE;
        typedef  std::map<const std::string, MYTREE*> ELEMENT;
        typedef  typename ELEMENT::iterator ELEITER;
        #define GETTREE(x)  (*(x->second))
        #define VALUE(x) (make_pair(x->Name(), x)) 
        typedef  std::string NAME;

        mytree(char *nm, C& vl, MYTREE *ch=0, MYTREE *brss=0, MYTREE* pr=0)
        : name(nm), value(vl){ insert (ch, brss, pr); }
        mytree(const char* nm, const C& vl, MYTREE *ch=0, MYTREE *brss=0,
MYTREE* pr=0)
        : name(nm), value(vl){ insert (ch, brss, pr); }

        MYTREE& operator/(const char* str) 
        {
                return myfind(child, str);
        }
        MYTREE&  operator|(const char* str)
        {
                return myfind(brosis, str);
        }
        MYTREE&  operator^(const char* str)
        {
                return myfind(parents, str);
        }
        const C& Value() {
                return value;
        }
        const NAME &Name() {
                return name;
        }
        operator C () {
                return value;
        }
        /* 
          noloop: to avoid infinite loop. consider A add B as brother and at
mean time B add A as brother. 
                  then A add B as brother... that will be infinite loop.
                  solution: (a) we can find each time to see if B is already
A's brother
                             (b) add the noloop, when it should be finished,
just set noloop to 0.
        */
        MYTREE& insert(MYTREE *ch, MYTREE *brss, MYTREE* pr, bool noloop=1)
        {       counter++;
                if(ch){all.insert(VALUE(ch)); child.insert(VALUE(ch));
                        if(noloop)ch->insert(0, 0, this, 0);}
                if(brss){all.insert(VALUE(brss));brosis.insert(VALUE(brss));
                        if(noloop)brss->insert(0, this, 0, 0);}
                if(pr){all.insert(VALUE(pr));parents.insert(VALUE(pr));
                        if(noloop)pr->insert(this, 0, 0, 0);}
                return *this;
        }
        void dump(MYTREE *caller=0, std::string lv="") {
                typename ELEMENT::iterator it;
                MYTREE *tr = this;

                //dump all brosis
                it = this->brosis.begin();
                while(it != this->brosis.end()) {
                        tr = &GETTREE(it);
                        assert(tr);
                        if(tr != caller && tr != this)  {
                                tr->dump(this, lv);
                                //OUTPUT(lv << "|" << tr->Name() << ": " <<
tr->Value() );                              
                        }
                        ++it;
                }

                OUTPUT(lv<< " " << this->Name() << ": " << this->Value() );     

                //dump all child
                it = this->child.begin();
                while(it != this->child.end()) {
                        tr = &GETTREE(it);
                        assert(tr);
                        if(tr != caller && tr != this) {
                                //OUTPUT(lv << "\t\\" << tr->Name() << ": " <<
tr->Value() );                                           
                                tr->dump(tr, lv+"\t");
                        }
                        ++it;
                }
        }
        static void dumpall() {
                ELEITER it = all.begin();
                while(it!= all.end()) {
                        OUTPUT(it->first <<" " << it->second );
                        ++it;
                }
        }
        /*static ELEMENT& getall() { return all;}*/
        private:
                MYTREE& myfind(ELEMENT& el, const char* str)
                {
                        typename ELEMENT::iterator it = el.find(NAME(str));
                        if ( it != el.end() ) return GETTREE(it);
                        return *this;                   
                }
                NAME name;
                ELEMENT child;
                ELEMENT brosis;
                ELEMENT parents;
                static ELEMENT all;
                static int counter;
                C value;
};

template<int> int mytree<int>::counter = 0;
/*
template<typename C> 
std::map<const std::string, mytree<C>* > mytree<C>::all = std::map<const
std::string, mytree<C>* >();// This line OK!!
*/
// This line will failed!
template<int > 
std::map<const std::string, mytree<int>* > mytree<int>::all = std::map<const
std::string, mytree<int>* >();

int main()
{
        mytree<int> my1("temp01", 1);
        mytree<int> my2("root", 2, new
          mytree<int>("hello", 3, new
            mytree<int>("world", 4)));

        my2.insert(0, new mytree<int>("my3", 5), new mytree<int>("my4", 6));
        std::cout << my2/"hello"/"world" << std::endl;
        std::cout << (my2/"hello"/"world"^"hello") <<std::endl;
        std::cout << (my2|"my3"|"root") << std::endl;
        std::cout <<(my2^"my4")/"root" << std::endl;
        (my2/"hello").insert(0, new mytree<int>("my5", 10),0);

        OUTPUT((my2/"hello"^"root")/"hello");

        mytree<int>::dumpall();
        my2.dump(/*&my2*/);

        return 0;
}


-- 
           Summary: Template Specialization break down
           Product: gcc
           Version: 3.4.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ypwangandy at gmail dot com
 GCC build triplet: i686-pc-cygwin
  GCC host triplet: i686-pc-cygwin
GCC target triplet: i686-pc-cygwin


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29766

Reply via email to