《STL源码剖析》—— stl_config.h

参考侯捷《STL源码剖析》
#ifndef __STL_CONFIG_H
# define __STL_CONFIG_H

// 本文件所做的事情:
//  (1)  如果编译器没有定义 bool,true,false,就定义它们
//  (2)  如果编译器的标准程序库未支持 drand48() 函数,就定义 __STL_NO_DRAND48
//  (3)  如果编译器无法处理 static member of template classes(模板类的静态成员),就定义 __STL_STATIC_TEMPLATE_MEMBER_BUG
//  (4)  如果编译器未支持关键词 typename,就将‘typename’定义为一个 null macro(空的宏).
//  (5)  如果编译器支持 partial specialization of class templates(模板类的部分特化),
//       就定义 __STL_CLASS_PARTIAL_SPECIALIZATION.
//  (6)  如果编译器支持 partial ordering of function templates (亦称为 partial specialization of function templates),
//       就定义 __STL_FUNCTION_TMPL_PARTIAL_ORDER
//  (7)  如果编译器允许我们在调用一个 function template 时可以明白指定其 template arguments,
//       就定义__STL_EXPLICIT_FUNCTION_TMPL_ARGS
//  (8)  如果编译器支持 template members of classes,就定义 __STL_MEMBER_TEMPLATES 
//  (9)  如果编译器不支持关键词 explicit ,就定义 ‘explicit’为一个 null macro.    
//  (10) 如果编译器无法根据前一个 template parameters 设定下一个 template parameters 的默认值,
//       就定义 __STL_LIMITED_DEFAULT_TEMPLATES 
//  (11) 如果编译器针对 non-type template parameters 执行 function template 的参数推导(argument deduction)时有问题,
//       就定义 __STL_NON_TYPE_TMPL_PARAM_BUG
//  (12) 如果编译器无法支持迭代器的 operator->,就定义 __SGI_STL_NO_ARROW_OPERATOR
//  (13) 如果编译器(在你所选择的模式中)支持 exceptions,就定义 __STL_USE_EXCEPTIONS
//  (14) 如果我们将 STL 放入命名空间中,则定义 __STL_USE_NAMESPACES 
//  (15) 如果本程序库由 SGI 编译器来编译,并且使用这并未选择 pthreads 或其他 threads,就定义 __STL_SGI_THREADS
//  (16) 如果本程序由一个 WIN32 编译器编译,并且在多线程模式下,就定义 __STL_WIN32THREADS
//  (17) 适当地定义与namespace 相关的 macros (如 __STD, __STL_BEGIN_NAMESPACE, 等.)
//  (18) 适当地定义与exception 相关的 macros (如 __STL_TRY, __STL_UNWIND, 等.)
//  (19) 根据 __STL_ASSERTIONS 是否定义,将 __stl_assert 定义为一个测试操作或一个 null macro

// 通过对上面注释的翻译,知道该文件会根据各家不同的编译器以及可能的不同版本,给予一些常量的定义。
// 这些常量中绝大部分都与模板(template)相关,包括 3,5,6,7,8,10,11

#ifdef _PTHREADS
#   define __STL_PTHREADS
#endif

// 使用 SGI STL 但却不是用 GNU C++:这里如果我们在Linux下编译SGI STL的话,下面包括的内容就可以不用考虑。
// 因为Linux上的编译器就是 GNU C++
# if defined(__sgi) && !defined(__GNUC__)
#   if !defined(_BOOL)
#     define __STL_NEED_BOOL
#   endif
#   if !defined(_TYPENAME_IS_KEYWORD)
#     define __STL_NEED_TYPENAME
#   endif
#   ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES
#     define __STL_CLASS_PARTIAL_SPECIALIZATION
#   endif
#   ifdef _MEMBER_TEMPLATES
#     define __STL_MEMBER_TEMPLATES
#   endif
#   if !defined(_EXPLICIT_IS_KEYWORD)
#     define __STL_NEED_EXPLICIT
#   endif
#   ifdef __EXCEPTIONS
#     define __STL_USE_EXCEPTIONS
#   endif
#   if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES)
#     define __STL_USE_NAMESPACES
#   endif 
#   if !defined(_NOTHREADS) && !defined(__STL_PTHREADS)
#     define __STL_SGI_THREADS
#   endif
# endif

// 下面是GNU C++ 编译器,从下面可以看出如果版本低于 2.8 的GNU C++ 和高于 2.8 版本的之间的不同,
// 例如高于2.8的版本支持类中的模板成员了(因为定义了_STL_MEMBER_TEMPLATES)
# ifdef __GNUC__
#   include <_G_config.h>
#   if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
#     define __STL_STATIC_TEMPLATE_MEMBER_BUG
#     define __STL_NEED_TYPENAME
#     define __STL_NEED_EXPLICIT
#   else
#     define __STL_CLASS_PARTIAL_SPECIALIZATION
#     define __STL_FUNCTION_TMPL_PARTIAL_ORDER
#     define __STL_EXPLICIT_FUNCTION_TMPL_ARGS
#     define __STL_MEMBER_TEMPLATES
#   endif
    /* glibc pre 2.0 is very buggy. We have to disable thread for it.
       It should be upgraded to glibc 2.0 or later. */
