boost::variant and "Current Approach: Temporary Heap Backup" vs "An Initial Solution: Double Storage"

1) boost::variant and "Current Approach: Temporary Heap Backup" vs "An Initial Solution: Double Storage" Please provide both solutions. A potential heap allocation may prevent certain application areas. 2) I also do not understand that exception safety requires that the variant is never empty (e.g. empty() returning always false). What is the use of calling the constructor (of which type btw?) if somebody creates an unintialized variant variable? Or: In the following piece of code is the std::string constructor being called? boost::variant<std::string, int> s; Thanks Peter

"Peter Foelsche" <peter_foelsche@agilent.com> wrote in message news:ha0hv5$7sj$1@ger.gmane.org...
1) boost::variant and "Current Approach: Temporary Heap Backup" vs "An Initial Solution: Double Storage" Please provide both solutions. A potential heap allocation may prevent certain application areas.
from the documentation: 1) Copy-construct the content of the left-hand side to the heap; call the pointer to this data backup. 2) Destroy the content of the left-hand side. 3) Copy-construct the content of the right-hand side in the (now-empty) storage of the left-hand side. 4) In the event of failure, copy backup to the left-hand side storage. step 4 may throw too in which case the variant is corrupted. I think only when providing double storage exception safety can be guaranteed. 5) In the event of success, deallocate the data pointed to by backup.

also it would be nice if one could somehow deduce the integer value returned from which(): typedef boost::variant<std::string, int, double> CVariant; CVariant("test").which() == CVariant::ID<std::string>::value CVariant(1.0).which() == CVariant::ID<double>::value

AMDG Peter Foelsche wrote:
also it would be nice if one could somehow deduce the integer value returned from which():
typedef boost::variant<std::string, int, double> CVariant;
CVariant("test").which() == CVariant::ID<std::string>::value CVariant(1.0).which() == CVariant::ID<double>::value
boost::mpl::index_of<CVariant::types, std::string>::value In Christ, Steven Watanabe

AMDG Peter Foelsche wrote:
"Peter Foelsche" <peter_foelsche@agilent.com> wrote in message news:ha0hv5$7sj$1@ger.gmane.org...
1) boost::variant and "Current Approach: Temporary Heap Backup" vs "An Initial Solution: Double Storage" Please provide both solutions. A potential heap allocation may prevent certain application areas.
from the documentation:
1) Copy-construct the content of the left-hand side to the heap; call the pointer to this data backup. 2) Destroy the content of the left-hand side. 3) Copy-construct the content of the right-hand side in the (now-empty) storage of the left-hand side. 4) In the event of failure, copy backup to the left-hand side storage.
step 4 may throw too in which case the variant is corrupted.
It can't throw because it is only copying a pointer. In Christ, Steven Watanabe

AMDG Peter Foelsche wrote:
1) boost::variant and "Current Approach: Temporary Heap Backup" vs "An Initial Solution: Double Storage" Please provide both solutions. A potential heap allocation may prevent certain application areas.
If any of the variant's types have a no-throw default constructor, then no heap backup is used, because variant can construct an object of that type if an exception is thrown. In practice, this means built-in types, or boost::blank.
2) I also do not understand that exception safety requires that the variant is never empty (e.g. empty() returning always false). What is the use of calling the constructor (of which type btw?) if somebody creates an unintialized variant variable? Or: In the following piece of code is the std::string constructor being called?
boost::variant<std::string, int> s;
A default constructed variant is initialized to hold an object of the first of its types. In Christ, Steven Watanabe

"Steven Watanabe" <watanabesj@gmail.com> wrote in message news:4AC3D46B.4020008@providere-consulting.com...
AMDG
Peter Foelsche wrote:
1) boost::variant and "Current Approach: Temporary Heap Backup" vs "An Initial Solution: Double Storage" Please provide both solutions. A potential heap allocation may prevent certain application areas.
If any of the variant's types have a no-throw default constructor, then no heap backup is used, because variant can construct an object of that type if an exception is thrown. In practice, this means built-in types, or boost::blank.
This means, my assumptions about exceptions safety of boost::variant may be wrong. Is this following code & assertion valid? I would like if I can assume this. Thanks Peter typedef boost::variant<type1, type2> CVariant; CVariant s(type1()); try { s = type2(); } catch (...) { assert(s.which() == boost::mpl::index_of<CVariant::types, type1>::value); }

"Peter Foelsche" <peter_foelsche@agilent.com> wrote in message news:ha0lp0$jcu$1@ger.gmane.org...
If any of the variant's types have a no-throw default constructor, then no heap backup is used, because variant can construct an object of that type if an exception is thrown. In practice, this means built-in types, or boost::blank.
This means, my assumptions about exceptions safety of boost::variant may be wrong. Is this following code & assertion valid? I would like if I can assume this.
never mind -- exceptions safety seems to be guaranteed-- I just had a look at boost::detail::variant::backup_assigner

AMDG Peter Foelsche wrote:
This means, my assumptions about exceptions safety of boost::variant may be wrong. Is this following code & assertion valid? I would like if I can assume this.
Thanks Peter
typedef boost::variant<type1, type2> CVariant;
CVariant s(type1()); try { s = type2(); } catch (...) { assert(s.which() == boost::mpl::index_of<CVariant::types, type1>::value); }
You cannot make this assumption. Assignment for boost::variant does not provide the strong guarantee. In Christ, Steven Watanabe
participants (2)
-
Peter Foelsche
-
Steven Watanabe