Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[simix] Make Mutex a C++ class (kind-of)
[simgrid.git] / include / xbt / functional.hpp
1 /* Copyright (c) 2015-2016. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #ifndef XBT_FUNCTIONAL_HPP
8 #define XBT_FUNCTIONAL_HPP
9
10 #include <cstdlib>
11
12 #include <exception>
13 #include <functional>
14 #include <future>
15 #include <utility>
16
17 #include <xbt/sysdep.h>
18
19 namespace simgrid {
20 namespace xbt {
21
22 class args {
23 private:
24   int argc_ = 0;
25   char** argv_ = nullptr;
26 public:
27
28   // Main constructors
29   args() {}
30
31   void assign(int argc, const char*const* argv)
32   {
33     clear();
34     char** new_argv = xbt_new(char*,argc + 1);
35     for (int i = 0; i < argc; i++)
36       new_argv[i] = xbt_strdup(argv[i]);
37     new_argv[argc] = nullptr;
38     this->argc_ = argc;
39     this->argv_ = new_argv;
40   }
41   args(int argc, const char*const* argv)
42   {
43     this->assign(argc, argv);
44   }
45
46   char** to_argv() const
47   {
48     const int argc = argc_;
49     char** argv = xbt_new(char*, argc + 1);
50     for (int i=0; i< argc; i++)
51       argv[i] = xbt_strdup(argv_[i]);
52     argv[argc] = nullptr;
53     return argv;
54   }
55
56   // Free
57   void clear()
58   {
59     for (int i = 0; i < this->argc_; i++)
60       std::free(this->argv_[i]);
61     std::free(this->argv_);
62     this->argc_ = 0;
63     this->argv_ = nullptr;
64   }
65   ~args() { clear(); }
66
67   // Copy
68   args(args const& that)
69   {
70     this->assign(that.argc(), that.argv());
71   }
72   args& operator=(args const& that)
73   {
74     this->assign(that.argc(), that.argv());
75     return *this;
76   }
77
78   // Move:
79   args(args&& that) : argc_(that.argc_), argv_(that.argv_)
80   {
81     that.argc_ = 0;
82     that.argv_ = nullptr;
83   }
84   args& operator=(args&& that)
85   {
86     this->argc_ = that.argc_;
87     this->argv_ = that.argv_;
88     that.argc_ = 0;
89     that.argv_ = nullptr;
90     return *this;
91   }
92
93   int    argc()            const { return argc_; }
94   char** argv()                  { return argv_; }
95   const char*const* argv() const { return argv_; }
96   char* operator[](std::size_t i) { return argv_[i]; }
97 };
98
99 template<class F> inline
100 std::function<void()> wrapMain(F code, std::shared_ptr<simgrid::xbt::args> args)
101 {
102   return [=]() {
103     code(args->argc(), args->argv());
104   };
105 }
106
107 template<class F> inline
108 std::function<void()> wrapMain(F code, simgrid::xbt::args args)
109 {
110   return wrapMain(std::move(code),
111     std::unique_ptr<simgrid::xbt::args>(new simgrid::xbt::args(std::move(args))));
112 }
113
114 template<class F> inline
115 std::function<void()> wrapMain(F code, int argc, const char*const* argv)
116 {
117   return wrapMain(std::move(code), args(argc, argv));
118 }
119
120 }
121 }
122
123 #endif