"Fossies" - the Fresh Open Source Software Archive

Member "dune-typetree-2.8.0/dune/typetree/proxynode.hh" (31 Aug 2021, 9832 Bytes) of package /linux/misc/dune/dune-typetree-2.8.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "proxynode.hh" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.8.0_vs_2.9.0.

    1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    2 // vi: set et ts=4 sw=2 sts=2:
    3 
    4 #ifndef DUNE_TYPETREE_PROXYNODE_HH
    5 #define DUNE_TYPETREE_PROXYNODE_HH
    6 
    7 #include <type_traits>
    8 #include <dune/typetree/nodeinterface.hh>
    9 #include <dune/typetree/nodetags.hh>
   10 #include <dune/common/shared_ptr.hh>
   11 #include <dune/common/indices.hh>
   12 #include <dune/common/std/type_traits.hh>
   13 
   14 namespace Dune {
   15   namespace TypeTree {
   16 
   17     /** \addtogroup Nodes
   18      *  \ingroup TypeTree
   19      *  \{
   20      */
   21 
   22     template<typename Node>
   23     class ProxyNode;
   24 
   25     //! Mixin class providing methods for child access with compile-time parameter.
   26     template<typename ProxiedNode>
   27     class StaticChildAccessors
   28     {
   29 
   30       static const bool proxiedNodeIsConst = std::is_const<typename std::remove_reference<ProxiedNode>::type>::value;
   31 
   32       template<std::size_t k>
   33       struct lazy_enabled
   34       {
   35         static const bool value = !proxiedNodeIsConst;
   36       };
   37 
   38       typedef ProxyNode<ProxiedNode> Node;
   39 
   40       template<bool enabled = !proxiedNodeIsConst>
   41       typename std::enable_if<enabled,Node&>::type
   42       node ()
   43       {
   44         return static_cast<Node&>(*this);
   45       }
   46 
   47       const Node& node () const
   48       {
   49         return static_cast<const Node&>(*this);
   50       }
   51 
   52     public:
   53 
   54       //! Access to the type and storage type of the i-th child.
   55       template<std::size_t k>
   56       struct Child
   57         : public ProxiedNode::template Child<k>
   58       {};
   59 
   60       //! @name Child Access
   61       //! @{
   62 
   63       //! Returns the i-th child.
   64       /**
   65        * \returns a reference to the i-th child.
   66        */
   67       template<std::size_t k,
   68         typename std::enable_if<lazy_enabled<k>::value, int>::type = 0>
   69       auto& child (index_constant<k> = {})
   70       {
   71         return node().proxiedNode().template child<k>();
   72       }
   73 
   74       //! Returns the i-th child (const version).
   75       /**
   76        * \returns a const reference to the i-th child.
   77        */
   78       template<std::size_t k>
   79       const auto& child (index_constant<k> = {}) const
   80       {
   81         return node().proxiedNode().template child<k>();
   82       }
   83 
   84       //! Returns the storage of the i-th child.
   85       /**
   86        * \returns a copy of the object storing the i-th child.
   87        */
   88       template<std::size_t k,
   89         typename std::enable_if<lazy_enabled<k>::value, int>::type = 0>
   90       auto childStorage (index_constant<k> = {})
   91       {
   92         return node().proxiedNode().template childStorage<k>();
   93       }
   94 
   95       //! Returns the storage of the i-th child (const version).
   96       /**
   97        * This method is only important if the child is stored as
   98        * some kind of pointer, as this allows the pointee type to
   99        * become const.
  100        * \returns a copy of the object storing the i-th child.
  101        */
  102       template<std::size_t k>
  103       auto childStorage (index_constant<k> = {}) const
  104       {
  105         return node().proxiedNode().template childStorage<k>();
  106       }
  107 
  108       //! Sets the i-th child to the passed-in value.
  109       template<std::size_t k, class ProxyChild>
  110       void setChild (ProxyChild&& child, typename std::enable_if<lazy_enabled<k>::value,void*>::type = 0)
  111       {
  112         node().proxiedNode().template setChild<k>(std::forward<ProxyChild>(child));
  113       }
  114 
  115       const typename ProxiedNode::NodeStorage& nodeStorage () const
  116       {
  117         return node().proxiedNode().nodeStorage();
  118       }
  119 
  120     };
  121 
  122     //! Mixin class providing methods for child access with run-time parameter.
  123     /**
  124      * This class also provides the compile-time parameter based methods, as
  125      * multiple inheritance from both DynamicChildAccessors and StaticChildAccessors
  126      * creates ambigous method lookups.
  127      */
  128     template<typename ProxiedNode>
  129     class DynamicChildAccessors
  130       : public StaticChildAccessors<ProxiedNode>
  131     {
  132 
  133       typedef ProxyNode<ProxiedNode> Node;
  134 
  135       static const bool proxiedNodeIsConst = std::is_const<typename std::remove_reference<ProxiedNode>::type>::value;
  136 
  137       template<bool enabled = !proxiedNodeIsConst>
  138       typename std::enable_if<enabled,Node&>::type
  139       node ()
  140       {
  141         return static_cast<Node&>(*this);
  142       }
  143 
  144       const Node& node () const
  145       {
  146         return static_cast<const Node&>(*this);
  147       }
  148 
  149     public:
  150 
  151       //! @name Child Access (Dynamic methods)
  152       //! @{
  153 
  154       //! Returns the i-th child.
  155       /**
  156        * \returns a reference to the i-th child.
  157        */
  158       template<bool enabled = !proxiedNodeIsConst,
  159         typename std::enable_if<enabled, int>::type = 0>
  160       auto& child (std::size_t i)
  161       {
  162         return node().proxiedNode().child(i);
  163       }
  164 
  165       //! Returns the i-th child (const version).
  166       /**
  167        * \returns a const reference to the i-th child.
  168        */
  169       const auto& child (std::size_t i) const
  170       {
  171         return node().proxiedNode().child(i);
  172       }
  173 
  174       //! Returns the storage of the i-th child.
  175       /**
  176        * \returns a copy of the object storing the i-th child.
  177        */
  178       template<bool enabled = !proxiedNodeIsConst,
  179         typename std::enable_if<enabled, int>::type = 0>
  180       auto childStorage (std::size_t i)
  181       {
  182         return node().proxiedNode().childStorage(i);
  183       }
  184 
  185       //! Returns the storage of the i-th child (const version).
  186       /**
  187        * This method is only important if the child is stored as
  188        * some kind of pointer, as this allows the pointee type to
  189        * become const.
  190        * \returns a copy of the object storing the i-th child.
  191        */
  192       auto childStorage (std::size_t i) const
  193       {
  194         return node().proxiedNode().childStorage(i);
  195       }
  196 
  197       //! Sets the i-th child to the passed-in value.
  198       template<class ProxyChild, bool enabled = !proxiedNodeIsConst>
  199       void setChild (std::size_t i, ProxyChild&& child, typename std::enable_if<enabled,void*>::type = 0)
  200       {
  201         node().proxiedNode().setChild(i, std::forward<ProxyChild>(child));
  202       }
  203 
  204     };
  205 
  206     //! Tag-based dispatch to appropriate base class that provides necessary functionality.
  207     template<typename Node, typename NodeTag>
  208     struct ProxyNodeBase;
  209 
  210     //! ProxyNode base class for LeafNode.
  211     template<typename Node>
  212     struct ProxyNodeBase<Node,LeafNodeTag>
  213     {
  214     };
  215 
  216     //! ProxyNode base class for CompositeNode.
  217     template<typename Node>
  218     struct ProxyNodeBase<Node,CompositeNodeTag>
  219       : public StaticChildAccessors<Node>
  220     {
  221       typedef typename Node::ChildTypes ChildTypes;
  222       typedef typename Node::NodeStorage NodeStorage;
  223     };
  224 
  225     //! ProxyNode base class for PowerNode.
  226     template<typename Node>
  227     struct ProxyNodeBase<Node,PowerNodeTag>
  228       : public DynamicChildAccessors<Node>
  229     {
  230       typedef typename Node::ChildType ChildType;
  231       typedef typename Node::NodeStorage NodeStorage;
  232     };
  233 
  234 
  235     //! Base class for nodes acting as a proxy for an existing node.
  236     /**
  237      * ProxyNode is a utility class for implementing proxy classes
  238      * that need to provide the TypeTree node functionality of the
  239      * proxied class. It exactly mirrors the TypeTree node characteristics
  240      * of the proxied node.
  241      */
  242     template<typename Node>
  243     class ProxyNode
  244       : public ProxyNodeBase<Node,NodeTag<Node>>
  245     {
  246       static const bool proxiedNodeIsConst = std::is_const<typename std::remove_reference<Node>::type>::value;
  247 
  248       template <class N>
  249       using HasStaticDegree = index_constant<N::degree()>;
  250 
  251       template <class N>
  252       static constexpr bool hasStaticDegree = Std::is_detected<HasStaticDegree, N>::value;
  253 
  254       // accessor mixins need to be friends for access to proxiedNode()
  255       friend class StaticChildAccessors<Node>;
  256       friend class DynamicChildAccessors<Node>;
  257 
  258     public:
  259 
  260       typedef Node ProxiedNode;
  261 
  262       typedef Dune::TypeTree::NodeTag<Node> NodeTag;
  263 
  264       //! Mark this class as non leaf in the \ref TypeTree.
  265       static const bool isLeaf = Node::isLeaf;
  266 
  267       //! Mark this class as a non power in the \ref TypeTree.
  268       static const bool isPower = Node::isPower;
  269 
  270       //! Mark this class as a composite in the \ref TypeTree.
  271       static const bool isComposite = Node::isComposite;
  272 
  273       //! The number of children.
  274       static const std::size_t CHILDREN = StaticDegree<Node>::value;
  275 
  276       template <class N = Node,
  277         std::enable_if_t<hasStaticDegree<N>, int> = 0>
  278       static constexpr auto degree ()
  279       {
  280         return N::degree();
  281       }
  282 
  283       template <class N = Node,
  284         std::enable_if_t<not hasStaticDegree<N>, int> = 0>
  285       auto degree () const
  286       {
  287         return proxiedNode().degree();
  288       }
  289 
  290 
  291     protected:
  292 
  293       //! @name Access to the proxied node
  294       //! @{
  295 
  296       //! Returns the proxied node.
  297       template<bool enabled = !proxiedNodeIsConst>
  298       typename std::enable_if<enabled,Node&>::type
  299       proxiedNode ()
  300       {
  301         return *_node;
  302       }
  303 
  304       //! Returns the proxied node (const version).
  305       const Node& proxiedNode () const
  306       {
  307         return *_node;
  308       }
  309 
  310       //! Returns the storage of the proxied node.
  311       template<bool enabled = !proxiedNodeIsConst>
  312       typename std::enable_if<enabled,std::shared_ptr<Node> >::type
  313       proxiedNodeStorage ()
  314       {
  315         return _node;
  316       }
  317 
  318       //! Returns the storage of the proxied node (const version).
  319       std::shared_ptr<const Node> proxiedNodeStorage () const
  320       {
  321         return _node;
  322       }
  323 
  324       //! @}
  325 
  326       //! @name Constructors
  327       //! @{
  328 
  329       ProxyNode (Node& node)
  330         : _node(stackobject_to_shared_ptr(node))
  331       {}
  332 
  333       ProxyNode (std::shared_ptr<Node> node)
  334         : _node(std::move(node))
  335       {}
  336 
  337       //! @}
  338 
  339     private:
  340 
  341       std::shared_ptr<Node> _node;
  342     };
  343 
  344     //! \} group Nodes
  345 
  346   } // namespace TypeTree
  347 } //namespace Dune
  348 
  349 #endif // DUNE_TYPETREE_PROXYNODE_HH