Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with type aliases inside template #284

Closed
arximboldi opened this issue Oct 27, 2016 · 9 comments · Fixed by #512
Closed

Problems with type aliases inside template #284

arximboldi opened this issue Oct 27, 2016 · 9 comments · Fixed by #512
Assignees
Labels
bug Problem in existing code code Source code

Comments

@arximboldi
Copy link
Contributor

Hi!

I am trying to use Breathe to document a template class. I am using breathe master, since I am aware that other releases have problems (as of #213). The relevant part of the template class looks like this:

template <typename T,
          detail::rbts::bits_t B = default_bits,
          typename MemoryPolicy  = default_memory_policy>
class flex_vector
{
public:
    using value_type = T;
    using reference = const T&;
    using size_type = std::size_t;
    using difference_type = std::ptrdiff_t;
    using const_reference = const T&;
    ...

Nothing crazy I believe, just the typical type aliases when defining a container. However, I am having problems with Breathe. On the command line, it reports stuff like:

immer/doc/index.md:1: WARNING: Too many template argument lists compared to parameter lists. Argument lists: 1, Parameter lists: 0, Extra empty parameters lists prepended: 1. Declaration:
    immer::flex_vector<T, B, MemoryPolicy>::value_type
...

And the generated documentation looks like this:
screenshot from 2016-10-27 20-59-47

I have these two comments:

  • The using keyword should only appear once. I guess that the using > thingy was not intended to appear and this is a bug.
  • The immer::flex_vector<T, B, MemoryPolicy>:: part in front of every type is verbose and redundant. Is there any way to make it not appear? That might be what is causing the problem, but I have not found a way to make doxygen not generate it as part of the definition. Maybe breathe itself could remove it otherwise, what do you think? If you guide me, I can prepare a patch for this.

Thanks!


For completeness, here are the relevant lines from the .xml file:

      <sectiondef kind="public-type">
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1aaad497f7f188158225b773a9a5e337a7" prot="public" static="no">
        <type>T</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::value_type =  T</definition>
        <argsstring></argsstring>
        <name>value_type</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="50" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="50" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1ad60cb8df3c51919b2a80775f1ccf8238" prot="public" static="no">
        <type>const T &amp;</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::reference =  const T&amp;</definition>
        <argsstring></argsstring>
        <name>reference</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="51" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="51" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1a5423c992ac3de5826a3788176795a801" prot="public" static="no">
        <type>std::size_t</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::size_type =  std::size_t</definition>
        <argsstring></argsstring>
        <name>size_type</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="52" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="52" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1ab8d403aa940d06ac3bc38577776b4225" prot="public" static="no">
        <type>std::ptrdiff_t</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::difference_type =  std::ptrdiff_t</definition>
        <argsstring></argsstring>
        <name>difference_type</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="53" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="53" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1aa7375d53688f22e709537ca4b3f10acc" prot="public" static="no">
        <type>const T &amp;</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::const_reference =  const T&amp;</definition>
        <argsstring></argsstring>
        <name>const_reference</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="54" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="54" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1ab47cc35b35b1f572c1d182feefa4c02b" prot="public" static="no">
        <type>detail::rbts::rrbtree_iterator&lt; T, B, MemoryPolicy &gt;</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::iterator =  detail::rbts::rrbtree_iterator&lt;T, B, MemoryPolicy&gt;</definition>
        <argsstring></argsstring>
        <name>iterator</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="56" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="56" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1ab8714e30fd6651744ad36e08d4e72d9f" prot="public" static="no">
        <type>iterator</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::const_iterator =  iterator</definition>
        <argsstring></argsstring>
        <name>const_iterator</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="57" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="57" bodyend="-1"/>
      </memberdef>
      <memberdef kind="typedef" id="classimmer_1_1flex__vector_1ac2cb1648385d8436315a9799971b0c63" prot="public" static="no">
        <type>std::reverse_iterator&lt; iterator &gt;</type>
        <definition>using immer::flex_vector&lt; T, B, MemoryPolicy &gt;::reverse_iterator =  std::reverse_iterator&lt;iterator&gt;</definition>
        <argsstring></argsstring>
        <name>reverse_iterator</name>
        <briefdescription>
        </briefdescription>
        <detaileddescription>
        </detaileddescription>
        <inbodydescription>
        </inbodydescription>
        <location file="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" line="58" column="1" bodyfile="/home/raskolnikov/dev/immer/immer/flex_vector.hpp" bodystart="58" bodyend="-1"/>
      </memberdef>
      </sectiondef>
@michaeljones
Copy link
Collaborator

Thank you for such a thorough issue report and for the kind offer to look into a patch. That is very much appreciated. I'll try to look into it and provide some advice on how best to tackle it.

Cheers,
Michael

@arximboldi
Copy link
Contributor Author

arximboldi commented Nov 9, 2016

Hi Michael,

Just to see if it changed anything, I tried running breathe master against sphinx master (I was using sphinx latest before) and this is what I get now:

screenshot from 2016-11-09 19-51-34

As you can see the using keyword appears twice in the HTML, but no longer does the first one has the weird >. You can not see that from the screenshot, but it is two separate <em> tags, as in:

<em class="property">using </em>
<em class="property">using </em>
...

The other problem (bigger one, the other I can fix with regex) is that the class name has magically disappeared! Here is how the HTM looks like where the class name should be:

<dt id="_CPPv2N5immer6vectorE">
<span id="immer::vector"></span><em class="property">class </em>
</dt>

I tried with different themes and similar results. Any clue what is going on?

Thanks!

@arximboldi
Copy link
Contributor Author

Ok, I managed to workaround these issues with some sed (this is definitely degenerating into compulsion):

# Add the missing class name
src='<span id="\(.*\)"></span><em class="property">class </em>'
dst='<span id=""></span><em class="property">class</em><tt class="descname">\1</tt>'
sed -i "s@$src@$dst@g" $location/_build/html/*.html

# Remove the duplicate `using`
src='<em class="property">using </em><em class="property">using </em>'
dst='<em class="property">using </em>'
sed -i "s@$src@$dst@g" $location/_build/html/*.html

# Remove template parameters in the parent class inside nested `using = ...` declarations
src='<code class="descclassname">\([^&]*\)&lt;\([^&]*\)&gt;::</code>'
dst='<code class="descclassname">\1::</code>'
sed -i "s@$src@$dst@g" $location/_build/html/*.html

arximboldi added a commit to arximboldi/immer that referenced this issue Nov 13, 2016
@michaeljones
Copy link
Collaborator

Thanks for the further investigation and updates. I'm not sure quite what is going on. A good step would be to start a branch with an example in the examples/specific folder that highlights this behaviour and then we can set about trying to figure out where this double up might be coming from.

I've made you a collaborator on the project so you should be able to just push a new branch if you have time.

@arximboldi
Copy link
Contributor Author

Thanks Michael!

Curiously I was looking at the Sphinx code right now because I wanted to tweak the Inherits from... stuff too 😄 This week I am very busy but I will look into these issues next week and see what I find.

@eric-wieser
Copy link
Contributor

The other problem (bigger one, the other I can fix with regex) is that the class name has magically disappeared!

I'm seeing this problem at the moment, with very simple cases - does this have an issue somewhere?

@vermeeren
Copy link
Collaborator

Could you check if this is still an issue with latest Sphinx (1.7.5) + Breathe (4.9.0)? Afaik there have been many changes since this issue was opened to better support C++ features like this one.

@jakobandersen
Copy link
Collaborator

(With Sphinx 1.7.5 it looks like the visual problems are gone)
The original problem with warnings on the form

WARNING: Too many template argument lists compared to parameter lists. Argument lists: 1, Parameter lists: 0, Extra empty parameters lists prepended: 1.

is related to why #374 happened. Breathe is sending a fully qualified name to Sphinx and then removes the qualifications from the document trees (see also #356). However, it looks like if you have a templated entity where a nested name is document, then a template argument list is inserted, even though it's not a specialization. For example:

template<typename T>
struct A {
   int i;
};

Breathe here sends int A<T>::i to Sphinx, which it then "corrects" to be template<> int A<T>::i.
There is currently to way to specify that declaration with full qualification and I don't see a reasonable way to do it. In the long term I think the best is for Breathe to emulate the declaration nesting from Sphinx and never insert the full qualification.

@vermeeren vermeeren added bug Problem in existing code code Source code labels Jun 9, 2018
@vermeeren vermeeren removed their assignment Aug 27, 2019
@vermeeren
Copy link
Collaborator

Should be fixed with #512, released in Breathe v4.17.0. Note that you also need Sphinx 3.x for recent Breathe versions.

@vermeeren vermeeren self-assigned this May 1, 2020
@vermeeren vermeeren linked a pull request Dec 3, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Problem in existing code code Source code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants