dune-fem  2.6-git
bindguard.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_COMMON_BINDGUARD_HH
2 #define DUNE_FEM_COMMON_BINDGUARD_HH
3 
4 #include <memory>
5 #include <tuple>
6 #include <utility>
7 
8 #include <dune/common/typeutilities.hh>
9 
10 namespace Dune
11 {
12 
13  namespace Fem
14  {
15 
16  // BindGuard
17  // ---------
18 
19  template< class Object >
20  struct BindGuard
21  {
22  template< class... Args >
23  BindGuard ( Object &object, Args &&... args )
24  : object_( &object )
25  {
26  object.bind( std::forward< Args >( args )... );
27  }
28 
29  private:
30  struct Deleter
31  {
32  void operator() ( Object *object ) { object->unbind(); }
33  };
34 
35  std::unique_ptr< Object, Deleter > object_;
36  };
37 
38 
39 
40  // isBindable
41  // ----------
42 
43  namespace Impl
44  {
45 
46  template< class Object, class... Args >
47  auto isBindable ( PriorityTag< 1 >, Object &object, Args &&... args )
48  -> decltype( std::declval< Object & >().bind( std::declval< Args >()... ), std::true_type() );
49 
50  template< class Object, class... Args >
51  auto isBindable ( PriorityTag< 0 >, Object &object, Args &&... args )
52  -> std::false_type;
53 
54  } // namespace Impl
55 
56  template< class Object, class... Args >
57  struct isBindable
58  : public decltype( Impl::isBindable( PriorityTag< 42 >(), std::declval< Object & >(), std::declval< Args >()... ) )
59  {};
60 
61 
62 
63  // bindGuard
64  // ---------
65 
66  template< class Object, class... Args >
67  inline static auto bindGuard ( Object &object, Args &&... args )
68  -> std::enable_if_t< isBindable< Object, Args... >::value, BindGuard< Object > >
69  {
70  return BindGuard< Object >( object, std::forward< Args >( args )... );
71  }
72 
73  template< std::size_t... i, class Objects, class... Args >
74  inline static auto bindGuard ( std::index_sequence< i... >, Objects objects, Args &&... args )
75  -> std::tuple< decltype( bindGuard( std::declval< std::tuple_element_t< i, Objects > >(), std::declval< Args >()... ) )... >
76  {
77  // note: do not forward args, as there the tuple might contain multiple entries
78  return std::make_tuple( bindGuard( std::get< i >( objects ), args... )... );
79  }
80 
81  template< class... Object, class... Args >
82  inline static auto bindGuard ( std::tuple< Object &... > objects, Args &&... args )
83  -> decltype( bindGuard( std::index_sequence_for< Object... >(), objects, std::forward< Args >( args )... ) )
84  {
85  return bindGuard( std::index_sequence_for< Object... >(), objects, std::forward< Args >( args )... );
86  }
87 
88  } // namespace Fem
89 
90 } // namespace Dune
91 
92 #endif // #ifndef DUNE_FEM_COMMON_BINDGUARD_HH
Definition: bindguard.hh:11
static auto bindGuard(Object &object, Args &&... args) -> std::enable_if_t< isBindable< Object, Args... >::value, BindGuard< Object > >
Definition: bindguard.hh:67
Definition: bindguard.hh:21
BindGuard(Object &object, Args &&... args)
Definition: bindguard.hh:23
Definition: bindguard.hh:59