c++ rtti-plus-0.0.4 for gcc-4.5.1,可以使用通用的 Save Load函数(一) typeinfo

[ 2012-03-31 20:15:03 | 作者: Admin ]
: | |
//======================typeinfo=================================
// RTTI support for -*- C++ -*-
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
// 2003, 2004, 2005, 2006, 2007, 2009, 2010
// Free Software Foundation
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.

/** @file typeinfo
* This is a Standard C++ Library header.
*/

#ifndef _TYPEINFO
#define _TYPEINFO

#pragma GCC system_header

#include <exception>

#pragma GCC visibility push(default)

extern "C++" {

namespace __cxxabiv1
{
class __class_type_info;
} // namespace __cxxabiv1

// Determine whether typeinfo names for the same type are merged (in which
// case comparison can just compare pointers) or not (in which case strings
// must be compared), and whether comparison is to be implemented inline or
// not. We used to do inline pointer comparison by default if weak symbols
// are available, but even with weak symbols sometimes names are not merged
// when objects are loaded with RTLD_LOCAL, so now we always use strcmp by
// default. For ABI compatibility, we do the strcmp inline if weak symbols
// are available, and out-of-line if not. Out-of-line pointer comparison
// is used where the object files are to be portable to multiple systems,
// some of which may not be able to use pointer comparison, but the
// particular system for which libstdc++ is being built can use pointer
// comparison; in particular for most ARM EABI systems, where the ABI
// specifies out-of-line comparison. The compiler's target configuration
// can override the defaults by defining __GXX_TYPEINFO_EQUALITY_INLINE to
// 1 or 0 to indicate whether or not comparison is inline, and
// __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to indicate whether or not pointer
// comparison can be used.

#ifndef __GXX_MERGED_TYPEINFO_NAMES
// By default, typeinfo names are not merged.
#define __GXX_MERGED_TYPEINFO_NAMES 0
#endif

// By default follow the old inline rules to avoid ABI changes.
#ifndef __GXX_TYPEINFO_EQUALITY_INLINE
#if !__GXX_WEAK__
#define __GXX_TYPEINFO_EQUALITY_INLINE 0
#else
#define __GXX_TYPEINFO_EQUALITY_INLINE 1
#endif
#endif

namespace std
{
/**
* @brief Part of RTTI.
*
* The @c type_info class describes type information generated by
* an implementation.
*/
  struct type_info;
  struct member_info{
    const type_info*__type;//
    const char * __name;//名称
    const long __offset;//偏移量
  };
  class type_info_ext{
  public:
     const long __version;
const char *__name;
const member_info* __member_info;//如果成员变量数为0或是数组和指针类型变量,置0
const long __member_count;
const type_info * __complete_type_info;//用于数组和指针类型变量,如果不是指针或数组,置0 ,只对成员对象有效,对 int*等数组或指针无效

explicit type_info_ext(const long __v,const char *__n,const member_info *__m_i,const int __m_c,const type_info*__t_i):
    __version(__v),__name(__n),__member_info(__m_i),__member_count(__m_c),__complete_type_info(__t_i){ }/*explicit防止自动转换操作*/

  };
class type_info
{
public:
/** Destructor first. Being the first non-inline virtual function, this
* controls in which translation unit the vtable is emitted. The
* compiler makes use of that information to know where to emit
* the runtime-mandated type_info structures in the new-abi. */
virtual ~type_info();

/** Returns an @e implementation-defined byte string; this is not
* portable between compilers! */
const char* name() const {
      if(((const unsigned char*)__ext)[0]>=0x20){
        return ((const unsigned char*)__ext)[0]=='*' ? ((const char*)__ext) +1:((const char*)__ext);
      }else{
        return __ext->__name[0] == '*' ? __ext->__name + 1 : __ext->__name;
      }
    }
/*------------------add by den-----------------*/
    const int get_member_count() const {return __ext->__member_count;}
    const member_info *get_member_info()const {return __ext->__member_info;}
    const type_info *get_type_info()const {return __ext->__complete_type_info;}
/*---------------------add end-------------------------------*/
#if !__GXX_TYPEINFO_EQUALITY_INLINE
// In old abi, or when weak symbols are not supported, there can
// be multiple instances of a type_info object for one
// type. Uniqueness must use the _name value, not object address.
bool before(const type_info& __arg) const;
bool operator==(const type_info& __arg) const;
#else
#if !__GXX_MERGED_TYPEINFO_NAMES
/** Returns true if @c *this precedes @c __arg in the implementation's
* collation order. */
// Even with the new abi, on systems that support dlopen
// we can run into cases where type_info names aren't merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const
{ return (name()[0] == '*' && __arg.name()[0] == '*')  ? name() < __arg.name():__builtin_strcmp (name(), __arg.name()) < 0; }

bool operator==(const type_info& __arg) const
{
return ((name() == __arg.name()) || (name()[0] != '*' && __builtin_strcmp (name(), __arg.name()) == 0));
}
#else
// On some targets we can rely on type_info's NTBS being unique,
// and therefore address comparisons are sufficient.
bool before(const type_info& __arg) const { return name() < __arg.name(); }

bool operator==(const type_info& __arg) const { return name() == __arg.name(); }
#endif
#endif
bool operator!=(const type_info& __arg) const { return !operator==(__arg); }

// Return true if this is a pointer type of some kind
virtual bool __is_pointer_p() const;

// Return true if this is a function type
virtual bool __is_function_p() const;

// Try and catch a thrown type. Store an adjusted pointer to the
// caught type in THR_OBJ. If THR_TYPE is not a pointer type, then
// THR_OBJ points to the thrown object. If THR_TYPE is a pointer
// type, then THR_OBJ is the pointer itself. OUTER indicates the
// number of outer pointers, and whether they were const
// qualified.
virtual bool __do_catch(const type_info *__thr_type, void **__thr_obj,
       unsigned __outer) const;

// Internally used during catch matching
virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target,
       void **__obj_ptr) const;

protected:
    const type_info_ext *__ext;
explicit type_info(const char *__n):    __ext((type_info_ext*)__n){ }/*explicit防止自动转换操作*/
private:
/// Assigning type_info is not supported.
type_info& operator=(const type_info&);
type_info(const type_info&);
};

/**
* @brief Thrown during incorrect typecasting.
* @ingroup exceptions
*
* If you attempt an invalid @c dynamic_cast expression, an instance of
* this class (or something derived from this class) is thrown. */
class bad_cast : public exception
{
public:
bad_cast() throw() { }

// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_cast() throw();

// See comment in eh_exception.cc.
virtual const char* what() const throw();
};

/**
* @brief Thrown when a NULL pointer in a @c typeid expression is used.
* @ingroup exceptions
*/
class bad_typeid : public exception
{
public:
bad_typeid () throw() { }

// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_typeid() throw();

// See comment in eh_exception.cc.
virtual const char* what() const throw();
};
} // namespace std

#pragma GCC visibility pop

} // extern "C++"
#endif
[最后修改由 Admin, 于 2013-04-13 13:53:42]
评论Feed 评论Feed: http://www.vTalkback.com/blog/feed.asp?q=comment&id=203

浏览模式: 显示全部 | 评论: 2 | 引用: 0 | 排序 | 浏览: 3905
引用 Admin
[ 2012-04-03 20:32:17 ]
将原有的成员变量指针__name改为 type_info_ext *__ext
__ext中保存类的成员变量信息
在编写Save函数时可以通过遍历 __ext 来实现

也就是说只要在基类中写一个通用的Save函数就行了
调用基类的Save函数可以保存子类的成员变量

不仅仅是Save、Load函数,对象的其他一些通用行为也可以这样做
象Clone,Copy,Instance,Assign,Compare,拷贝构造函数等等,
还可以在基类的析构函数中释放子类的资源,
对于有数百个类的程序可以节省很多工作,
比如GUI界面编辑器,类似VISIO的绘图工具
[最后修改由 Admin, 于 2012-4-3 20:32:17]
引用 Admin
[ 2012-04-03 20:35:47 ]
下一版将用一个宏定义和一个编译选项来禁用此功能

发表
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:  
验证码 * 请输入验证码