1 /*
2 Operating system dependent functionality.
3
4 Copyright (C) 2013 AMPL Optimization Inc
5
6 Permission to use, copy, modify, and distribute this software and its
7 documentation for any purpose and without fee is hereby granted,
8 provided that the above copyright notice appear in all copies and that
9 both that the copyright notice and this permission notice and warranty
10 disclaimer appear in supporting documentation.
11
12 The author and AMPL Optimization Inc disclaim all warranties with
13 regard to this software, including all implied warranties of
14 merchantability and fitness. In no event shall the author be liable
15 for any special, indirect or consequential damages or any damages
16 whatsoever resulting from loss of use, data or profits, whether in an
17 action of contract, negligence or other tortious action, arising out
18 of or in connection with the use or performance of this software.
19
20 Author: Victor Zverovich
21 */
22
23 #ifndef MP_OS_H_
24 #define MP_OS_H_
25
26 #include "mp/error.h"
27 #include "mp/posix.h"
28
29 namespace mp {
30
31 // This class provides a subset of boost filesystem's path API.
32 class path {
33 private:
34 std::string str_;
35
36
37 inline std::size_t FindLastSep() const {
38 #ifdef _WIN32
39 const char *sep = "/\\";
40 #else
41 const char sep = '/';
42 #endif
43 return str_.find_last_of(sep);
44 }
45
46 public:
47 #ifdef _WIN32
48 static const char preferred_separator = '\\';
49 #else
50 static const char preferred_separator = '/';
51 #endif
52
53 path() {}
54 explicit path(const std::string &s): str_(s) {}
55 path(const char *begin, const char *end) : str_(begin, end) {}
56
57 const std::string &string() const { return str_; }
58
59
60 path filename() const {
61 size_t last_sep = FindLastSep();
62 return last_sep == std::string::npos ?
63 *this : path(str_.substr(last_sep + 1));
64 }
65
66 path &remove_filename() {
67 size_t last_sep = FindLastSep();
68 if (last_sep == 0)
69 ++last_sep;
70 str_.resize(last_sep != std::string::npos ? last_sep : 0);
71 return *this;
72 }
73
74 // Returns a path to the system-specific temporary directory.
75 static path temp_directory_path();
76 };
77
78 // Returns the path to the currently running executable file.
79 // Throws Error on error.
80 path GetExecutablePath();
81
82 namespace internal {
(1) Event rule_of_three_violation: |
Class "mp::internal::MemoryMappedFileBase" has a user definition for at least one special function (copy constructor, copy assignment, destructor) but not all. If one of these functions requires a user definition then the others likely do as well. |
(2) Event remediation: |
Add user-definition for a copy constructor. |
(3) Event remediation: |
Add user-definition for a copy assignment operator. |
Also see events: |
[destructor] |
83 class MemoryMappedFileBase {
84 private:
85 char *start_;
86 std::size_t size_;
87
88 FMT_DISALLOW_COPY_AND_ASSIGN(MemoryMappedFileBase);
89
90 protected:
91 MemoryMappedFileBase() : start_(), size_(0) {}
92 ~MemoryMappedFileBase() {
93 if (start_)
94 unmap();
95 }
96
97 void map(int fd, std::size_t size);
98 void unmap();
99
100 public:
101 const char *start() const { return start_; }
102 std::size_t size() const { return size_; }
103 };
104
105 // Converts file size to mmap size.
106 inline std::size_t ConvertFileToMmapSize(fmt::LongLong file_size,
107 fmt::CStringRef filename) {
108 MP_ASSERT(file_size >= 0, "negative file size");
109 fmt::ULongLong unsigned_file_size = file_size;
110 // Check if file size fits in size_t.
111 std::size_t size = static_cast<std::size_t>(unsigned_file_size);
112 if (size != unsigned_file_size)
113 throw Error("file {} is too big", filename);
114 return size;
115 }
116 } // namespace internal
117
118 template <typename File = fmt::File>
119 class MemoryMappedFile : public internal::MemoryMappedFileBase {
120 public:
121 MemoryMappedFile() {}
122 MemoryMappedFile(const File &file, std::size_t size) {
123 internal::MemoryMappedFileBase::map(file.descriptor(), size);
124 }
125
126 void map(const File &file, std::size_t size) {
127 if (start())
128 unmap();
129 internal::MemoryMappedFileBase::map(file.descriptor(), size);
130 }
131
132 void map(const File &file, fmt::CStringRef filename) {
133 map(file, internal::ConvertFileToMmapSize(file.size(), filename));
134 }
135 };
136
137 // The default buffer size.
138 enum { BUFFER_SIZE = 500 };
139 } // namespace mp
140
141 #endif // MP_OS_H_
142