Skip to content

Handle specialized template functions#117

Merged
svenevs merged 6 commits intosvenevs:masterfrom
hidmic:specialized-template-functions
Dec 30, 2021
Merged

Handle specialized template functions#117
svenevs merged 6 commits intosvenevs:masterfrom
hidmic:specialized-template-functions

Conversation

@hidmic
Copy link
Copy Markdown
Collaborator

@hidmic hidmic commented Oct 8, 2021

Precisely what the title says. It does so by differentiating empty lists of template parameters from no template parameters at all.

Needs breathe-doc/breathe#750 (or breathe won't pick specialized template functions to begin with).

@svenevs
Copy link
Copy Markdown
Owner

svenevs commented Oct 14, 2021

diff --git a/requirements.txt b/requirements.txt
index 432ca19..90c72b3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
 bs4            # BeautifulSoup!
 lxml           # We need the lxml backend for BeautifulSoup.
 sphinx>=1.6.1  # Exhale is a Sphinx extension.  1.6 introduces logging API.
-breathe        # The directives used for documentation come from the excellent Breathe.
+# breathe        # The directives used for documentation come from the excellent Breathe.
+git+https://github.com/michaeljones/breathe@refs/pull/750/merge
 six            # Primarily for Unicode string types
diff --git a/testing/tests/cpp_func_overloads.py b/testing/tests/cpp_func_overloads.py
index 8f55d9a..81ee6f4 100644
--- a/testing/tests/cpp_func_overloads.py
+++ b/testing/tests/cpp_func_overloads.py
@@ -93,7 +93,7 @@ class CPPFuncOverloads(ExhaleTestCase):
     def test_builds(self):
         """Test deliberately kept to serve as a perpetual reminder this is still broken."""
         self.app.build()
-        if False:  # set to True, and run: tox -e py -- -k cpp_func_overloads -s
+        if True:  # set to True, and run: tox -e py -- -k cpp_func_overloads -s
             import ipdb  #                 then you can view the results
             ipdb.set_trace()
             print("hi there")

If you apply the above patch then it will build and pause so that you can examine testing/projects/cpp_func_overloads/docs_CPPFuncOverloads_test_builds/_build/html/index.html. That said, I'm not sure what the changes to breathe are that require it, the function renders fine with or without the change to requirements.txt (and deleting / recreating .tox directory).

In order to merge this, I need to understand that change to breathe. If the change is required, then we need some kind of version switch selection in exhale.

FWIW the rest of the function overload tests are still somewhat catastrophically broken and I'm not intending on fixing that anytime soon. The options reported by breathe can be explicitly hacked in and still it will not resolve. It's a very complicated issue, which you'll likely hit soon.

@hidmic
Copy link
Copy Markdown
Collaborator Author

hidmic commented Oct 18, 2021

@svenevs see 4474a37.

Also, changing the requirements.txt file won't affect tox virtual environments. The following does:

diff --git a/tox.ini b/tox.ini
index 580c789..2ee0002 100644
--- a/tox.ini
+++ b/tox.ini
@@ -11,11 +11,11 @@ skip_install = true
 # This way, if the variable is not set, it uses the latest version.
 deps =
     sphinx{env:SPHINX_VERSION:}
-    breathe{env:BREATHE_VERSION:}
     bs4
     lxml
     six
 commands =
+    {envpython} -m pip install --no-build-isolation git+https://github.com/michaeljones/breathe@refs/pull/750/merge
     {envpython} -m pip install -q -r requirements-dev.txt
     pytest . {posargs}
     {envpython} -c 'import sphinx; print("Tested against Sphinx version %s." % sphinx.__version__)'

@hidmic hidmic force-pushed the specialized-template-functions branch from 4474a37 to 6a3b2ce Compare December 6, 2021 18:29
@hidmic
Copy link
Copy Markdown
Collaborator Author

hidmic commented Dec 6, 2021

Rebased and ready for a review (if CI comes out green).

CC @svenevs @clalancette

@svenevs
Copy link
Copy Markdown
Owner

svenevs commented Dec 6, 2021

Thanks for reading, I'll look at this soon (as well as remove py2). Do we know what the next version of breathe will be? This requires that so I'm just going to pin

@svenevs
Copy link
Copy Markdown
Owner

svenevs commented Dec 10, 2021

I've got this slated for the weekend since it looks like breathe==4.32.0 is going to ship.

I think this one fixes a number of issues with templates and believe I get to remove an obnoxious warning ❤️

Will land this ASAP, thanks again for fixing this and breathe!

@svenevs svenevs force-pushed the specialized-template-functions branch from ba9aa53 to bfe45a6 Compare December 30, 2021 04:33
@svenevs svenevs merged commit 4119480 into svenevs:master Dec 30, 2021
@svenevs
Copy link
Copy Markdown
Owner

svenevs commented Dec 30, 2021

