メインページ | モジュール | 名前空間一覧 | クラス階層 | 構成 | ファイル一覧 | 名前空間メンバ | 構成メンバ | ファイルメンバ | 関連ページ

toppers/trace.hpp

解説を見る。
00001 /*
00002  *  TOPPERS/C++ API Template Library
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      C++ API Template Library
00005  *
00006  *  Copyright (C) 2004 by TAKAGI Nobuhisa
00007  *
00008  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
00009  *  によって公表されている GNU General Public License の Version 2 に記
00010  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00011  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00012  *  利用と呼ぶ)することを無償で許諾する.
00013  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00014  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00015  *      スコード中に含まれていること.
00016  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00017  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00018  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00019  *      の無保証規定を掲載すること.
00020  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00021  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00022  *      と.
00023  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00024  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00025  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00026  *        報告すること.
00027  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00028  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00029  *
00030  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00031  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00032  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00033  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00034  *
00035  *  @(#) $Id: trace.hpp,v 1.1.1.1 2004/04/14 09:30:31 takagi-n Exp $
00036  */
00037 
00052 #ifndef TOPPERS_TRACE_HPP_
00053 #define TOPPERS_TRACE_HPP_
00054 
00055 #include <typeinfo>
00056 #include <limits>
00057 #include <toppers/diagnostics.hpp>
00058 #include <toppers/kernelstatus.hpp>
00059 
00065 #ifdef  __GNUC__
00066 #define TOPPERS_TYPENAME(type)  toppers::type_name<__typeof__(type)>::get()
00067 #else
00068 #define TOPPERS_TYPENAME(type)  toppers::type_name_helper< type >()
00069 #endif
00070 
00071 #ifndef TOPPERS_HAS_SYSLOG
00072 #if TKERNEL_MAKER == 0x0118
00073 #define TOPPERS_HAS_SYSLOG  1
00074 #else
00075 #define TOPPERS_HAS_SYSLOG  0
00076 #endif
00077 #endif
00078 
00079 namespace toppers
00080 {
00081 
00091     class null_tracer
00092     {
00093     };
00094 
00095     template <typename T>
00096     null_tracer& operator<<(null_tracer& tr, const T& obj)
00097     {
00098         return tr;
00099     }
00100 
00101     namespace detail
00102     {
00103 
00104         enum
00105         {
00106             boolalpha = 0x0001,
00107             showbase  = 0x0002,
00108             uppercase = 0x0004,
00109             oct       = 0x0030,
00110             hex       = 0x0050,
00111             basefield = 0x0070
00112         };
00113 
00114         struct setpri_helper
00115         {
00116             UINT prio_;
00117         };
00118 
00119         struct setfill_helper
00120         {
00121             char fill_;
00122         };
00123 
00124         struct setwidth_helper
00125         {
00126             int width_;
00127         };
00128 
00129         template <typename Int, typename Putter, typename Dest>
00130         void convert(Int value, unsigned int base, bool uppercase, bool showbase,
00131                     int width, bool minus, char fill, Putter putter, Dest dest)
00132         {
00133             typedef std::numeric_limits<Int>    limits;
00134             TOPPERS_STATIC_ASSERT(limits::is_integer && !limits::is_signed);
00135             char    buf[33];
00136             int i = 0;
00137             Int t = value;
00138             do
00139             {
00140                 static const char upper[] = "0123456789ABCDEF";
00141                 static const char lower[] = "0123456789abcdef";
00142                 int d = t % base;
00143                 buf[i++] = uppercase ? upper[d] : lower[d];
00144                 t /= base;
00145             } while (t != 0);
00146 
00147             if (minus)
00148                 --width;
00149             if (minus && fill == '0')
00150             {
00151                 putter('-', dest);
00152             }
00153             if (value != 0 && showbase)
00154             {
00155                 switch (base)
00156                 {
00157                 case 8:
00158                     --width;
00159                     putter('0', dest);
00160                     break;
00161                 case 16:
00162                     width -= 2;
00163                     putter('0', dest);
00164                     putter(uppercase ? 'X' : 'x', dest);
00165                     break;
00166                 }
00167             }
00168             for (int j = i; j < width; j++)
00169             {
00170                 putter(fill, dest);
00171             }
00172             if (minus && fill != '0')
00173             {
00174                 putter('-', dest);
00175             }
00176             while (i > 0)
00177             {
00178                 putter(buf[--i], dest);
00179             }
00180         }
00181 
00182         template <class Tracer, typename T>
00183         inline Tracer& puthex(Tracer& tr, T x)
00184         {
00185             // Tが符号付きの場合の誤作動を回避するためsizeof(T) * CHAR_BITでビット数を求める。
00186             const int char_bits = std::numeric_limits<unsigned char>::digits;
00187             unsigned long t = (unsigned long)x;
00188             tr << '0' << 'x';
00189             convert(t, 16, false, false, (sizeof(x) * char_bits + 3) / 4, false, '0', tr.putter, (void*)&tr);
00190             return tr;
00191         }
00192 
00193         inline const char* ta_asm_or_hlng(ATR atr)
00194         {
00195             return (atr & TA_ASM) ? "TA_ASM" : "TA_HLNG";
00196         }
00197 
00198         inline const char* ta_tfifo_or_tpri(ATR atr)
00199         {
00200             return (atr & TA_TPRI) ? "TA_TPRI" : "TA_TFIFO";
00201         }
00202 
00203         inline const char* ta_mfifo_or_mpri(ATR atr)
00204         {
00205             return (atr & TA_MPRI) ? "TA_MPRI" : "TA_MFIFO";
00206         }
00207 
00208         inline const char* ta_wsgl_or_wmul(ATR atr)
00209         {
00210 #ifndef TA_WMUL
00211             return "TA_WSGL";
00212 #else
00213             return (atr & TA_WMUL) ? "TA_WMUL" : "TA_WSGL";
00214 #endif
00215         }
00216 
00217         inline const char* str_tmo(TMO tmout)
00218         {
00219             const char* s = 0;
00220             switch (tmout)
00221             {
00222             case TMO_POL:
00223                 s = "TMO_POL";
00224                 break;
00225             case TMO_FEVR:
00226                 s = "TMO_FEVR";
00227                 break;
00228             case TMO_NBLK:
00229                 s = "TMO_NBLK";
00230                 break;
00231             }
00232             return s;
00233         }
00234 
00235         inline const char* str_tskstat(STAT tskstat)
00236         {
00237             const char* s = 0;
00238 #ifdef  TTS_RUN
00239             switch (tskstat)
00240             {
00241             case TTS_RUN:
00242                 s = "TTS_RUN";
00243                 break;
00244             case TTS_RDY:
00245                 s = "TTS_RDY";
00246                 break;
00247 
00248             case TTS_WAI:
00249                 s = "TTS_WAI";
00250                 break;
00251             case TTS_SUS:
00252                 s = "TTS_SUS";
00253                 break;
00254             case TTS_WAS:
00255                 s = "TTS_WAS";
00256                 break;
00257             case TTS_DMT:
00258                 s = "TTS_DMT";
00259                 break;
00260             }
00261 #endif
00262             return s;
00263         }
00264 
00265         inline const char* str_tskwait(STAT tskwait)
00266         {
00267             const char* s = 0;
00268 #ifdef  TTW_SLP
00269             switch (tskwait)
00270             {
00271             case TTW_SLP:
00272                 s = "TTW_SLP";
00273                 break;
00274             case TTW_DLY:
00275                 s = "TTW_DLY";
00276                 break;
00277             case TTW_SEM:
00278                 s = "TTW_SEM";
00279                 break;
00280             case TTW_FLG:
00281                 s = "TTW_FLG";
00282                 break;
00283             case TTW_SDTQ:
00284                 s = "TTW_SDTQ";
00285                 break;
00286             case TTW_RDTQ:
00287                 s = "TTW_RDTQ";
00288                 break;
00289             case TTW_MBX:
00290                 s = "TTW_MBX";
00291                 break;
00292             case TTW_MTX:
00293                 s = "TTW_MTX";
00294                 break;
00295             case TTW_SMBF:
00296                 s = "TTW_SMBF";
00297                 break;
00298             case TTW_RMBF:
00299                 s = "TTW_RMBF";
00300                 break;
00301             case TTW_CAL:
00302                 s = "TTW_CAL";
00303                 break;
00304             case TTW_ACP:
00305                 s = "TTW_ACP";
00306                 break;
00307             case TTW_RDV:
00308                 s = "TTW_RDV";
00309                 break;
00310             case TTW_MPF:
00311                 s = "TTW_MPF";
00312                 break;
00313             case TTW_MPL:
00314                 s = "TTW_MPL";
00315                 break;
00316             }
00317 #endif
00318             return s;
00319         }
00320 
00321         inline const char* str_texstat(STAT texstat)
00322         {
00323             const char* s = 0;
00324 #ifdef  TTEX_ENA
00325             switch (texstat)
00326             {
00327             case TTEX_ENA:
00328                 s = "TTEX_ENA";
00329                 break;
00330             case TTEX_DIS:
00331                 s = "TTEX_DIS";
00332                 break;
00333             }
00334 #endif
00335             return s;
00336         }
00337 
00338     }
00339 
00350     template <std::size_t Count = 32,
00351               std::size_t BufferSize = 256,
00352               class Diagnostics = TOPPERS_DEFAULT_DIAGNOSTICS >
00353     class syslog_tracer : Diagnostics
00354     {
00355         TOPPERS_STATIC_ASSERT(TOPPERS_HAS_SYSLOG);
00356         UINT prio_;
00357         UINT flags_;
00358         int width_;
00359         char fill_;
00360         char* buf_, * ptr_;
00361 
00362         static char (&buffer())[Count][BufferSize]
00363         {
00364             static char b[Count][BufferSize];
00365             return b;
00366         }
00367         static std::size_t& cur()
00368         {
00369             static std::size_t c;
00370             return c;
00371         }
00372 
00373         void get_buf();
00374 
00375     public:
00377         explicit syslog_tracer(UINT prio = 5u)
00378             : prio_(prio)
00379         {
00380             get_buf();
00381             init();
00382         }
00383 
00385         void init()
00386         {
00387             flags_ = 0;
00388             width_ = 0;
00389             fill_  = ' ';
00390         }
00391 
00393         UINT flags() const
00394         {
00395             return flags_;
00396         }
00398         UINT flags(UINT fmtfl)
00399         {
00400             UINT prev = flags_;
00401             flags_ = fmtfl;
00402             return prev;
00403         }
00404 
00406         UINT setf(UINT fmtfl)
00407         {
00408             UINT prev = flags_;
00409             flags_ |= fmtfl;
00410             return prev;
00411         }
00413         UINT setf(UINT fmtfl, UINT mask)
00414         {
00415             UINT prev = flags_;
00416             flags_ = (flags_ & ~mask) | fmtfl;
00417             return prev;
00418         }
00420         UINT unsetf(UINT mask)
00421         {
00422             UINT prev = flags_;
00423             flags_ &= ~mask;
00424             return prev;
00425         }
00426 
00428         int width() const
00429         {
00430             return width_;
00431         }
00433         int width(int wide)
00434         {
00435             int prev = width_;
00436             width_ = wide >= 0 ? wide : 0;
00437             return prev;
00438         }
00439 
00441         char fill() const
00442         {
00443             return fill_;
00444         }
00446         char fill(char c)
00447         {
00448             char prev = fill_;
00449             fill_ = c ? c : ' ';
00450             return prev;
00451         }
00452 
00454         UINT priority() const
00455         {
00456             return prio_;
00457         }
00459         UINT priority(UINT prio)
00460         {
00461             UINT prev = prio_;
00462             prio_ = prio;
00463             return prev;
00464         }
00465 
00467         syslog_tracer<Count, BufferSize, Diagnostics>& flush();
00468 
00470         syslog_tracer<Count, BufferSize, Diagnostics>& put(char c)
00471         {
00472             if (ptr_ - buf_ < BufferSize)
00473             {
00474                 *ptr_++ = c;
00475                 *ptr_ = '\0';
00476             }
00477             return *this;
00478         }
00480         syslog_tracer<Count, BufferSize, Diagnostics>& put(const char* s);
00481 
00490         static void putter(char c, void* p)
00491         {
00492             static_cast<syslog_tracer<Count, BufferSize, Diagnostics>*>(p)->put(c);
00493         }
00494 
00495         syslog_tracer& operator<<(syslog_tracer& (*manip)(syslog_tracer&))
00496         {
00497             return (*manip)(*this);
00498         }
00499     };
00500 
00501     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00502     void syslog_tracer<Count, BufferSize, Diagnostics>::get_buf()
00503     {
00504         bool locked = cpulock<Diagnostics>::sense();
00505         if (!locked)
00506             cpulock<Diagnostics>::lock(context_independent);
00507 
00508         static char buffer_[Count][BufferSize];
00509         static std::size_t cur_;
00510 
00511         buf_ = buffer_[cur_++];
00512         if (cur_ >= Count)
00513             cur_ = 0;
00514 
00515         if (!locked)
00516             cpulock<Diagnostics>::unlock(context_independent);
00517 
00518         ptr_ = buf_;
00519         *ptr_ = '\0';
00520     }
00521 
00522     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00523     syslog_tracer<Count, BufferSize, Diagnostics>& syslog_tracer<Count, BufferSize, Diagnostics>::flush()
00524     {
00525         SYSLOG log;
00526         log.logtype = LOG_TYPE_COMMENT;
00527         log.loginfo[0] = (VP_INT)"%s";
00528         log.loginfo[1] = (VP_INT)buf_;
00529         ER ercd = vwri_log(prio_, &log);
00530         Diagnostics::handle_error(ercd);
00531         get_buf();
00532         return *this;
00533     }
00534 
00535     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00536     syslog_tracer<Count, BufferSize, Diagnostics>& syslog_tracer<Count, BufferSize, Diagnostics>::put(const char* s)
00537     {
00538         if (s == 0)
00539             s = "(null)";
00540         while (*s != '\0' && ptr_ - buf_ < BufferSize)
00541             *ptr_++ = *s++;
00542         *ptr_ = '\0';
00543         return *this;
00544     }
00545 
00552     inline detail::setpri_helper setpri(UINT prio)
00553     {
00554         detail::setpri_helper t;
00555         t.prio_ = prio;
00556         return t;
00557     }
00558 
00559     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00560     inline syslog_tracer<Count, BufferSize, Diagnostics>& operator<<(syslog_tracer<Count, BufferSize, Diagnostics>& tr, const detail::setpri_helper& helper)
00561     {
00562         tr.priority(helper.prio_);
00563         return tr;
00564     }
00565 
00566     template <class Tracer>
00567     inline Tracer& operator<<(Tracer& tr, const detail::setpri_helper& helper)
00568     {
00569         return tr;
00570     }
00571 
00578     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00579     inline syslog_tracer<Count, BufferSize, Diagnostics>& endl(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00580     {
00581         return tr.flush();
00582     }
00583 
00592     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00593     inline syslog_tracer<Count, BufferSize, Diagnostics>& boolalpha(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00594     {
00595         tr.setf(detail::boolalpha);
00596         return tr;
00597     }
00598 
00607     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00608     inline syslog_tracer<Count, BufferSize, Diagnostics>& unboolalpha(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00609     {
00610         tr.unsetf(detail::boolalpha);
00611         return tr;
00612     }
00613 
00622     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00623     inline syslog_tracer<Count, BufferSize, Diagnostics>& showbase(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00624     {
00625         tr.setf(detail::showbase);
00626         return tr;
00627     }
00628 
00637     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00638     inline syslog_tracer<Count, BufferSize, Diagnostics>& unshowbase(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00639     {
00640         tr.unsetf(detail::showbase);
00641         return tr;
00642     }
00643 
00652     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00653     inline syslog_tracer<Count, BufferSize, Diagnostics>& uppercase(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00654     {
00655         tr.setf(detail::uppercase);
00656         return tr;
00657     }
00658 
00667     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00668     inline syslog_tracer<Count, BufferSize, Diagnostics>& lowercase(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00669     {
00670         tr.unsetf(detail::uppercase);
00671         return tr;
00672     }
00673 
00682     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00683     inline syslog_tracer<Count, BufferSize, Diagnostics>& dec(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00684     {
00685         tr.unsetf(detail::basefield);
00686         return tr;
00687     }
00688 
00697     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00698     inline syslog_tracer<Count, BufferSize, Diagnostics>& oct(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00699     {
00700         tr.setf(detail::oct, detail::basefield);
00701         return tr;
00702     }
00703 
00712     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00713     inline syslog_tracer<Count, BufferSize, Diagnostics>& hex(syslog_tracer<Count, BufferSize, Diagnostics>& tr)
00714     {
00715         tr.setf(detail::hex, detail::basefield);
00716         return tr;
00717     }
00718 
00719     template <std::size_t Count, std::size_t BufferSize, class Diagnostics>
00720     inline syslog_tracer<Count, BufferSize, Diagnostics>&
00721         operator<<(syslog_tracer<Count, BufferSize, Diagnostics>& tr,
00722                    syslog_tracer<Count, BufferSize, Diagnostics>& (*manip)(syslog_tracer<Count, BufferSize, Diagnostics>&))
00723     {
00724         return (*manip)(tr);
00725     }
00726 
00735     template <class Tracer>
00736     inline Tracer& operator<<(Tracer& tr, Tracer& (*manip)(Tracer&))
00737     {
00738         return (*manip)(tr);
00739     }
00740 
00748     inline detail::setfill_helper setfill(char c)
00749     {
00750         detail::setfill_helper t;
00751         t.fill_ = c;
00752         return t;
00753     }
00754 
00755     template <class Tracer>
00756     inline Tracer& operator<<(Tracer& tr, const detail::setfill_helper& helper)
00757     {
00758         tr.fill(helper.fill_);
00759         return tr;
00760     }
00761 
00768     inline detail::setwidth_helper setw(int width)
00769     {
00770         detail::setwidth_helper t;
00771         t.width_ = width;
00772         return t;
00773     }
00774 
00775     template <class Tracer>
00776     inline Tracer& operator<<(Tracer& tr, const detail::setwidth_helper& helper)
00777     {
00778         tr.width(helper.width_);
00779         return tr;
00780     }
00781 
00791     template <class Tracer>
00792     Tracer& operator<<(Tracer& tr, bool x)
00793     {
00794         int width = tr.width();
00795         char fill = tr.fill();
00796 
00797         if (tr.flags() & detail::boolalpha)
00798         {
00799             for (int i = (x ? sizeof("true") : sizeof("false")) - 1; i < width; i++)
00800                 tr.put(fill);
00801             tr.put(x ? "true" : "false");
00802         }
00803         else
00804         {
00805             for (int i = 1; i < width; i++)
00806                 tr.put(fill);
00807             tr.put(x ? '1' : '0');
00808         }
00809         return tr;
00810     }
00811 
00821     template <class Tracer>
00822     Tracer& operator<<(Tracer& tr, char x)
00823     {
00824         int width = tr.width();
00825         char fill = tr.fill();
00826 
00827         for (int i = 1; i < width; i++)
00828             tr.put(fill);
00829         tr.put(x);
00830         return tr;
00831     }
00832 
00841     template <class Tracer>
00842     Tracer& operator<<(Tracer& tr, const char* x)
00843     {
00844         int width = tr.width();
00845         if (width > 0)
00846         {
00847             char fill = tr.fill();
00848             const char* s;
00849             for (s = x; *s != '\0'; s++) {}
00850             for (int i = (int)(s - x); i < width; i++)
00851                 tr.put(fill);
00852         }
00853         tr.put(x);
00854         return tr;
00855     }
00856 
00863     template <class Tracer>
00864     Tracer& operator<<(Tracer& tr, long x)
00865     {
00866         bool minus = x < 0;
00867         unsigned long t = static_cast<unsigned long>(minus ? -x : x);
00868         UINT flags = tr.flags();
00869         unsigned int base = flags & detail::basefield;
00870 
00871         if (base == detail::oct)
00872             base = 8;
00873         else if (base == detail::hex)
00874             base = 16;
00875         else
00876             base = 10;
00877 
00878         detail::convert(t, base, flags & detail::uppercase, flags & detail::showbase, tr.width(), minus, tr.fill(), tr.putter, (void*)&tr);
00879         return tr;
00880     }
00881 
00888     template <class Tracer>
00889     Tracer& operator<<(Tracer& tr, unsigned long x)
00890     {
00891         UINT flags = tr.flags();
00892         unsigned int base = flags & detail::basefield;
00893 
00894         if (base == detail::oct)
00895             base = 8;
00896         else if (base == detail::hex)
00897             base = 16;
00898         else
00899             base = 10;
00900 
00901         detail::convert(x, base, flags & detail::uppercase, flags & detail::showbase, tr.width(), false, tr.fill(), tr.putter, (void*)&tr);
00902         return tr;
00903     }
00904 
00911     template <class Tracer>
00912     inline Tracer& operator<<(Tracer& tr, int x)
00913     {
00914         return tr << static_cast<long>(x);
00915     }
00916 
00923     template <class Tracer>
00924     inline Tracer& operator<<(Tracer& tr, unsigned int x)
00925     {
00926         return tr << static_cast<unsigned long>(x);
00927     }
00928 
00929 #ifdef  TOPPERS_LONG_LONG
00930 
00939     template <class Tracer>
00940     Tracer& operator<<(Tracer& tr, TOPPERS_LONG_LONG x)
00941     {
00942         bool minus = x < 0;
00943         unsigned TOPPERS_LONG_LONG t = static_cast<unsigned TOPPERS_LONG_LONG>(minus ? -t : t);
00944         UINT flags = tr.flags();
00945         unsigned int base = flags & detail::basefield;
00946 
00947         if (base == detail::oct)
00948             base = 8;
00949         else if (base == detail::hex)
00950             base = 16;
00951         else
00952             base = 10;
00953 
00954         detail::convert(t, base, flags & detail::uppercase, flags & detail::showbase, tr.width(), minus, tr.fill(), tr.putter, (void*)&tr);
00955         return tr;
00956     }
00957 
00966     template <class Tracer>
00967     Tracer& operator<<(Tracer& tr, unsigned TOPPERS_LONG_LONG x)
00968     {
00969         UINT flags = tr.flags();
00970         unsigned int base = flags & detail::basefield;
00971 
00972         if (base == detail::oct)
00973             base = 8;
00974         else if (base == detail::hex)
00975             base = 16;
00976         else
00977             base = 10;
00978 
00979         detail::convert(x, base, flags & detail::uppercase, flags & detail::showbase, tr.width(), false, tr.fill(), tr.putter, (void*)&tr);
00980         return tr;
00981     }
00982 
00983 #endif
00984 
00993     template <class Tracer>
00994     Tracer& operator<<(Tracer& tr, const volatile void* x)
00995     {
00996         if (x == 0)
00997             return tr << "NULL";
00998         return detail::puthex(tr, x);
00999     }
01000 
01008     template <class Tracer>
01009     inline Tracer& operator<<(Tracer& tr, FP x)
01010     {
01011         return detail::puthex(tr, x);
01012     }
01013     template <class Tracer, typename R>
01014     inline Tracer& operator<<(Tracer& tr, R (*x)())
01015     {
01016         return detail::puthex(tr, x);
01017     }
01018     template <class Tracer, typename R>
01019     inline Tracer& operator<<(Tracer& tr, R (*x)(...))
01020     {
01021         return detail::puthex(tr, x);
01022     }
01023     template <class Tracer, typename R, typename T>
01024     inline Tracer& operator<<(Tracer& tr, R (*x)(T))
01025     {
01026         return detail::puthex(tr, x);
01027     }
01028     template <class Tracer, typename R, typename T>
01029     inline Tracer& operator<<(Tracer& tr, R (*x)(T, ...))
01030     {
01031         return detail::puthex(tr, x);
01032     }
01033     template <class Tracer, typename R, typename T1, typename T2>
01034     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2))
01035     {
01036         return detail::puthex(tr, x);
01037     }
01038     template <class Tracer, typename R, typename T1, typename T2>
01039     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, ...))
01040     {
01041         return detail::puthex(tr, x);
01042     }
01043     template <class Tracer, typename R, typename T1, typename T2, typename T3>
01044     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3))
01045     {
01046         return detail::puthex(tr, x);
01047     }
01048     template <class Tracer, typename R, typename T1, typename T2, typename T3>
01049     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, ...))
01050     {
01051         return detail::puthex(tr, x);
01052     }
01053     template <class Tracer, typename R, typename T1, typename T2, typename T3, typename T4>
01054     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, T4))
01055     {
01056         return detail::puthex(tr, x);
01057     }
01058     template <class Tracer, typename R, typename T1, typename T2, typename T3, typename T4>
01059     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, T4, ...))
01060     {
01061         return detail::puthex(tr, x);
01062     }
01063     template <class Tracer, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
01064     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, T4, T5))
01065     {
01066         return detail::puthex(tr, x);
01067     }
01068     template <class Tracer, typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
01069     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, T4, T5, ...))
01070     {
01071         return detail::puthex(tr, x);
01072     }
01073     template <class Tracer, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
01074     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, T4, T5, T6))
01075     {
01076         return detail::puthex(tr, x);
01077     }
01078     template <class Tracer, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
01079     inline Tracer& operator<<(Tracer& tr, R (*x)(T1, T2, T3, T4, T5, T6, ...))
01080     {
01081         return detail::puthex(tr, x);
01082     }
01083 
01090     template <class Tracer>
01091     Tracer& operator<<(Tracer& tr, const t_msg& x)
01092     {
01093         return tr << "{ " << (void*)x.next << " }";
01094     }
01095 
01102     template <class Tracer>
01103     Tracer& operator<<(Tracer& tr, const t_msg_pri& x)
01104     {
01105         return tr << "{ " << x.msgque << ", " << x.msgpri << " }";
01106     }
01107 
01114     template <class Tracer>
01115     Tracer& operator<<(Tracer& tr, const t_ctsk& x)
01116     {
01117         tr << "{ "
01118             << detail::ta_asm_or_hlng(x.tskatr);
01119         if (x.tskatr & TA_ACT)
01120             tr << "|TA_ACT";
01121         if (x.tskatr & ~(TA_ASM|TA_HLNG|TA_ACT))
01122         {
01123             tr << "|";
01124             detail::puthex(tr, x.tskatr);
01125         }
01126         tr << ", "
01127             << x.exinf << ", "
01128             << x.task << ", "
01129             << x.itskpri << ", "
01130             << x.stksz << ", "
01131             << x.stk
01132            << " }";
01133         return tr;
01134     }
01135 
01142     template <class Tracer>
01143     Tracer& operator<<(Tracer& tr, const t_rtsk& x)
01144     {
01145         const char* s;
01146         tr << "{ ";
01147 
01148             s = detail::str_tskstat(x.tskstat);
01149             if (s == 0)
01150                 tr << x.tskstat;
01151             else
01152                 tr << s;
01153 
01154         tr << ", "
01155             << x.tskpri << ", "
01156             << x.tskbpri << ", ";
01157 
01158             s = detail::str_tskwait(x.tskwait);
01159             if (s == 0)
01160                 tr << x.tskwait;
01161             else
01162                 tr << s;
01163 
01164         tr << ", "
01165             << x.wobjid << ", ";
01166 
01167             if (x.lefttmo >= 0)
01168                 tr << x.lefttmo;
01169             else
01170                 tr << detail::str_tmo(x.lefttmo);
01171 
01172         tr  << ", "
01173             << x.actcnt << ", "
01174             << x.wupcnt << ", "
01175             << x.suscnt
01176           << " }";
01177         return tr;
01178     }
01179 
01186     template <class Tracer>
01187     Tracer& operator<<(Tracer& tr, const t_rtst& x)
01188     {
01189         const char* s;
01190         tr << "{ ";
01191 
01192             s = detail::str_tskstat(x.tskstat);
01193             if (s == 0)
01194                 tr << x.tskstat;
01195             else
01196                 tr << s;
01197 
01198         tr << ", ";
01199 
01200             s = detail::str_tskwait(x.tskwait);
01201             if (s == 0)
01202                 tr << x.tskwait;
01203             else
01204                 tr << s;
01205 
01206         tr << " }";
01207         return tr;
01208     }
01209 
01216     template <class Tracer>
01217     Tracer& operator<<(Tracer& tr, const t_dtex& x)
01218     {
01219         tr << "{ "
01220             << detail::ta_asm_or_hlng(x.texatr);
01221         if (x.texatr & ~(TA_ASM|TA_HLNG))
01222         {
01223             tr << "|";
01224             detail::puthex(tr, x.texatr);
01225         }
01226         tr << ", "
01227             << x.texrtn
01228            << " }";
01229         return tr;
01230     }
01231 
01238     template <class Tracer>
01239     Tracer& operator<<(Tracer& tr, const t_rtex& x)
01240     {
01241         const char* s;
01242         tr << "{ ";
01243 
01244             s = detail::str_texstat(x.texstat);
01245             if (s == 0)
01246                 tr << x.texstat;
01247             else
01248                 tr << s;
01249 
01250         tr << ", ";
01251             detail::puthex(tr, x.pndptn)
01252           << " }";
01253         return tr;
01254     }
01255 
01262     template <class Tracer>
01263     Tracer& operator<<(Tracer& tr, const t_csem& x)
01264     {
01265         tr << "{ "
01266             << detail::ta_tfifo_or_tpri(x.sematr);
01267         if (x.sematr & ~(TA_TFIFO|TA_TPRI))
01268         {
01269             tr << "|";
01270             detail::puthex(tr, x.sematr);
01271         }
01272         tr << ", "
01273             << x.isemcnt << ", "
01274             << x.maxsem
01275            << " }";
01276         return tr;
01277     }
01278 
01285     template <class Tracer>
01286     Tracer& operator<<(Tracer& tr, const t_rsem& x)
01287     {
01288         return tr << "{ "
01289                     << x.wtskid << ", "
01290                     << x.semcnt
01291                   << " }";
01292     }
01293 
01300     template <class Tracer>
01301     Tracer& operator<<(Tracer& tr, const t_cflg& x)
01302     {
01303         tr << "{ "
01304             << detail::ta_tfifo_or_tpri(x.flgatr) << '|'
01305             << detail::ta_wsgl_or_wmul(x.flgatr);
01306         if (x.flgatr & TA_CLR)
01307             tr << "|TA_CLR";
01308 #ifndef TA_WMUL
01309         if (x.flgatr & ~(TA_TFIFO|TA_TPRI|TA_WSGL|TA_CLR))
01310 #else
01311         if (x.flgatr & ~(TA_TFIFO|TA_TPRI|TA_WSGL|TA_WMUL|TA_CLR))
01312 #endif
01313         {
01314             tr << "|";
01315             detail::puthex(tr, x.flgatr);
01316         }
01317         tr << ", ";
01318             detail::puthex(tr, x.iflgptn)
01319            << " }";
01320         return tr;
01321     }
01322 
01329     template <class Tracer>
01330     Tracer& operator<<(Tracer& tr, const t_rflg& x)
01331     {
01332         tr << "{ "
01333             << x.wtskid << ", ";
01334             detail::puthex(tr, x.flgptn)
01335           << " }";
01336         return tr;
01337     }
01338 
01345     template <class Tracer>
01346     Tracer& operator<<(Tracer& tr, const t_cdtq& x)
01347     {
01348         tr << "{ "
01349             << detail::ta_tfifo_or_tpri(x.dtqatr);
01350         if (x.dtqatr & ~(TA_TFIFO|TA_TPRI))
01351         {
01352             tr << "|";
01353             detail::puthex(tr, x.dtqatr);
01354         }
01355         tr << ", "
01356             << x.dtqcnt << ", "
01357             << x.dtq
01358            << " }";
01359         return tr;
01360     }
01361 
01368     template <class Tracer>
01369     Tracer& operator<<(Tracer& tr, const t_rdtq& x)
01370     {
01371         return tr << "{ "
01372                     << x.stskid << ", "
01373                     << x.rtskid << ", "
01374                     << x.sdtqcnt
01375                   << " }";
01376     }
01377 
01384     template <class Tracer>
01385     Tracer& operator<<(Tracer& tr, const t_cmbx& x)
01386     {
01387         tr << "{ "
01388             << detail::ta_tfifo_or_tpri(x.mbxatr) << '|'
01389             << detail::ta_mfifo_or_mpri(x.mbxatr);
01390         if (x.mbxatr & ~(TA_TFIFO|TA_TPRI|TA_MFIFO|TA_MPRI))
01391         {
01392             tr << "|";
01393             detail::puthex(tr, x.mbxatr);
01394         }
01395         tr << ", "
01396             << x.maxmpri << ", "
01397             << x.mprihd
01398            << " }";
01399         return tr;
01400     }
01401 
01408     template <class Tracer>
01409     Tracer& operator<<(Tracer& tr, const t_rmbx& x)
01410     {
01411         return tr << "{ "
01412                     << x.wtskid << ", "
01413                     << x.pk_msg
01414                   << " }";
01415     }
01416 
01423     template <class Tracer>
01424     Tracer& operator<<(Tracer& tr, const t_cmtx& x)
01425     {
01426         const char* s = "";
01427         switch (x.mtxatr & (TA_TFIFO|TA_TPRI|TA_INHERIT|TA_CEILING))
01428         {
01429         case TA_TFIFO:
01430             s = "TA_TFIFO";
01431             break;
01432         case TA_TPRI:
01433             s = "TA_TPRI";
01434             break;
01435         case TA_INHERIT:
01436             s = "TA_INHERIT";
01437             break;
01438         case TA_CEILING:
01439             s = "TA_CEILING";
01440             break;
01441         }
01442         tr << "{ "
01443             << s;
01444         if (x.mtxatr & ~(TA_TFIFO|TA_TPRI|TA_INHERIT|TA_CEILING))
01445         {
01446             tr << "|";
01447             detail::puthex(tr, x.mtxatr);
01448         }
01449         tr << ", "
01450             << x.ceilpri
01451            << " }";
01452         return tr;
01453     }
01454 
01461     template <class Tracer>
01462     Tracer& operator<<(Tracer& tr, const t_rmtx& x)
01463     {
01464         return tr << "{ "
01465                     << x.htskid << ", "
01466                     << x.wtskid
01467                   << " }";
01468     }
01469 
01476     template <class Tracer>
01477     Tracer& operator<<(Tracer& tr, const t_cmbf& x)
01478     {
01479         tr << "{ "
01480             << detail::ta_tfifo_or_tpri(x.mbfatr);
01481         if (x.mbfatr & ~(TA_TFIFO|TA_TPRI))
01482         {
01483             tr << "|";
01484             detail::puthex(tr, x.mbfatr);
01485         }
01486         tr << ", "
01487             << x.maxmsz << ", "
01488             << x.mbfsz << ", "
01489             << x.mbf
01490            << " }";
01491         return tr;
01492     }
01493 
01500     template <class Tracer>
01501     Tracer& operator<<(Tracer& tr, const t_rmbf& x)
01502     {
01503         return tr << "{ "
01504                     << x.stskid << ", "
01505                     << x.rtskid << ", "
01506                     << x.smsgcnt << ", "
01507                     << x.fmbfsz
01508                   << " }";
01509     }
01510 
01517     template <class Tracer>
01518     Tracer& operator<<(Tracer& tr, const t_cpor& x)
01519     {
01520         tr << "{ "
01521             << detail::ta_tfifo_or_tpri(x.poratr);
01522         if (x.poratr & ~(TA_TFIFO|TA_TPRI))
01523         {
01524             tr << "|";
01525             detail::puthex(tr, x.poratr);
01526         }
01527         tr << ", "
01528             << x.maxcmsz << ", "
01529             << x.maxrmsz
01530            << " }";
01531         return tr;
01532     }
01533 
01540     template <class Tracer>
01541     Tracer& operator<<(Tracer& tr, const t_rpor& x)
01542     {
01543         return tr << "{ "
01544                     << x.ctskid << ", "
01545                     << x.atskid
01546                   << " }";
01547     }
01548 
01555     template <class Tracer>
01556     Tracer& operator<<(Tracer& tr, const t_rrdv& x)
01557     {
01558         return tr << "{ "
01559                     << x.wtskid
01560                   << " }";
01561     }
01562 
01569     template <class Tracer>
01570     Tracer& operator<<(Tracer& tr, const t_cmpf& x)
01571     {
01572         tr << "{ "
01573             << detail::ta_tfifo_or_tpri(x.mpfatr);
01574         if (x.mpfatr & ~(TA_TFIFO|TA_TPRI))
01575         {
01576             tr << "|";
01577             detail::puthex(tr, x.mpfatr);
01578         }
01579         tr << ", "
01580             << x.blkcnt << ", "
01581             << x.blksz << ", "
01582             << x.mpf
01583            << " }";
01584         return tr;
01585     }
01586 
01593     template <class Tracer>
01594     Tracer& operator<<(Tracer& tr, const t_rmpf& x)
01595     {
01596         return tr << "{ "
01597                     << x.wtskid << ", "
01598                     << x.fblkcnt
01599                   << " }";
01600     }
01601 
01608     template <class Tracer>
01609     Tracer& operator<<(Tracer& tr, const t_cmpl& x)
01610     {
01611         tr << "{ "
01612             << detail::ta_tfifo_or_tpri(x.mplatr);
01613         if (x.mplatr & ~(TA_TFIFO|TA_TPRI))
01614         {
01615             tr << "|";
01616             detail::puthex(tr, x.mplatr);
01617         }
01618         tr << ", "
01619             << x.mplsz << ", "
01620             << x.mpl
01621            << " }";
01622         return tr;
01623     }
01624 
01631     template <class Tracer>
01632     Tracer& operator<<(Tracer& tr, const t_rmpl& x)
01633     {
01634         return tr << "{ "
01635                     << x.wtskid << ", "
01636                     << x.fmplsz << ", "
01637                     << x.fblksz
01638                   << " }";
01639     }
01640 
01647     template <class Tracer>
01648     Tracer& operator<<(Tracer& tr, const t_ccyc& x)
01649     {
01650         tr << "{ "
01651             << detail::ta_asm_or_hlng(x.cycatr);
01652         if (x.cycatr & TA_STA)
01653             tr << "|TA_STA";
01654         if (x.cycatr & TA_PHS)
01655             tr << "|TA_PHS";
01656         if (x.cycatr & ~(TA_ASM|TA_HLNG|TA_STA|TA_PHS))
01657         {
01658             tr << "|";
01659             detail::puthex(tr, x.cycatr);
01660         }
01661         tr << ", "
01662             << x.exinf << ", "
01663             << x.cychdr << ", "
01664             << x.cyctim << ", "
01665             << x.cycphs
01666            << " }";
01667         return tr;
01668     }
01669 
01676     template <class Tracer>
01677     Tracer& operator<<(Tracer& tr, const t_rcyc& x)
01678     {
01679         tr << "{ ";
01680             switch (x.cycstat)
01681             {
01682             case TCYC_STP:
01683                 tr << "TCYC_STP";
01684                 break;
01685             case TCYC_STA:
01686                 tr << "TCYC_STA";
01687                 break;
01688             default:
01689                 tr << x.cycstat;
01690                 break;
01691             }
01692         tr << ", "
01693             << x.lefttim
01694            << " }";
01695         return tr;
01696     }
01697 
01704     template <class Tracer>
01705     Tracer& operator<<(Tracer& tr, const t_calm& x)
01706     {
01707         tr << "{ "
01708             << detail::ta_asm_or_hlng(x.almatr);
01709         if (x.almatr & ~(TA_ASM|TA_HLNG))
01710         {
01711             tr << "|";
01712             detail::puthex(tr, x.almatr);
01713         }
01714         tr << ", "
01715             << x.exinf << ", "
01716             << x.almhdr
01717            << " }";
01718         return tr;
01719     }
01720 
01727     template <class Tracer>
01728     Tracer& operator<<(Tracer& tr, const t_ralm& x)
01729     {
01730         tr << "{ ";
01731             switch (x.almstat)
01732             {
01733             case TALM_STP:
01734                 tr << "TALM_STP";
01735                 break;
01736             case TALM_STA:
01737                 tr << "TALM_STA";
01738                 break;
01739             default:
01740                 tr << x.almstat;
01741                 break;
01742             }
01743         tr << ", "
01744             << x.lefttim
01745            << " }";
01746         return tr;
01747     }
01748 
01755     template <class Tracer>
01756     Tracer& operator<<(Tracer& tr, const t_dovr& x)
01757     {
01758         tr << "{ "
01759             << detail::ta_asm_or_hlng(x.ovratr);
01760         if (x.ovratr & ~(TA_ASM|TA_HLNG))
01761         {
01762             tr << "|";
01763             detail::puthex(tr, x.ovratr);
01764         }
01765         tr << ", "
01766             << x.ovrhdr
01767            << " }";
01768         return tr;
01769     }
01770 
01777     template <class Tracer>
01778     Tracer& operator<<(Tracer& tr, const t_rovr& x)
01779     {
01780         tr << "{ ";
01781             switch (x.ovrstat)
01782             {
01783             case TOVR_STP:
01784                 tr << "TOVR_STP";
01785                 break;
01786             case TOVR_STA:
01787                 tr << "TOVR_STA";
01788                 break;
01789             default:
01790                 tr << x.ovrstat;
01791                 break;
01792             }
01793         tr << ", "
01794             << x.leftotm
01795            << " }";
01796         return tr;
01797     }
01798 
01805     template <class Tracer>
01806     Tracer& operator<<(Tracer& tr, const t_rsys& x)
01807     {
01808         return tr << "{ "
01809 #if TKERNEL_MAKER == 0x0118
01810 #endif
01811                   << " }";
01812     }
01813 
01820     template <class Tracer>
01821     Tracer& operator<<(Tracer& tr, const t_dinh& x)
01822     {
01823         tr << "{ ";
01824             detail::puthex(tr, x.inhatr) << ", "
01825             << x.inthdr
01826            << " }";
01827         return tr;
01828     }
01829 
01836     template <class Tracer>
01837     Tracer& operator<<(Tracer& tr, const t_cisr& x)
01838     {
01839         tr << "{ "
01840             << detail::ta_asm_or_hlng(x.isratr);
01841         if (x.isratr & ~(TA_ASM|TA_HLNG))
01842         {
01843             tr << "|";
01844             detail::puthex(tr, x.isratr);
01845         }
01846         tr << ", "
01847             << x.exinf << ", "
01848             << x.intno << ", "
01849             << x.isr
01850            << " }";
01851         return tr;
01852     }
01853 
01860     template <class Tracer>
01861     Tracer& operator<<(Tracer& tr, const t_risr& x)
01862     {
01863         return tr << "{ "
01864 #if TKERNEL_MAKER == 0x0118
01865 #endif
01866                   << " }";
01867     }
01868 
01875     template <class Tracer>
01876     Tracer& operator<<(Tracer& tr, const t_dsvc& x)
01877     {
01878         tr << "{ "
01879             << detail::ta_asm_or_hlng(x.svcatr);
01880         if (x.svcatr & ~(TA_ASM|TA_HLNG))
01881         {
01882             tr << "|";
01883             detail::puthex(tr, x.svcatr);
01884         }
01885         tr << ", "
01886             << x.svcrtn
01887            << " }";
01888         return tr;
01889     }
01890 
01897     template <class Tracer>
01898     Tracer& operator<<(Tracer& tr, const t_dexc& x)
01899     {
01900         tr << "{ ";
01901             detail::puthex(tr, x.excatr) << ", "
01902             << x.exchdr
01903            << " }";
01904         return tr;
01905     }
01906 
01913     template <class Tracer>
01914     Tracer& operator<<(Tracer& tr, const t_rcfg& x)
01915     {
01916         return tr << "{ "
01917 #if TKERNEL_MAKER == 0x0118
01918 #endif
01919                   << " }";
01920     }
01921 
01928     template <class Tracer>
01929     Tracer& operator<<(Tracer& tr, const t_rver& x)
01930     {
01931         tr << "{ ";
01932             detail::puthex(tr, x.maker) << ", ";
01933             detail::puthex(tr, x.prid) << ", ";
01934             detail::puthex(tr, x.spver) << ", ";
01935             detail::puthex(tr, x.prver) << ", ";
01936 
01937         tr  << "{ ";
01938             detail::puthex(tr, x.prno[0]) << ", ";
01939             detail::puthex(tr, x.prno[1]) << ", ";
01940             detail::puthex(tr, x.prno[2]) << ", ";
01941             detail::puthex(tr, x.prno[3])
01942             << " }";
01943         tr << " }";
01944         return tr;
01945     }
01946 
01947 #ifdef  TOPPERS_STRUCT_SYSTIM
01948 
01949     template <class Tracer>
01950     Tracer& operator<<(Tracer& tr, const SYSTIM& x)
01951     {
01952         // SYSTIMが構造体の場合の最低限の対応のため、16進数で表現するものとする。
01953         TOPPERS_ASSERT(std::numeric_limits<unsigned char>::digits == 8);
01954         unsigned long t1 = (unsigned long)x.htime;
01955         unsigned long t1 = (unsigned long)x.ltime;
01956         tr << '0' << 'x';
01957         convert(t1, 16, false, false, (sizeof(x.htime) * 8 + 3) / 4, false, '0', tr.putter, (void*)&tr);
01958         convert(t2, 16, false, false, (sizeof(x.ltime) * 8 + 3) / 4, false, '0', tr.putter, (void*)&tr);
01959         return tr;
01960     }
01961 
01962 #endif  // TOPPERS_STRUCT_SYSTIM
01963 
01964     template <typename T>
01965     inline const char* type_name_helper()
01966     {
01967         return typeid(T).name();
01968     }
01969 
01970 #define TOPPERS_DEFINE_TYPE_NAME(type)  \
01971     template <> inline const char* type_name<type>::get() { return #type; }
01972 
01973     template <typename T> 
01974     void _(char* name) throw()
01975     {
01976         const int offset = sizeof "void toppers::_(char*) [with T =";
01977         const char* first = __PRETTY_FUNCTION__ + offset;
01978         const char* last  = first + sizeof __PRETTY_FUNCTION__ - offset - sizeof "]";
01979         for (const char* s = first; s < last; s++, name++)
01980             *name = *s;
01981         *name = '\0';
01982     }
01983 
01984     template <typename T>
01985     struct type_name
01986     {
01987         static const char* get();
01988     };
01989 
01990     template <typename T>
01991     inline const char* type_name<T>::get()
01992     {
01993         static const char* name;
01994         if (name == 0)
01995         {
01996             int state = sns_dsp();
01997             if (!state)
01998                 dis_dsp();
01999             if (name == 0)
02000             {
02001                 static char s[sizeof __PRETTY_FUNCTION__ - 45 + 1];
02002                 _<T>(s);
02003                 name = s;
02004             }
02005             if (!state)
02006                 ena_dsp();
02007         }
02008         return name;
02009     }
02010 
02011     TOPPERS_DEFINE_TYPE_NAME(char)
02012     TOPPERS_DEFINE_TYPE_NAME(signed char)
02013     TOPPERS_DEFINE_TYPE_NAME(unsigned char)
02014     TOPPERS_DEFINE_TYPE_NAME(short)
02015     TOPPERS_DEFINE_TYPE_NAME(unsigned short)
02016     TOPPERS_DEFINE_TYPE_NAME(int)
02017     TOPPERS_DEFINE_TYPE_NAME(unsigned int)
02018     TOPPERS_DEFINE_TYPE_NAME(long)
02019     TOPPERS_DEFINE_TYPE_NAME(unsigned long)
02020     TOPPERS_DEFINE_TYPE_NAME(long long)
02021     TOPPERS_DEFINE_TYPE_NAME(unsigned long long)
02022     TOPPERS_DEFINE_TYPE_NAME(float)
02023     TOPPERS_DEFINE_TYPE_NAME(double)
02024     TOPPERS_DEFINE_TYPE_NAME(long double)
02025     TOPPERS_DEFINE_TYPE_NAME(bool)
02026 
02027     TOPPERS_DEFINE_TYPE_NAME(char*)
02028     TOPPERS_DEFINE_TYPE_NAME(signed char*)
02029     TOPPERS_DEFINE_TYPE_NAME(unsigned char*)
02030     TOPPERS_DEFINE_TYPE_NAME(short*)
02031     TOPPERS_DEFINE_TYPE_NAME(unsigned short*)
02032     TOPPERS_DEFINE_TYPE_NAME(int*)
02033     TOPPERS_DEFINE_TYPE_NAME(unsigned int*)
02034     TOPPERS_DEFINE_TYPE_NAME(long*)
02035     TOPPERS_DEFINE_TYPE_NAME(unsigned long*)
02036     TOPPERS_DEFINE_TYPE_NAME(long long*)
02037     TOPPERS_DEFINE_TYPE_NAME(unsigned long long*)
02038     TOPPERS_DEFINE_TYPE_NAME(float*)
02039     TOPPERS_DEFINE_TYPE_NAME(double*)
02040     TOPPERS_DEFINE_TYPE_NAME(long double*)
02041     TOPPERS_DEFINE_TYPE_NAME(bool*)
02042 
02043     TOPPERS_DEFINE_TYPE_NAME(const char*)
02044     TOPPERS_DEFINE_TYPE_NAME(const signed char*)
02045     TOPPERS_DEFINE_TYPE_NAME(const unsigned char*)
02046     TOPPERS_DEFINE_TYPE_NAME(const short*)
02047     TOPPERS_DEFINE_TYPE_NAME(const unsigned short*)
02048     TOPPERS_DEFINE_TYPE_NAME(const int*)
02049     TOPPERS_DEFINE_TYPE_NAME(const unsigned int*)
02050     TOPPERS_DEFINE_TYPE_NAME(const long*)
02051     TOPPERS_DEFINE_TYPE_NAME(const unsigned long*)
02052     TOPPERS_DEFINE_TYPE_NAME(const long long*)
02053     TOPPERS_DEFINE_TYPE_NAME(const unsigned long long*)
02054     TOPPERS_DEFINE_TYPE_NAME(const float*)
02055     TOPPERS_DEFINE_TYPE_NAME(const double*)
02056     TOPPERS_DEFINE_TYPE_NAME(const long double*)
02057     TOPPERS_DEFINE_TYPE_NAME(const bool*)
02058 
02059 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
02060     TOPPERS_DEFINE_TYPE_NAME(wchar_t)
02061     TOPPERS_DEFINE_TYPE_NAME(wchar_t*)
02062     TOPPERS_DEFINE_TYPE_NAME(const wchar_t*)
02063 #endif
02064 
02065 }
02066 
02067 #endif  // ! TOPPERS_TRACE_HPP_