#ifndef cathlibcpp_hoistbp_H
#define cathlibcpp_hoistbp_H

// File:       hoistbp.h
// Author:     (c) Miles Sabin, 1997
// Purpose:    hoisted binary predicate


#ifndef cathlibcpp_bool_H
#include "bool.h"
#endif

#ifndef cathlibcpp_config_H
#include "config.h"
#endif

#ifndef cathlibcpp_hoistbpp_H
#include "hoistbpp.h"
#endif

#ifndef cathlibcpp_stringfwd_H
#include "stringfwd.h"
#endif


template<class BinaryPredicate, class T>
class HoistBinaryPredicate : public HoistBinaryPredicateProtocol
{
  public:

    // constructors
    HoistBinaryPredicate(BinaryPredicate const& pred)
      : pred_(pred)
      {}

    ~HoistBinaryPredicate();

    // accessors
    bool operator()(void const* x, void const* y) const;

  private:

    BinaryPredicate const& pred_;
};


template<class BinaryPredicate, class T>
inline HoistBinaryPredicate<BinaryPredicate, T> make_hoist_binary_predicate(BinaryPredicate const& pred, T*)
{
  return HoistBinaryPredicate<BinaryPredicate, T>(pred);
}

template<class T>
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(T*);

template<class T>
HoistBinaryPredicateProtocol& get_hoist_less_comparator(T*);


// specializations for builtin types

HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(char*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(short*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(int*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(long*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned char*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned short*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned int*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned long*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(float*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(double*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(string*);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(char**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(char const**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(short**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(int**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(long**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned char**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned char const**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned short**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned int**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(unsigned long**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(float**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(double**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(string**);
HoistBinaryPredicateProtocol& get_hoist_equal_to_comparator(void**);

HoistBinaryPredicateProtocol& get_hoist_less_comparator(char*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(short*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(int*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(long*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned char*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned short*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned int*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned long*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(float*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(double*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(string*);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(char**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(char const**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(short**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(int**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(long**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned char**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned char const**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned short**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned int**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(unsigned long**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(float**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(double**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(string**);
HoistBinaryPredicateProtocol& get_hoist_less_comparator(void**);

#endif