Sorry for the delay on this. Will be merging this since it works with the specialized pathological example you added. I keep looking at this and then desiring to fix the template overloads that are not specialized and then getting wound out over it, so unfixed they will remain with a tag to #106 and synopsis that this has to be a breathe bug but I don't think it will be easy for anyone to fix and I at least warn people in the build output.


The warning from breathe:

Warning

doxygenfunction: Unable to resolve function “overload::blargh” with arguments (typename C::type) in doxygen xml output for project “cpp_func_overloads” from directory: ./_doxygen/xml. Potential matches:

- float blargh(float x)
- float blargh(float x, float y)
- float blargh(float x, float y, float z)
- float blargh(float, float, float, float)
- int blargh(int x)
- int blargh(int x, int y)
- int blargh(int x, int y, int z)
- int blargh(int, int, int, int)
- std::size_t blargh(std::size_t x, const float &y, double z, const std::string &s)
- std::size_t blargh(std::size_t x, const std::string &s)
- std::string blargh(const std::string &x)
- std::string blargh(const std::string &x, const std::string &y)
- std::string blargh(const std::string &x, const std::string &y, const std::string &z)
- std::string blargh(const std::string&, const std::string&, const std::string&, const std::string&)
- template<class C, typename T> std::enable_if<!std::is_convertible<typename C::type, T>::value, T>::type blargh(typename C::type t)
- template<class C, typename T> std::enable_if<std::is_convertible<typename C::type, T>::value, T>::type blargh(typename C::type t)
- template<class C> C::type blargh(typename C::type t)
- void blargh()
- void blargh(const float *x, const float *y, float *z, std::size_t N)
- void blargh(std::vector<std::string> &v)
- void blargh(std::vector<std::vector<int>> &v)

Via

.. _exhale_function_overload_8hpp_1a78c463f6d2e0247e92b6a8cee2dbd86c:

Template Function overload::blargh(typename C::type)
====================================================

- Defined in :ref:`file_include_overload_overload.hpp`


Function Documentation
----------------------


.. doxygenfunction:: overload::blargh(typename C::type)

So if I update breathe_identifier() to use full_signature() for functions:

.. _exhale_function_overload_8hpp_1a78c463f6d2e0247e92b6a8cee2dbd86c:

Template Function template<class C, typename T> std::enable_if<std::is_convertible<typename C::type, T>::value, T>::type overload::blargh(typename C::type)
===========================================================================================================================================================

- Defined in :ref:`file_include_overload_overload.hpp`


Function Documentation
----------------------

.. this is the one desired
..                   template<class C, typename T> std::enable_if<std::is_convertible<typename C::type, T>::value, T>::type blargh(typename C::type t)

.. doxygenfunction:: template<class C, typename T> std::enable_if<std::is_convertible<typename C::type, T>::value, T>::type overload::blargh(typename C::type)
  1. It doesn't like having the namespace overload::blargh vs blargh.
  2. It wants typename C::type t with defname t rather than typename C::type.

Alas, even if you give it the exact signature it wants, it does not succeed 😢 A diff that breaks all the other functions (<declname> causes problems everywhere else):

diff --git a/exhale/graph.py b/exhale/graph.py
index 54e57b9..f61319a 100644
--- a/exhale/graph.py
+++ b/exhale/graph.py
@@ -268,10 +268,11 @@ class ExhaleNode(object):
         """
         if self.kind == "function":
             # TODO: breathe bug with templates and overloads, don't know what to do...
-            return "{name}({parameters})".format(
-                name=self.name,
-                parameters=", ".join(self.parameters)
-            )
+            # return "{name}({parameters})".format(
+            #     name=self.name,
+            #     parameters=", ".join(self.parameters)
+            # )
+            return self.full_signature()
 
         return self.name
 
@@ -290,9 +291,9 @@ class ExhaleNode(object):
         """
         if self.kind == "function":
             return "{template}{return_type} {name}({parameters})".format(
-                template="template <{0}> ".format(", ".join(self.template)) if self.template is not None else "",
+                template="template<{0}> ".format(", ".join(self.template)) if self.template is not None else "",
                 return_type=self.return_type,
-                name=self.name,
+                name=self.name.split("::")[-1],
                 parameters=", ".join(self.parameters)
             )
         raise RuntimeError(
@@ -2164,8 +2165,13 @@ class ExhaleRoot(object):
                 # 2. The function parameter list.
                 parameters = []
                 for param in memberdef.find_all("param", recursive=False):
-                    parameters.append(param.type.text)
-                func.parameters = utils.sanitize_all(parameters)
+                    p = utils.sanitize(param.type.text)
+                    if param.declname:
+                        p += " " + param.declname.text
+                    parameters.append(p)
+
+                func.parameters = parameters
+
                 # 3. The template parameter list.
                 templateparamlist = memberdef.templateparamlist
                 if templateparamlist:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants