Skip to content

Commit aad15b1

Browse files
committed
wip
1 parent 5075da5 commit aad15b1

File tree

2 files changed

+303
-87
lines changed

2 files changed

+303
-87
lines changed

include/boost/openmethod/core.hpp

Lines changed: 58 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -720,83 +720,63 @@ class virtual_ptr {
720720

721721
//! Construct a `virtual_ptr` from another `virtual_ptr`
722722
//!
723-
//! Copy the object and v-table pointers from `other` to `this`.
723+
//! Copy the object and v-table pointers from `other` to `this.
724724
//!
725-
//! @param other A virtual_ptr to a type-compatible object
725+
//! `Other` is _not_ required to be a pointer to a polymorphic class.
726+
//!
727+
//! @par Examples
728+
//!
729+
//! Assigning from a plain virtual_ptr:
726730
//!
727-
//! @par Example
728731
//! @code
729732
//! struct Animal {}; // polymorphism not required
730733
//! struct Dog : Animal {}; // polymorphism not required
731734
//! BOOST_OPENMETHOD_CLASSES(Animal, Dog);
732735
//! initialize();
733736
//!
734737
//! Dog snoopy;
735-
//! const virtual_ptr<Dog> dog = final_virtual_ptr(snoopy);
738+
//! virtual_ptr<Dog> dog = final_virtual_ptr(snoopy);
739+
//! virtual_ptr<Animal> p{nullptr};
736740
//!
737-
//! virtual_ptr<Animal> p(dog);
741+
//! p = dog;
738742
//!
739743
//! BOOST_TEST(p.get() == &snoopy);
740744
//! BOOST_TEST(p.vptr() == default_registry::static_vptr<Dog>);
741745
//! @endcode
742746
//!
743-
//! @par Requirements
744-
//!
745-
//! @li `Other\*` must be constructible from `Class\*`.
746-
template<
747-
class Other,
748-
typename = std::enable_if_t<std::is_constructible_v<
749-
Class*, typename virtual_ptr<Other, Registry>::element_type*>>>
750-
virtual_ptr(const virtual_ptr<Other, Registry>& other)
751-
: vp(other.vp), obj(other.get()) {
752-
}
753-
754-
//! Construct a `virtual_ptr` from another `virtual_ptr`
755-
//!
756-
//! Copy the object and v-table pointers from `other` to `this`.
757-
//!
758-
//! A plain `virtual_ptr` can be constructed from a smart virtual_ptr, as
759-
//! long as the smart pointer's element type is convertible to the plain
760-
//! pointer's element type.
761-
//!
762-
//! `Other::element_type` is _not_ required to be a pointer to a polymorphic
763-
//! class.
747+
//! Assigning from a smart virtual_ptr:
764748
//!
765-
//! @par Example
766749
//! @code
767750
//! struct Animal {}; // polymorphism not required
768751
//! struct Dog : Animal {}; // polymorphism not required
769752
//! BOOST_OPENMETHOD_CLASSES(Animal, Dog);
770753
//! initialize();
771754
//!
772-
//! Dog snoopy;
773-
//! virtual_ptr<Dog> dog = final_virtual_ptr(snoopy);
774-
//!
775-
//! virtual_ptr<Animal> p(dog);
755+
//! virtual_ptr<std::shared_ptr<Animal>> snoopy = make_shared_virtual<Dog>();
756+
//! virtual_ptr<Animal> p = snoopy;
776757
//!
777-
//! BOOST_TEST(p.get() == &snoopy);
758+
//! BOOST_TEST(p.get() == snoopy.get());
778759
//! BOOST_TEST(p.vptr() == default_registry::static_vptr<Dog>);
779760
//! @endcode
780761
//!
762+
//! No construction of a smart `virtual_ptr` from a plain `virtual_ptr`:
763+
//!
764+
//! @code
765+
//! static_assert(
766+
//! std::is_constructible_v<
767+
//! shared_virtual_ptr<Animal>, virtual_ptr<Dog>> == false);
768+
//! @endcode
769+
//!
781770
//! @param other A virtual_ptr to a type-compatible object
782771
//!
783772
//! @par Requirements
784-
//!
785-
//! @li `Other\*` must be constructible from `Class\*`.
773+
//! @li `Other`\'s object pointer must be assignable to a `Class\*`.
786774
template<
787775
class Other,
788776
typename = std::enable_if_t<std::is_constructible_v<
789777
Class*, typename virtual_ptr<Other, Registry>::element_type*>>>
790-
virtual_ptr(virtual_ptr<Other, Registry>& other)
778+
virtual_ptr(const virtual_ptr<Other, Registry>& other)
791779
: vp(other.vp), obj(other.get()) {
792-
// Why is this needed? Consider this conversion conversion from
793-
// smart to dumb pointer:
794-
// virtual_ptr<std::shared_ptr<const Node>> p = ...;
795-
// virtual_ptr<const Node> q = p;
796-
// Since 'p' is not const, in the absence of this ctor,
797-
// virtual_ptr(Other&) would be preferred to
798-
// virtual_ptr(const virtual_ptr<Other, Registry>& other), and
799-
// that is incorrect.
800780
}
801781

802782
//! Assign a `virtual_ptr` from a reference to an object
@@ -843,7 +823,7 @@ class virtual_ptr {
843823
typename = std::enable_if_t<
844824
BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS
845825
IsPolymorphic<Class, Registry> &&
846-
std::is_assignable_v<Class*, Other*>>>
826+
std::is_assignable_v<Class*&, Other*>>>
847827
virtual_ptr& operator=(Other& other) {
848828
obj = &other;
849829
vp = detail::box_vptr<use_indirect_vptrs>(
@@ -893,7 +873,7 @@ class virtual_ptr {
893873
typename = std::enable_if_t<
894874
BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS
895875
IsPolymorphic<Class, Registry> &&
896-
std::is_assignable_v<Class*, Other*>>>
876+
std::is_assignable_v<Class*&, Other*>>>
897877
virtual_ptr& operator=(Other* other) {
898878
obj = other;
899879
vp = detail::box_vptr<use_indirect_vptrs>(
@@ -903,11 +883,14 @@ class virtual_ptr {
903883

904884
//! Assign a `virtual_ptr` from another `virtual_ptr`
905885
//!
906-
//! The pointer to the v-table is copied from `other`.
886+
//! Copy the object and v-table pointers from `other` to `this.
907887
//!
908888
//! `Other` is _not_ required to be a pointer to a polymorphic class.
909889
//!
910-
//! @par Example
890+
//! @par Examples
891+
//!
892+
//! Assigning from a plain virtual_ptr:
893+
//!
911894
//! @code
912895
//! struct Animal {}; // polymorphism not required
913896
//! struct Dog : Animal {}; // polymorphism not required
@@ -924,14 +907,39 @@ class virtual_ptr {
924907
//! BOOST_TEST(p.vptr() == default_registry::static_vptr<Dog>);
925908
//! @endcode
926909
//!
927-
//! @param other A virtual_ptr to a type-compatible polymorphic object
910+
//! Assigning from a smart virtual_ptr:
911+
//!
912+
//! @code
913+
//! struct Animal {}; // polymorphism not required
914+
//! struct Dog : Animal {}; // polymorphism not required
915+
//! BOOST_OPENMETHOD_CLASSES(Animal, Dog);
916+
//! initialize();
917+
//!
918+
//! virtual_ptr<std::shared_ptr<Animal>> snoopy = make_shared_virtual<Dog>();
919+
//! virtual_ptr<Animal> p;
920+
//!
921+
//! p = snoopy;
922+
//!
923+
//! BOOST_TEST(p.get() == snoopy.get());
924+
//! BOOST_TEST(p.vptr() == default_registry::static_vptr<Dog>);
925+
//! @endcode
926+
//!
927+
//! No assignment from a plain `virtual_ptr` to a smart `virtual_ptr`:
928+
//!
929+
//! @code
930+
//! static_assert(
931+
//! std::is_assignable_v<
932+
//! shared_virtual_ptr<Animal>&, virtual_ptr<Dog>> == false);
933+
//! @endcode
934+
//!
935+
//! @param other A virtual_ptr to a type-compatible object
928936
//!
929937
//! @par Requirements
930-
//! @li `Other\*` must be constructible from `Class\*`.
938+
//! @li `Other`\'s object pointer must be assignable to a `Class\*`.
931939
template<
932940
class Other,
933941
typename = std::enable_if_t<std::is_assignable_v<
934-
Class*, typename virtual_ptr<Other, Registry>::element_type*>>>
942+
Class*&, typename virtual_ptr<Other, Registry>::element_type*>>>
935943
virtual_ptr& operator=(const virtual_ptr<Other, Registry>& other) {
936944
obj = other.get();
937945
vp = other.vp;
@@ -1283,43 +1291,6 @@ class virtual_ptr<
12831291
: vp(other.vp), obj(other.obj) {
12841292
}
12851293

1286-
//! Construct from a smart virtual pointer to a derived class
1287-
//!
1288-
//! Copy the object and v-table pointers from `other`.
1289-
//!
1290-
//! `Other` is _not_ required to be a pointer to a polymorphic class.
1291-
//!
1292-
//! @par Example
1293-
//! @code
1294-
//! struct Animal {}; // polymorphism not required
1295-
//! struct Dog : Animal {}; // polymorphism not required
1296-
//! BOOST_OPENMETHOD_CLASSES(Animal, Dog);
1297-
//! initialize();
1298-
//!
1299-
//! virtual_ptr<std::shared_ptr<Dog>> snoopy = make_shared_virtual<Dog>();
1300-
//! virtual_ptr<std::shared_ptr<Animal>> p = snoopy;
1301-
//!
1302-
//! BOOST_TEST(snoopy.get() != nullptr);
1303-
//! BOOST_TEST(p.get() == snoopy.get());
1304-
//! BOOST_TEST(p.vptr() == default_registry::static_vptr<Dog>);
1305-
//! @endcode
1306-
//!
1307-
//! @par Requirements
1308-
//! @li `SmartPtr` and `Other` must be instantiated from the same template -
1309-
//! e.g. both `std::shared_ptr` or both `std::unique_ptr`.
1310-
//! @li `Other` must be a virtual pointer to a class derived from
1311-
//! `element_type`.
1312-
//! @li `SmartPtr` must be constructible from `Other&`.
1313-
template<
1314-
class Other,
1315-
typename = std::enable_if_t<
1316-
BOOST_OPENMETHOD_DETAIL_UNLESS_MRDOCS
1317-
SameSmartPtr<SmartPtr, Other, Registry> &&
1318-
std::is_constructible_v<SmartPtr, Other&>>>
1319-
virtual_ptr(virtual_ptr<Other, Registry>& other)
1320-
: vp(other.vp), obj(other.obj) {
1321-
}
1322-
13231294
//! Construct-move from a virtual pointer to a derived class
13241295
//!
13251296
//! Move the object pointer from `other` to `this`. Copy the v-table pointer

0 commit comments

Comments
 (0)