# C++ language checks AC_DEFUN(AC_CXX_STDHEADERS, [ AC_SUBST(cxx_have_stdheaders) AC_MSG_CHECKING(whether C++ supports the ISO C++ standard includes) AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([#include ],[std::ostream *o; return 0;], db_cv_cxx_have_stdheaders=yes, db_cv_cxx_have_stdheaders=no) AC_LANG_RESTORE AC_MSG_RESULT($db_cv_cxx_have_stdheaders) if test "$db_cv_cxx_have_stdheaders" = yes; then cxx_have_stdheaders="#define HAVE_CXX_STDHEADERS 1" fi]) AC_DEFUN(AC_CXX_WSTRING, [ AC_MSG_CHECKING(whether C++ supports the wstring class) AC_SUBST(WSTRING_decl) AC_LANG_PUSH(C++) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]] [[std::wstring ws; ws.find_first_of(ws);]]), [WSTRING_decl="#define HAVE_WSTRING 1" ; AC_MSG_RESULT(yes)], [WSTRING_decl="#undef HAVE_WSTRING" ; AC_MSG_RESULT(no)]]) AC_LANG_POP(C++) ]) AC_DEFUN(AC_CXX_SUPPORTS_TEMPLATES, [ AC_MSG_CHECKING(whether the C++ compiler supports templates for STL) AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE([#include #include #include using std::string; using std::vector; namespace dbstl_configure_test { template class MyClass { public: explicit MyClass(int i) { imem = i;} MyClass(const T1& t1, const T2& t2, int i) { mem1 = t1; mem2 = t2; imem = i; } template T2 templ_mem_func(T1 t1, T3 t3) { mem2 = t1; T3 t32 = t3; T2 t2; return t2; } double templ_mem_func(T1 t1, double t3) { mem1 = t1; double t32 = t3; return t3; } template ReturnType templ_mem_func(T7, T8); operator T1() const {return mem1;} private: T1 mem1; T2 mem2; int imem; }; template template ReturnType MyClass::templ_mem_func(T7, T8) { ReturnType rt; return rt; } template<> class MyClass { public: explicit MyClass(int i) { imem = i;} MyClass(const double& t1, const float& t2, int i) { mem1 = t1; mem2 = t2; imem = i; } template float templ_mem_func(double t1, T3 t3) { mem2 = t1; T3 t32 = t3; float t2; return t2; } double templ_mem_func(double t1, double t3) { mem1 = t1; double t32 = t3; return t3; } template ReturnType templ_mem_func(T7, T8); operator double() const {return mem1;} private: double mem1; float mem2; int imem; }; template ReturnType MyClass::templ_mem_func(T7, T8) { ReturnType rt; return rt; } template class MyClass2 { public: MyClass2(const T1& t1, const T2&t2){} }; // partial specialization: both template parameters have same type template class MyClass2 { public: MyClass2(const T& t1, const T&t2){} }; // partial specialization: second type is int template class MyClass2 { public: MyClass2(const T& t1, const int&t2){} }; // partial specialization: both template parameters are pointer types template class MyClass2 { public: MyClass2(const T1* t1, const T2*t2){} }; template class MyClass2 { public: MyClass2(const T* t1, const T*t2){} }; template int part_spec_func(T4 t4, T5 t5) { // Zero Initialization should work. T4 t44 = T4(); T5 t55 = T5(); t44 = t4; t55 = t5; } template int part_spec_func(T4 t4, std::vector t55) { T4 t44 = t4; std::vector abc = t55; } // maximum of two int values inline int const& max (int const& a, int const& b) { return a inline T2 const max (T1 const& a, T2 const& b) { return a inline T const& max (T const& a, T const& b) { return a inline T const& max (T const& a, T const& b, T const& c) { return max (max(a,b), c); } template class Base { public: void exit2(){} Base(){} }; template class Derived : public Base { public: // Call Base() explicitly here, otherwise can't access it. // Kind of like this->. Derived() : Base(){} void foo() { this->exit2(); } }; } // dbstl_configure_test using namespace dbstl_configure_test;], [ char cc = 'a'; int i = 4; double pi = 3.14; float gold = 0.618; MyClass2 mif(i, gold); // uses MyClass2 MyClass2 mff(gold, gold); // uses MyClass2 MyClass2 mfi(gold, i); // uses MyClass2 MyClass2 mp(&i, &gold); // uses MyClass2 MyClass2 m(&i, &i); // uses MyClass2 MyClass obj1(i); obj1.templ_mem_func(cc, pi); obj1.templ_mem_func(cc, gold); obj1.templ_mem_func(i, pi); obj1.templ_mem_func(cc, cc); char ch = (char)obj1; string str1("abc"), str2("def"); MyClass obj2(str1.c_str(), str2, i); obj2.templ_mem_func("klm", str2); obj2.templ_mem_func("hij", pi); // Use j to help distinguish, otherwise unable to use the one defined // outside of class body. int j = obj2.templ_mem_func(cc, cc); // Call explicitly. obj2.templ_mem_func(gold, pi); const char *pch = (const char*)obj2; MyClass obj3(pi, gold, i); obj3.templ_mem_func(pi, i); obj3.templ_mem_func(pi, str1); obj3.templ_mem_func(pi, pi); obj3.templ_mem_func(cc, pi); obj3.templ_mem_func(cc, cc); double tmpd = (double)obj3; MyClass obj4(i); obj4.templ_mem_func(pi, i); obj4.templ_mem_func(pi, str1); obj4.templ_mem_func(pi, pi); obj4.templ_mem_func(gold, pi); tmpd = (double)obj4; // Function template partial specialization. part_spec_func(pi, gold); part_spec_func(gold, i); part_spec_func(str1, str2); std::vector strv; part_spec_func(str1, strv); std::vector dblv; part_spec_func(pi, dblv); // Function template overloads and explicit call and deduction. dbstl_configure_test::max(7, 42, 68); // calls the template for three arguments dbstl_configure_test::max(7.0, 42.0); // calls max (by argument deduction) dbstl_configure_test::max('a', 'b'); // calls max (by argument deduction) dbstl_configure_test::max(7, 42.0); dbstl_configure_test::max(4,4.2); // instantiate T as double dbstl_configure_test::max(7, 42); // calls the nontemplate for two ints dbstl_configure_test::max<>(7, 42); // calls max (by argument deduction) dbstl_configure_test::max(7, 42); // calls max (no argument deduction) dbstl_configure_test::max('a', 42.7); // calls the nontemplate for two ints Base bobj; bobj.exit2(); // Using this-> to access base class members. Derived dobj; dobj.foo(); dobj.exit2(); ], AC_MSG_RESULT(yes), AC_MSG_ERROR(no)) AC_LANG_RESTORE ])