现在的位置: 首页 > 综合 > 正文

一个很强大的Comparator生成器

2014年01月03日 ⁄ 综合 ⁄ 共 2844字 ⁄ 字号 评论关闭

 

/**
  @brief 生成一个比较器(Comparator),兼键提取(KeyExtractor)类

  使用这个宏生成的比较器可以作用在不同的对象上,只要这些对象有相同名称的成员,
  并且可以作用在类型为成员类型的对象上。

  - 假设:

    - 有 n 个类 class[1], class[2], ... class[n],都有类型为 MemberType ,名称为 MemberName 的数据成员
    - 那么以下类型的对象可以使用该类相互比较,并且可以从这些对象中提取出 MemberType 类型的键:
        class[1] ... class[n], MemberType, 以及所有这些类型的任意级别的指针

  @param ComparatorName 比较器类的名字
  @param MemberType     要比较的对象的成员类型
  @param MemberName     要比较的对象的成员名字,也可以是一个成员函数调用,
                        前面必须加 '.' 或者 '->', 加 '->' 只是为用于 smart_ptr/iterator/proxy 等重载 '->' 的对象
                        当用于裸指针时,仍使用 '.',这意味着裸指针和 smart_ptr/iterator/proxy
                        不能使用同一个生成的 Comparator,虽然裸指针的语法和它们都相同
  @param ComparePred    比较准则,这个比较准则将被应用到 XXXX MemberName

  @note
    - 这个类不是从 ComparePred 继承,为的是可以允许 ComparePred 是个函数,
      但这样(不继承)阻止了编译器进行空类优化
    - 不在内部使用 const MemberType&, 而是直接使用 MemberType, 
      是为了允许 MemberName 是一个函数时,返回一个即时计算出来的 Key;
      - 当为了效率需要使用引用时,将 const MemberType& 作为 MemberType 传进来
    - 当 MemberType 是个指针时,将 Type* 作为 MemberType ,而非 const Type*,即使 MemberType 真的是 const Type*
    - 注意 C++ 参数推导机制:
    @code
      template<T> void f(const T& x) { } // f1
      template<T> void f(const T* x) { } // f2
      template<T> void g(const T& x) { } // g1
      template<T> void g(const T* x) { } // g2
      template<T> void g(      T& x) { } // g3
      template<T> void g(      T* x) { } // g4
      void foo()
      {
         int a;
         const int b;
         f(&a); // call f1, T was deduced as int*, and then convert to 'const int*&', so match f1, not f2
         f(&b); // call f2, T was deduced as int
         g(&a); // call g4, T was deduced as int
         g(&b); // call g2, T was deduced as int
      }
    @endcode
      在上述代码已经表现得比较明白了,这就是要生成四个不同 deref 版本的原因
    - 为了配合上述机制,传入的 MemberType 不要有任何 const 修饰符
 */
#define SAME_NAME_MEMBER_COMPARATOR_EX(ComparatorName, MemberType, MemberName, ComparePred) /
class ComparatorName                                        /
{                                                           /
    ComparePred m_comp;                                     /
public:                                                     /
    typedef bool        result_type;                        /
    typedef MemberType  key_type;                           /
    typedef boost::integral_constant<bool,                  /
        febird::HasTriCompare<ComparePred>::value           /
    > has_tri_compare;                                      /
                                                            /
    ComparatorName()  {}                                    /
    ComparatorName(const ComparePred& rhs)                  /
        : m_comp(rhs) {}                                    /
                                                            /
    template<class T>const T&deref(T*x)const{return*x;}     /
    template<class T>const T&deref(T&x)const{return x;}     /
    template<class T>const T&deref(const T*x)const{return*x;}/
    template<class T>const T&deref(const T&x)const{return x;}/
                                                            /
    const MemberType operator()(const MemberType x)const{return x;} /
    template<class T>const MemberType operator()(const T&x)const{return deref(x)MemberName;}/
                                                            /
    template<class Tx, class Ty>                            /
    bool operator()(const Tx&x, const Ty&y) const           /
    {                                                       /
        return m_comp((*this)(x),(*this)(y));               /
    }                                                       /
    template<class Tx, class Ty>                            /
    int compare(const Tx&x, const Ty&y) const               /
    {                                                       /
        return m_comp.compare((*this)(x),(*this)(y));       /
    }                                                       /
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#endif

// #define SAME_NAME_MEMBER_COMPARATOR_EX(ComparatorName, MemberType, MemberName, ComparePred)  /
// SAME_NAME_MEMBER_COMPARATOR_EX_NO_TRAITS(ComparatorName, MemberType, MemberName, ComparePred)/
// BOOST_TT_AUX_BOOL_TRAIT_SPEC1(HasTriCompare, ComparatorName, HasTriCompare<ComparePred>::value)

//! note@ if MemberType must not be a reference, neither const nor non-const
#define SAME_NAME_MEMBER_COMPARATOR(ComparatorName, MemberType, MemberName) /
    SAME_NAME_MEMBER_COMPARATOR_EX(ComparatorName, MemberType, MemberName, std::less<MemberType>)

抱歉!评论已关闭.