|
| template<typename value_t, typename self_t> |
| static void | assign (const self_t &self, const value_t &value) |
| template<typename self_t> |
| static void | assign_property (const self_t &self, ::CFPropertyListRef value, ::CFPropertyListRef baseline=nullptr) |
| template<typename container_t, typename self_t> |
| static container_t | children (const self_t &self) |
| template<typename value_t> |
| static constexpr bool | enabled () |
| template<typename value_t, typename self_t> |
| static bool | fetch (const self_t &self, value_t &value) |
| template<typename self_t> |
| static bool | nested (const self_t &self) |
| template<typename self_t> |
| static ::CFPropertyListRef | property_list (const self_t &self) |
| template<typename self_t> |
| static void | purge (const self_t &self) noexcept |
| template<typename self_t> |
| static size_t | size (const self_t &self) |
template<typename derived_t>
class cf::tree< derived_t >
dx::key_value_tree<derived_t> contract (dxd/interface/dx_key_value_tree.h), implemented once for every CF-backed preference store (cf::_preference, sc::_preference, dx::coreaudio::server::_preference) - inherit from this (CRTP: class _preference: public cf::tree<_preference>) instead of reimplementing it.
derived_t only ever has to provide the 10 position-only primitives below - operating on self's own key alone (empty meaning the whole domain, or, for a derived_t that documents no root support, throwing), never the parent chain:
operator ::CFPropertyListRef() const;
::CFPropertyListRef operator ()(::CFPropertyListRef dflt) const;
operator ::CFArrayRef() const;
template<typename container_t> operator container_t() const;
bool container() const;
operator bool() const;
void erase();
static size_t size(const self_t &self)
Definition cf_tree.h:172
super & operator=(::BOOL value)
Definition dx_pipe.h:159
Everything else - resolving self's whole parent chain into the entire nested CFPropertyListRef subtree rooted at self - is identical for every CF-backed store and lives here, once (property_list()/assign_property(), plus size()/children() below). These reach derived_t's own, non-recursive primitives via self.derived_t::operator X(), never plain self.operator
X(): dx::key_value_tree<derived_t> redeclares operator bool()/operator=/ operator value_t()/erase()/container()/size() itself (folding in this same parent-chain resolution), hiding those names inherited from derived_t - a plain unqualified access would otherwise recurse into the wrong (derived, chain-resolving) version instead of derived_t's own.