ewmscp  ..
scoped.h
Go to the documentation of this file.
1 #ifndef __scoped_h__
2 #define __scoped_h__
3 
4 /*
5  template functions for scoped object handling
6  Copyright (C) 2018 Juergen Hannappel
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21 
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <dirent.h>
27 
28 #include <throwcall.h>
29 
30 namespace scoped {
31  // this is a simple amateuric attempt to achive what is described here:
32  // http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#e19-use-a-final_action-object-to-express-cleanup-if-no-suitable-resource-handle-is-available
33  // https://www.bfilipek.com/2017/04/finalact.html
34  template <typename T> class generic {
36  typedef void (*finisherType)(T&);
38  public:
39  generic(T& stopItem, finisherType Finisher):
40  finishItem(stopItem),
41  finisher(Finisher) {
42  }
45  }
46  };
47 
48  class Fd {
49  int fd;
50  const std::string& name;
51  public:
52  Fd(const std::string& Name, int _Fd):
53  fd(_Fd),
54  name(Name) {
55  }
56  ~Fd() {
57  if (fd != -1) { // don't choke on non-open files...
58  throwcall::good0(close(fd), "can't close ", name);
59  }
60  }
61  int operator() () {
62  return fd;
63  }
64  operator int () {
65  return fd;
66  }
67  operator int () const {
68  return fd;
69  }
70  };
71  class Dir {
72  DIR* dir;
73  const std::string& name;
74  public:
75  Dir(const std::string& Name, DIR* _Dir):
76  dir(_Dir),
77  name(Name) {
78  }
79  Dir(const std::string& Name):
80  name(Name) {
81  dir = throwcall::badval(opendir(name.c_str()),
82  nullptr, "can't open directory", name);
83  }
84  ~Dir() {
85  if (dir != nullptr) { // don't choke on non-open files...
86  throwcall::good0(closedir(dir), "can't close ", name);
87  }
88  }
89  DIR* operator() () {
90  return dir;
91  }
92  operator DIR* () {
93  return dir;
94  }
95  };
96 } // end of namespace scoped
97 
98 #endif
scoped::Fd::~Fd
~Fd()
Definition: scoped.h:56
throwcall::badval
T badval(T call, t badvalue, const Args &... args)
template function to wrap system calls that return a special bad value on failure
Definition: throwcall.h:54
scoped::Dir::Dir
Dir(const std::string &Name)
Definition: scoped.h:79
scoped::generic
Definition: scoped.h:34
scoped::generic::finisherType
void(* finisherType)(T &)
Definition: scoped.h:36
scoped::generic::~generic
~generic()
Definition: scoped.h:43
scoped::Fd::fd
int fd
Definition: scoped.h:49
throwcall.h
scoped::Fd::Fd
Fd(const std::string &Name, int _Fd)
Definition: scoped.h:52
scoped::Dir::Dir
Dir(const std::string &Name, DIR *_Dir)
Definition: scoped.h:75
scoped::Dir::~Dir
~Dir()
Definition: scoped.h:84
scoped::Dir::dir
DIR * dir
Definition: scoped.h:72
scoped
Definition: scoped.h:30
scoped::Fd::name
const std::string & name
Definition: scoped.h:50
scoped::Dir
Definition: scoped.h:71
scoped::generic::finisher
finisherType finisher
Definition: scoped.h:37
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
scoped::Fd
Definition: scoped.h:48
scoped::generic::finishItem
T & finishItem
Definition: scoped.h:35
scoped::Dir::name
const std::string & name
Definition: scoped.h:73