Subject: [Boost-bugs] [Boost C++ Libraries] #9948: remove use of const_cast in intrusive containers
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-04-24 16:40:08
#9948: remove use of const_cast in intrusive containers
-----------------------------------------+------------------------
Reporter: Matei David <matei@â¦> | Owner: igaztanaga
Type: Feature Requests | Status: new
Milestone: To Be Determined | Component: intrusive
Version: Boost 1.55.0 | Severity: Problem
Keywords: intrusive custom references |
-----------------------------------------+------------------------
In intrusive containers, the existing value traits customization mechanism
described
[http://www.boost.org/doc/libs/1_55_0/doc/html/intrusive/value_traits.html
here] allows for value `pointer` to be a custom class. Moreover, the
existing pointer traits mechanism allows for the user to:
- Define and use a custom `pointer_traits<pointer>::reference` class
instead of raw references.
- Provide custom conversions between `pointer` and `reference`, and
between `pointer` and `const_pointer`.
That being said, in `list.hpp`, `slist.hpp`, `bstree.hpp` the C++ operator
`const_cast` operator is used to convert a `const_reference` (defined as
`pointer_traits<const_pointer>::reference`) into a `reference` (defined as
`pointer_traits<pointer>::reference`). This happens in `[s_]iterator_to()`
methods. This is unfortunate because `const_cast` cannot be overridden,
and it cannot work with anything other than real pointers and real
references. So even though most of the existing code base (through value
traits & pointer traits mechanisms) can support custom references, that
possibility is removed by the use of `const_cast`.
I created a pull request in that sense, where I replaced calls of the
form:
`const_cast<reference>(value)` (where `value` is a
`pointer_traits<const_pointer>::reference`)
by:
`*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))`
This relies on the existence of:
1. `const_pointer
pointer_traits<const_pointer>::pointer_to(const_reference)`;
2. `pointer pointer_traits<pointer>::const_cast_from(const_pointer)`;
3. `reference pointer::operator * ()`.
I think it is reasonable to expect all of these to be met. A user of raw
references and raw pointers will be unaffected, because the default
definitions of `pointer_traits` work as expected. As explained earlier,
there is no existing code that uses custom references. That leaves only
code with custom pointers and raw references to worry about breaking.
Regarding 1, the `pointer_to()` method is used heavily by the boost
intrusive code, so it is reasonable to expect any existing specialization
of `pointer_traits` to provide that.
Regarding 2, the `const_cast_from()` method, even though clearly
documented in the pointer traits description, is not otherwise used in
boost intrusive. So it is possible for existing code to specialize
`pointer_traits` and not provide `const_cast_from`, which would result in
broken code with the current modifications. I think the error message
would be quite informative though: "missing const_cast_from", and easy to
diagnose and fix. It would also be a step in the right direction: if a
user really needs custom pointer traits, then they should really be
providing the custom casts.
As for 3, the `operator * ()` method, I think it's reasonable to expect a
custom pointer class would provide that. Standard smart pointer classes
provide that. In the future, I would also suggest adding this conversion
explicitly in `pointer_traits`, e.g., require specializations to define
`pointer_traits<pointer>::reference
pointer_traits<pointer>::reference_from(pointer)`.
The pull request is [https://github.com/boostorg/intrusive/pull/4 here].
As explained, this removes `const_cast` from `list.hpp`, `slist.hpp`, and
`bstree.hpp`. It is still used in `hashtable.hpp`, whose code looks a bit
different than the other containers, so I left it alone.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/9948> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:16 UTC