From a74bfbafc8baeaacf78396f458a7db0b4048e769 Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Thu, 1 Jun 2023 23:58:15 -0500 Subject: [PATCH] Explicitly define namespaces in headers instead of relying on include site (#27) * Explicitly define namespaces in headers instead of relying on include site The old way was supposedly undefined behavior according to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105707 and began causing the build to fail on GCC 12.2. Explicitly declaring the namespaces within the headers themselves fixes the build and doesn't seem like it would have unintended consequences (most of the headers are private and only included once anyway). Also some fixes for the CI which has long languished. EP-209 --- .github/workflows/linux-ci.yml | 2 +- .github/workflows/mac-ci.yml | 6 +++--- CMakeLists.txt | 2 +- cpptcl/cpptcl.h | 27 ++++++++++++++++++++++++--- cpptcl/cpptcl_object.h | 4 ++++ cpptcl/details/bind.h | 4 ++++ cpptcl/details/callbacks.h | 6 ++++++ cpptcl/details/callbacks_v.h | 6 ++++++ cpptcl/details/constructors.h | 5 +++++ cpptcl/details/conversions.h | 4 ++++ cpptcl/details/dispatchers.h | 6 ++++++ cpptcl/details/metahelpers.h | 5 +++++ cpptcl/details/methods.h | 5 +++++ cpptcl/details/methods_v.h | 5 +++++ 14 files changed, 79 insertions(+), 8 deletions(-) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 452c4d4..0c13588 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -9,7 +9,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/mac-ci.yml b/.github/workflows/mac-ci.yml index 3f75a7a..5a7d668 100644 --- a/.github/workflows/mac-ci.yml +++ b/.github/workflows/mac-ci.yml @@ -9,7 +9,7 @@ on: jobs: build: - runs-on: macos-latest + runs-on: macos-11 steps: - uses: actions/checkout@v2 @@ -18,8 +18,8 @@ jobs: brew update brew install tcl-tk || true sudo mkdir -p /usr/local - sudo ln -sf /usr/local/opt/tcl-tk/include /usr/local/include/tcl8.6 - sudo cp /usr/local/opt/tcl-tk/lib/libtcl* /usr/local/lib + sudo ln -sf /usr/local/opt/tcl-tk/include/tcl-tk /usr/local/include/tcl8.6 + sudo install /usr/local/opt/tcl-tk/lib/libtcl* /usr/local/lib sudo ln -sf /usr/local/opt/tcl-tk/bin/tclsh8.6 /usr/local/bin/tclsh sudo ln -sf /usr/local/opt/tcl-tk/bin/tclsh8.6 /usr/local/bin/tclsh8.6 - name: make diff --git a/CMakeLists.txt b/CMakeLists.txt index d2741e5..1ad5c84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(cpptcl) include(cmake/version.cmake) load_git_properties(cpptcl ${CMAKE_BINARY_DIR}/generated) -set(CPPTCL_VERSION 2.2.5) +set(CPPTCL_VERSION 2.2.8) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to Release as none was specified.") diff --git a/cpptcl/cpptcl.h b/cpptcl/cpptcl.h index 7a748d6..1852a6c 100644 --- a/cpptcl/cpptcl.h +++ b/cpptcl/cpptcl.h @@ -110,12 +110,20 @@ void set_result(Tcl_Interp *interp, std::string const &s); void set_result(Tcl_Interp *interp, void *p); void set_result(Tcl_Interp *interp, object const &o); +} + +} + // helper functor for converting Tcl objects to the given type #include "cpptcl/details/conversions.h" // dispatchers able to capture (or ignore) the result #include "cpptcl/details/dispatchers.h" +namespace Tcl { + +namespace details { + // helper for checking for required number of parameters // (throws tcl_error when not met) void check_params_no(int objc, int required, const std::string &message); @@ -123,7 +131,7 @@ void check_params_no(int objc, int required, const std::string &message); // helper for gathering optional params in variadic functions object get_var_params(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int from, policies const &pol); -// the callback_base is used to store callback handlers in a polynorphic map +// the callback_base is used to store callback handlers in a polymorphic map class callback_base { public: virtual ~callback_base() {} @@ -190,6 +198,10 @@ template class class_handler : public class_handler_base { } }; +} + +} + // factory functions for creating class objects #include "cpptcl/details/constructors.h" @@ -202,6 +214,10 @@ template class class_handler : public class_handler_base { // helper meta function for figuring appropriate constructor callback #include "cpptcl/details/metahelpers.h" +namespace Tcl { + +namespace details { + // this class is used to provide the "def" interface for defining // class member functions @@ -444,8 +460,12 @@ class interpreter { bool owner_; }; +} + #include "cpptcl/cpptcl_object.h" +namespace Tcl { + // the InputIterator should give object& or Tcl_Obj* when dereferenced template details::result interpreter::eval(InputIterator first, InputIterator last) { std::vector v; @@ -458,7 +478,7 @@ template details::result interpreter::eval(InputIterator f return details::result(interp_); } -namespace details { +} // additional callback envelopes for variadic functions #include "cpptcl/details/callbacks_v.h" @@ -466,10 +486,11 @@ namespace details { // additional method envelopes for variadic methods #include "cpptcl/details/methods_v.h" -} // namespace details #include "cpptcl/details/bind.h" +namespace Tcl { + inline std::ostream & operator<<(std::ostream &os, const object& obj) { return os << obj.get(); diff --git a/cpptcl/cpptcl_object.h b/cpptcl/cpptcl_object.h index 2d8cb18..a1f54ac 100644 --- a/cpptcl/cpptcl_object.h +++ b/cpptcl/cpptcl_object.h @@ -8,6 +8,8 @@ #ifndef CPPTCL_OBJECT_H #define CPPTCL_OBJECT_H +namespace Tcl { + class object; /* @@ -243,4 +245,6 @@ template <> char const *object::get(interpreter &i) const; template <> std::string object::get(interpreter &i) const; template <> std::vector object::get>(interpreter &i) const; +} + #endif /* CPPTCL_OBJECT_H */ diff --git a/cpptcl/details/bind.h b/cpptcl/details/bind.h index f731c4e..a66414f 100644 --- a/cpptcl/details/bind.h +++ b/cpptcl/details/bind.h @@ -1,3 +1,5 @@ +namespace Tcl { + template struct Bind { private: object cmd_; @@ -173,3 +175,5 @@ template struct Bindeval(obj)); } }; + +} diff --git a/cpptcl/details/callbacks.h b/cpptcl/details/callbacks.h index ac60f01..e06902e 100644 --- a/cpptcl/details/callbacks.h +++ b/cpptcl/details/callbacks.h @@ -13,6 +13,8 @@ #include #include +namespace Tcl { namespace details { + template class callback0 : public callback_base { typedef R (*functor_type)(); @@ -213,3 +215,7 @@ template class callback1 : public callback_base { typedef object const &T1; typedef R (*functor_type)(T1); @@ -199,3 +201,7 @@ template struct construct { static C *doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { return new C(t1, t2, t3, t4, t5, t6, t7, t8, t9); } @@ -49,3 +50,7 @@ template struct construct struct construct { static C *doit() { return new C(); } }; + +} + +} diff --git a/cpptcl/details/conversions.h b/cpptcl/details/conversions.h index ff12740..6d1eaa8 100644 --- a/cpptcl/details/conversions.h +++ b/cpptcl/details/conversions.h @@ -13,6 +13,7 @@ // helper functor for converting Tcl objects to the given type // (it is a struct instead of function, // because I need to partially specialize it) +namespace Tcl { namespace details { template struct tcl_cast; @@ -65,3 +66,6 @@ template <> struct tcl_cast { static char const *from(Tcl_Interp * template <> struct tcl_cast { static object from(Tcl_Interp *, Tcl_Obj *, bool byReference = false); }; +} + +} diff --git a/cpptcl/details/dispatchers.h b/cpptcl/details/dispatchers.h index 9a1e93b..b1998b9 100644 --- a/cpptcl/details/dispatchers.h +++ b/cpptcl/details/dispatchers.h @@ -14,6 +14,8 @@ // capture its return value // further dispatch specialization ignores the res +namespace Tcl { namespace details { + template struct dispatch { template static void do_dispatch(Tcl_Interp *interp, Functor f) { R res = f(); @@ -87,3 +89,7 @@ template <> struct dispatch { template static void do_dispatch(Tcl_Interp *, Functor f, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) { f(t1, t2, t3, t4, t5, t6, t7, t8, t9); } }; + +} + +} diff --git a/cpptcl/details/metahelpers.h b/cpptcl/details/metahelpers.h index d87cfa8..b3436d7 100644 --- a/cpptcl/details/metahelpers.h +++ b/cpptcl/details/metahelpers.h @@ -9,6 +9,7 @@ // // Note: this file is not supposed to be a stand-alone header +namespace Tcl { namespace details { template struct get_callback_type_for_construct { typedef callback9 type; }; @@ -29,3 +30,7 @@ template struct get_callback_type_for_constr template struct get_callback_type_for_construct { typedef callback1 type; }; template struct get_callback_type_for_construct { typedef callback0 type; }; + +} + +} diff --git a/cpptcl/details/methods.h b/cpptcl/details/methods.h index 34029ff..ef33cd4 100644 --- a/cpptcl/details/methods.h +++ b/cpptcl/details/methods.h @@ -9,6 +9,7 @@ // // Note: this file is not supposed to be a stand-alone header +namespace Tcl { namespace details { template class method0 : public object_cmd_base { typedef R (C::*mem_type)(); @@ -302,3 +303,7 @@ template class method1 : public object_cmd_base { typedef object const &T1; @@ -261,3 +262,7 @@ template