#   if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS)
#     define __STL_PTHREADS
#   endif
#   ifdef __EXCEPTIONS
#     define __STL_USE_EXCEPTIONS
#   endif
# endif

# if defined(__SUNPRO_CC) 
#   define __STL_NEED_BOOL
#   define __STL_NEED_TYPENAME
#   define __STL_NEED_EXPLICIT
#   define __STL_USE_EXCEPTIONS
# endif

# if defined(__COMO__)
#   define __STL_MEMBER_TEMPLATES
#   define __STL_CLASS_PARTIAL_SPECIALIZATION
#   define __STL_USE_EXCEPTIONS
#   define __STL_USE_NAMESPACES
# endif

// 下面是 VC 编译器的部分
# if defined(_MSC_VER)
#   if _MSC_VER > 1000
#     include <yvals.h>
#   else
#     define __STL_NEED_BOOL
#   endif
#   define __STL_NO_DRAND48
#   define __STL_NEED_TYPENAME
#   if _MSC_VER < 1100
#     define __STL_NEED_EXPLICIT
#   endif
#   define __STL_NON_TYPE_TMPL_PARAM_BUG
#   define __SGI_STL_NO_ARROW_OPERATOR
#   ifdef _CPPUNWIND
#     define __STL_USE_EXCEPTIONS
#   endif
#   ifdef _MT
#     define __STL_WIN32THREADS
#   endif
# endif

# if defined(__BORLANDC__)
#   define __STL_NO_DRAND48
#   define __STL_NEED_TYPENAME
#   define __STL_LIMITED_DEFAULT_TEMPLATES
#   define __SGI_STL_NO_ARROW_OPERATOR
#   define __STL_NON_TYPE_TMPL_PARAM_BUG
#   ifdef _CPPUNWIND
#     define __STL_USE_EXCEPTIONS
#   endif
#   ifdef __MT__
#     define __STL_WIN32THREADS
#   endif
# endif

// 从这里开始,编译器特性的分析已经结束了,需要对分析结果进行处理了。
# if defined(__STL_NEED_BOOL)
    typedef int bool;
#   define true 1
#   define false 0
# endif

# ifdef __STL_NEED_TYPENAME
#   define typename
# endif

# ifdef __STL_NEED_EXPLICIT
#   define explicit
# endif

# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS
#   define __STL_NULL_TMPL_ARGS <>
# else
#   define __STL_NULL_TMPL_ARGS
# endif

# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
#   define __STL_TEMPLATE_NULL template<>
# else
#   define __STL_TEMPLATE_NULL
# endif

// 注释(14)
// __STL_NO_NAMESPACES is a hook so that users can disable namespaces
// without having to edit library headers.
# if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES)
#   define __STD std
#   define __STL_BEGIN_NAMESPACE namespace std {
#   define __STL_END_NAMESPACE }
#   define  __STL_USE_NAMESPACE_FOR_RELOPS
#   define __STL_BEGIN_RELOPS_NAMESPACE namespace std {
#   define __STL_END_RELOPS_NAMESPACE }
#   define __STD_RELOPS std
# else
#   define __STD 
#   define __STL_BEGIN_NAMESPACE 
#   define __STL_END_NAMESPACE 
#   undef  __STL_USE_NAMESPACE_FOR_RELOPS
#   define __STL_BEGIN_RELOPS_NAMESPACE 
#   define __STL_END_RELOPS_NAMESPACE 
#   define __STD_RELOPS 
# endif

// 注释(18)
# ifdef __STL_USE_EXCEPTIONS 
#   define __STL_TRY try
#   define __STL_CATCH_ALL catch(...)
#   define __STL_RETHROW throw
#   define __STL_NOTHROW throw()
#   define __STL_UNWIND(action) catch(...) { action; throw; }
# else
#   define __STL_TRY 
#   define __STL_CATCH_ALL if (false)
#   define __STL_RETHROW 
#   define __STL_NOTHROW 
#   define __STL_UNWIND(action) 
# endif

// 注释(19)
#ifdef __STL_ASSERTIONS
# include <stdio.h>
# define __stl_assert(expr) \
    if (!(expr)) { fprintf(stderr, "%s:%d STL assertion failure: %s\n", \
			  __FILE__, __LINE__, # expr); abort(); }
#else
# define __stl_assert(expr)
#endif

#endif /* __STL_CONFIG_H */


   

你可能感兴趣的:(源码,STL)