Bug Summary

File:tools/llvm-readobj/Win64EHDumper.cpp
Warning:line 293, column 9
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Win64EHDumper.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/tools/llvm-readobj -I /build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325874/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/tools/llvm-readobj -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-23-163436-368-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj/Win64EHDumper.cpp

/build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj/Win64EHDumper.cpp

1//===- Win64EHDumper.cpp - Win64 EH Printer ---------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Win64EHDumper.h"
11#include "llvm-readobj.h"
12#include "llvm/Object/COFF.h"
13#include "llvm/Support/ErrorHandling.h"
14#include "llvm/Support/Format.h"
15
16using namespace llvm;
17using namespace llvm::object;
18using namespace llvm::Win64EH;
19
20static const EnumEntry<unsigned> UnwindFlags[] = {
21 { "ExceptionHandler", UNW_ExceptionHandler },
22 { "TerminateHandler", UNW_TerminateHandler },
23 { "ChainInfo" , UNW_ChainInfo }
24};
25
26static const EnumEntry<unsigned> UnwindOpInfo[] = {
27 { "RAX", 0 },
28 { "RCX", 1 },
29 { "RDX", 2 },
30 { "RBX", 3 },
31 { "RSP", 4 },
32 { "RBP", 5 },
33 { "RSI", 6 },
34 { "RDI", 7 },
35 { "R8", 8 },
36 { "R9", 9 },
37 { "R10", 10 },
38 { "R11", 11 },
39 { "R12", 12 },
40 { "R13", 13 },
41 { "R14", 14 },
42 { "R15", 15 }
43};
44
45static uint64_t getOffsetOfLSDA(const UnwindInfo& UI) {
46 return static_cast<const char*>(UI.getLanguageSpecificData())
47 - reinterpret_cast<const char*>(&UI);
48}
49
50static uint32_t getLargeSlotValue(ArrayRef<UnwindCode> UC) {
51 if (UC.size() < 3)
52 return 0;
53 return UC[1].FrameOffset + (static_cast<uint32_t>(UC[2].FrameOffset) << 16);
54}
55
56// Returns the name of the unwind code.
57static StringRef getUnwindCodeTypeName(uint8_t Code) {
58 switch (Code) {
59 default: llvm_unreachable("Invalid unwind code")::llvm::llvm_unreachable_internal("Invalid unwind code", "/build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj/Win64EHDumper.cpp"
, 59)
;
60 case UOP_PushNonVol: return "PUSH_NONVOL";
61 case UOP_AllocLarge: return "ALLOC_LARGE";
62 case UOP_AllocSmall: return "ALLOC_SMALL";
63 case UOP_SetFPReg: return "SET_FPREG";
64 case UOP_SaveNonVol: return "SAVE_NONVOL";
65 case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR";
66 case UOP_SaveXMM128: return "SAVE_XMM128";
67 case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
68 case UOP_PushMachFrame: return "PUSH_MACHFRAME";
69 }
70}
71
72// Returns the name of a referenced register.
73static StringRef getUnwindRegisterName(uint8_t Reg) {
74 switch (Reg) {
75 default: llvm_unreachable("Invalid register")::llvm::llvm_unreachable_internal("Invalid register", "/build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj/Win64EHDumper.cpp"
, 75)
;
76 case 0: return "RAX";
77 case 1: return "RCX";
78 case 2: return "RDX";
79 case 3: return "RBX";
80 case 4: return "RSP";
81 case 5: return "RBP";
82 case 6: return "RSI";
83 case 7: return "RDI";
84 case 8: return "R8";
85 case 9: return "R9";
86 case 10: return "R10";
87 case 11: return "R11";
88 case 12: return "R12";
89 case 13: return "R13";
90 case 14: return "R14";
91 case 15: return "R15";
92 }
93}
94
95// Calculates the number of array slots required for the unwind code.
96static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
97 switch (UnwindCode.getUnwindOp()) {
98 default: llvm_unreachable("Invalid unwind code")::llvm::llvm_unreachable_internal("Invalid unwind code", "/build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj/Win64EHDumper.cpp"
, 98)
;
99 case UOP_PushNonVol:
100 case UOP_AllocSmall:
101 case UOP_SetFPReg:
102 case UOP_PushMachFrame:
103 return 1;
104 case UOP_SaveNonVol:
105 case UOP_SaveXMM128:
106 return 2;
107 case UOP_SaveNonVolBig:
108 case UOP_SaveXMM128Big:
109 return 3;
110 case UOP_AllocLarge:
111 return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
112 }
113}
114
115static std::string formatSymbol(const Dumper::Context &Ctx,
116 const coff_section *Section, uint64_t Offset,
117 uint32_t Displacement) {
118 std::string Buffer;
119 raw_string_ostream OS(Buffer);
120
121 SymbolRef Symbol;
122 if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) {
123 Expected<StringRef> Name = Symbol.getName();
124 if (Name) {
125 OS << *Name;
126 if (Displacement > 0)
127 OS << format(" +0x%X (0x%" PRIX64"l" "X" ")", Displacement, Offset);
128 else
129 OS << format(" (0x%" PRIX64"l" "X" ")", Offset);
130 return OS.str();
131 } else {
132 // TODO: Actually report errors helpfully.
133 consumeError(Name.takeError());
134 }
135 }
136
137 OS << format(" (0x%" PRIX64"l" "X" ")", Offset);
138 return OS.str();
139}
140
141static std::error_code resolveRelocation(const Dumper::Context &Ctx,
142 const coff_section *Section,
143 uint64_t Offset,
144 const coff_section *&ResolvedSection,
145 uint64_t &ResolvedAddress) {
146 SymbolRef Symbol;
20
Calling defaulted default constructor for 'SymbolRef'
25
Returning from default constructor for 'SymbolRef'
147 if (std::error_code EC =
26
Calling 'error_code::operator bool'
28
Returning from 'error_code::operator bool'
29
Taking false branch
148 Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData))
149 return EC;
150
151 Expected<uint64_t> ResolvedAddressOrErr = Symbol.getAddress();
30
Calling 'SymbolRef::getAddress'
57
Returning from 'SymbolRef::getAddress'
58
Calling move constructor for 'Expected'
143
Returning from move constructor for 'Expected'
152 if (!ResolvedAddressOrErr)
144
Calling 'Expected::operator bool'
145
Returning from 'Expected::operator bool'
146
Taking true branch
153 return errorToErrorCode(ResolvedAddressOrErr.takeError());
147
Calling 'Expected::takeError'
154
Returning from 'Expected::takeError'
155
Calling '~Expected'
165
Returning from '~Expected'
154 ResolvedAddress = *ResolvedAddressOrErr;
155
156 Expected<section_iterator> SI = Symbol.getSection();
157 if (!SI)
158 return errorToErrorCode(SI.takeError());
159 ResolvedSection = Ctx.COFF.getCOFFSection(**SI);
160 return std::error_code();
161}
162
163namespace llvm {
164namespace Win64EH {
165void Dumper::printRuntimeFunctionEntry(const Context &Ctx,
166 const coff_section *Section,
167 uint64_t Offset,
168 const RuntimeFunction &RF) {
169 SW.printString("StartAddress",
170 formatSymbol(Ctx, Section, Offset + 0, RF.StartAddress));
171 SW.printString("EndAddress",
172 formatSymbol(Ctx, Section, Offset + 4, RF.EndAddress));
173 SW.printString("UnwindInfoAddress",
174 formatSymbol(Ctx, Section, Offset + 8, RF.UnwindInfoOffset));
175}
176
177// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
178// the unwind codes array, this function requires that the correct number of
179// slots is provided.
180void Dumper::printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC) {
181 assert(UC.size() >= getNumUsedSlots(UC[0]))(static_cast <bool> (UC.size() >= getNumUsedSlots(UC
[0])) ? void (0) : __assert_fail ("UC.size() >= getNumUsedSlots(UC[0])"
, "/build/llvm-toolchain-snapshot-7~svn325874/tools/llvm-readobj/Win64EHDumper.cpp"
, 181, __extension__ __PRETTY_FUNCTION__))
;
182
183 SW.startLine() << format("0x%02X: ", unsigned(UC[0].u.CodeOffset))
184 << getUnwindCodeTypeName(UC[0].getUnwindOp());
185
186 switch (UC[0].getUnwindOp()) {
187 case UOP_PushNonVol:
188 OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo());
189 break;
190
191 case UOP_AllocLarge:
192 OS << " size="
193 << ((UC[0].getOpInfo() == 0) ? UC[1].FrameOffset * 8
194 : getLargeSlotValue(UC));
195 break;
196
197 case UOP_AllocSmall:
198 OS << " size=" << (UC[0].getOpInfo() + 1) * 8;
199 break;
200
201 case UOP_SetFPReg:
202 if (UI.getFrameRegister() == 0)
203 OS << " reg=<invalid>";
204 else
205 OS << " reg=" << getUnwindRegisterName(UI.getFrameRegister())
206 << format(", offset=0x%X", UI.getFrameOffset() * 16);
207 break;
208
209 case UOP_SaveNonVol:
210 OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo())
211 << format(", offset=0x%X", UC[1].FrameOffset * 8);
212 break;
213
214 case UOP_SaveNonVolBig:
215 OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo())
216 << format(", offset=0x%X", getLargeSlotValue(UC));
217 break;
218
219 case UOP_SaveXMM128:
220 OS << " reg=XMM" << static_cast<uint32_t>(UC[0].getOpInfo())
221 << format(", offset=0x%X", UC[1].FrameOffset * 16);
222 break;
223
224 case UOP_SaveXMM128Big:
225 OS << " reg=XMM" << static_cast<uint32_t>(UC[0].getOpInfo())
226 << format(", offset=0x%X", getLargeSlotValue(UC));
227 break;
228
229 case UOP_PushMachFrame:
230 OS << " errcode=" << (UC[0].getOpInfo() == 0 ? "no" : "yes");
231 break;
232 }
233
234 OS << "\n";
235}
236
237void Dumper::printUnwindInfo(const Context &Ctx, const coff_section *Section,
238 off_t Offset, const UnwindInfo &UI) {
239 DictScope UIS(SW, "UnwindInfo");
240 SW.printNumber("Version", UI.getVersion());
241 SW.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
242 SW.printNumber("PrologSize", UI.PrologSize);
243 if (UI.getFrameRegister()) {
244 SW.printEnum("FrameRegister", UI.getFrameRegister(),
245 makeArrayRef(UnwindOpInfo));
246 SW.printHex("FrameOffset", UI.getFrameOffset());
247 } else {
248 SW.printString("FrameRegister", StringRef("-"));
249 SW.printString("FrameOffset", StringRef("-"));
250 }
251
252 SW.printNumber("UnwindCodeCount", UI.NumCodes);
253 {
254 ListScope UCS(SW, "UnwindCodes");
255 ArrayRef<UnwindCode> UC(&UI.UnwindCodes[0], UI.NumCodes);
256 for (const UnwindCode *UCI = UC.begin(), *UCE = UC.end(); UCI < UCE; ++UCI) {
257 unsigned UsedSlots = getNumUsedSlots(*UCI);
258 if (UsedSlots > UC.size()) {
259 errs() << "corrupt unwind data";
260 return;
261 }
262
263 printUnwindCode(UI, makeArrayRef(UCI, UCE));
264 UCI = UCI + UsedSlots - 1;
265 }
266 }
267
268 uint64_t LSDAOffset = Offset + getOffsetOfLSDA(UI);
269 if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
270 SW.printString("Handler",
271 formatSymbol(Ctx, Section, LSDAOffset,
272 UI.getLanguageSpecificHandlerOffset()));
273 } else if (UI.getFlags() & UNW_ChainInfo) {
274 if (const RuntimeFunction *Chained = UI.getChainedFunctionEntry()) {
275 DictScope CS(SW, "Chained");
276 printRuntimeFunctionEntry(Ctx, Section, LSDAOffset, *Chained);
277 }
278 }
279}
280
281void Dumper::printRuntimeFunction(const Context &Ctx,
282 const coff_section *Section,
283 uint64_t SectionOffset,
284 const RuntimeFunction &RF) {
285 DictScope RFS(SW, "RuntimeFunction");
286 printRuntimeFunctionEntry(Ctx, Section, SectionOffset, RF);
287
288 const coff_section *XData;
18
'XData' declared without an initial value
289 uint64_t Offset;
290 resolveRelocation(Ctx, Section, SectionOffset + 8, XData, Offset);
19
Calling 'resolveRelocation'
166
Returning from 'resolveRelocation'
291
292 ArrayRef<uint8_t> Contents;
293 error(Ctx.COFF.getSectionContents(XData, Contents));
167
1st function call argument is an uninitialized value
294 if (Contents.empty())
295 return;
296
297 Offset = Offset + RF.UnwindInfoOffset;
298 if (Offset > Contents.size())
299 return;
300
301 const auto UI = reinterpret_cast<const UnwindInfo*>(Contents.data() + Offset);
302 printUnwindInfo(Ctx, XData, Offset, *UI);
303}
304
305void Dumper::printData(const Context &Ctx) {
306 for (const auto &Section : Ctx.COFF.sections()) {
307 StringRef Name;
308 Section.getName(Name);
309
310 if (Name != ".pdata" && !Name.startswith(".pdata$"))
1
Taking false branch
5
Taking false branch
9
Taking false branch
13
Taking false branch
311 continue;
312
313 const coff_section *PData = Ctx.COFF.getCOFFSection(Section);
314 ArrayRef<uint8_t> Contents;
315 error(Ctx.COFF.getSectionContents(PData, Contents));
316 if (Contents.empty())
2
Assuming the condition is false
3
Taking false branch
6
Assuming the condition is false
7
Taking false branch
10
Assuming the condition is false
11
Taking false branch
14
Assuming the condition is false
15
Taking false branch
317 continue;
318
319 const RuntimeFunction *Entries =
320 reinterpret_cast<const RuntimeFunction *>(Contents.data());
321 const size_t Count = Contents.size() / sizeof(RuntimeFunction);
322 ArrayRef<RuntimeFunction> RuntimeFunctions(Entries, Count);
323
324 size_t Index = 0;
325 for (const auto &RF : RuntimeFunctions) {
4
Assuming '__begin3' is equal to '__end3'
8
Assuming '__begin3' is equal to '__end3'
12
Assuming '__begin3' is equal to '__end3'
16
Assuming '__begin3' is not equal to '__end3'
326 printRuntimeFunction(Ctx, Ctx.COFF.getCOFFSection(Section),
17
Calling 'Dumper::printRuntimeFunction'
327 Index * sizeof(RuntimeFunction), RF);
328 ++Index;
329 }
330 }
331}
332}
333}
334

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Object/ObjectFile.h

1//===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares a file format independent ObjectFile class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_OBJECTFILE_H
15#define LLVM_OBJECT_OBJECTFILE_H
16
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/Triple.h"
19#include "llvm/ADT/iterator_range.h"
20#include "llvm/BinaryFormat/Magic.h"
21#include "llvm/MC/SubtargetFeature.h"
22#include "llvm/Object/Binary.h"
23#include "llvm/Object/Error.h"
24#include "llvm/Object/SymbolicFile.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/Error.h"
27#include "llvm/Support/FileSystem.h"
28#include "llvm/Support/MemoryBuffer.h"
29#include <cassert>
30#include <cstdint>
31#include <memory>
32#include <system_error>
33
34namespace llvm {
35
36class ARMAttributeParser;
37
38namespace object {
39
40class COFFObjectFile;
41class MachOObjectFile;
42class ObjectFile;
43class SectionRef;
44class SymbolRef;
45class symbol_iterator;
46class WasmObjectFile;
47
48using section_iterator = content_iterator<SectionRef>;
49
50/// This is a value type class that represents a single relocation in the list
51/// of relocations in the object file.
52class RelocationRef {
53 DataRefImpl RelocationPimpl;
54 const ObjectFile *OwningObject = nullptr;
55
56public:
57 RelocationRef() = default;
58 RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
59
60 bool operator==(const RelocationRef &Other) const;
61
62 void moveNext();
63
64 uint64_t getOffset() const;
65 symbol_iterator getSymbol() const;
66 uint64_t getType() const;
67
68 /// @brief Get a string that represents the type of this relocation.
69 ///
70 /// This is for display purposes only.
71 void getTypeName(SmallVectorImpl<char> &Result) const;
72
73 DataRefImpl getRawDataRefImpl() const;
74 const ObjectFile *getObject() const;
75};
76
77using relocation_iterator = content_iterator<RelocationRef>;
78
79/// This is a value type class that represents a single section in the list of
80/// sections in the object file.
81class SectionRef {
82 friend class SymbolRef;
83
84 DataRefImpl SectionPimpl;
85 const ObjectFile *OwningObject = nullptr;
86
87public:
88 SectionRef() = default;
89 SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
90
91 bool operator==(const SectionRef &Other) const;
92 bool operator!=(const SectionRef &Other) const;
93 bool operator<(const SectionRef &Other) const;
94
95 void moveNext();
96
97 std::error_code getName(StringRef &Result) const;
98 uint64_t getAddress() const;
99 uint64_t getIndex() const;
100 uint64_t getSize() const;
101 std::error_code getContents(StringRef &Result) const;
102
103 /// @brief Get the alignment of this section as the actual value (not log 2).
104 uint64_t getAlignment() const;
105
106 bool isCompressed() const;
107 bool isText() const;
108 bool isData() const;
109 bool isBSS() const;
110 bool isVirtual() const;
111 bool isBitcode() const;
112 bool isStripped() const;
113
114 bool containsSymbol(SymbolRef S) const;
115
116 relocation_iterator relocation_begin() const;
117 relocation_iterator relocation_end() const;
118 iterator_range<relocation_iterator> relocations() const {
119 return make_range(relocation_begin(), relocation_end());
120 }
121 section_iterator getRelocatedSection() const;
122
123 DataRefImpl getRawDataRefImpl() const;
124 const ObjectFile *getObject() const;
125};
126
127/// This is a value type class that represents a single symbol in the list of
128/// symbols in the object file.
129class SymbolRef : public BasicSymbolRef {
130 friend class SectionRef;
131
132public:
133 enum Type {
134 ST_Unknown, // Type not specified
135 ST_Data,
136 ST_Debug,
137 ST_File,
138 ST_Function,
139 ST_Other
140 };
141
142 SymbolRef() = default;
21
Calling defaulted default constructor for 'BasicSymbolRef'
24
Returning from default constructor for 'BasicSymbolRef'
143 SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
144 SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
145 assert(isa<ObjectFile>(BasicSymbolRef::getObject()))(static_cast <bool> (isa<ObjectFile>(BasicSymbolRef
::getObject())) ? void (0) : __assert_fail ("isa<ObjectFile>(BasicSymbolRef::getObject())"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Object/ObjectFile.h"
, 145, __extension__ __PRETTY_FUNCTION__))
;
146 }
147
148 Expected<StringRef> getName() const;
149 /// Returns the symbol virtual address (i.e. address at which it will be
150 /// mapped).
151 Expected<uint64_t> getAddress() const;
152
153 /// Return the value of the symbol depending on the object this can be an
154 /// offset or a virtual address.
155 uint64_t getValue() const;
156
157 /// @brief Get the alignment of this symbol as the actual value (not log 2).
158 uint32_t getAlignment() const;
159 uint64_t getCommonSize() const;
160 Expected<SymbolRef::Type> getType() const;
161
162 /// @brief Get section this symbol is defined in reference to. Result is
163 /// end_sections() if it is undefined or is an absolute symbol.
164 Expected<section_iterator> getSection() const;
165
166 const ObjectFile *getObject() const;
167};
168
169class symbol_iterator : public basic_symbol_iterator {
170public:
171 symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
172 symbol_iterator(const basic_symbol_iterator &B)
173 : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
174 cast<ObjectFile>(B->getObject()))) {}
175
176 const SymbolRef *operator->() const {
177 const BasicSymbolRef &P = basic_symbol_iterator::operator *();
178 return static_cast<const SymbolRef*>(&P);
179 }
180
181 const SymbolRef &operator*() const {
182 const BasicSymbolRef &P = basic_symbol_iterator::operator *();
183 return static_cast<const SymbolRef&>(P);
184 }
185};
186
187/// This class is the base class for all object file types. Concrete instances
188/// of this object are created by createObjectFile, which figures out which type
189/// to create.
190class ObjectFile : public SymbolicFile {
191 virtual void anchor();
192
193protected:
194 ObjectFile(unsigned int Type, MemoryBufferRef Source);
195
196 const uint8_t *base() const {
197 return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
198 }
199
200 // These functions are for SymbolRef to call internally. The main goal of
201 // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
202 // entry in the memory mapped object file. SymbolPimpl cannot contain any
203 // virtual functions because then it could not point into the memory mapped
204 // file.
205 //
206 // Implementations assume that the DataRefImpl is valid and has not been
207 // modified externally. It's UB otherwise.
208 friend class SymbolRef;
209
210 virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
211 std::error_code printSymbolName(raw_ostream &OS,
212 DataRefImpl Symb) const override;
213 virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
214 virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
215 virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
216 virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
217 virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
218 virtual Expected<section_iterator>
219 getSymbolSection(DataRefImpl Symb) const = 0;
220
221 // Same as above for SectionRef.
222 friend class SectionRef;
223
224 virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
225 virtual std::error_code getSectionName(DataRefImpl Sec,
226 StringRef &Res) const = 0;
227 virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
228 virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
229 virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
230 virtual std::error_code getSectionContents(DataRefImpl Sec,
231 StringRef &Res) const = 0;
232 virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
233 virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
234 virtual bool isSectionText(DataRefImpl Sec) const = 0;
235 virtual bool isSectionData(DataRefImpl Sec) const = 0;
236 virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
237 // A section is 'virtual' if its contents aren't present in the object image.
238 virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
239 virtual bool isSectionBitcode(DataRefImpl Sec) const;
240 virtual bool isSectionStripped(DataRefImpl Sec) const;
241 virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
242 virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
243 virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
244
245 // Same as above for RelocationRef.
246 friend class RelocationRef;
247 virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
248 virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
249 virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
250 virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
251 virtual void getRelocationTypeName(DataRefImpl Rel,
252 SmallVectorImpl<char> &Result) const = 0;
253
254 uint64_t getSymbolValue(DataRefImpl Symb) const;
255
256public:
257 ObjectFile() = delete;
258 ObjectFile(const ObjectFile &other) = delete;
259
260 uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
261 assert(getSymbolFlags(Symb) & SymbolRef::SF_Common)(static_cast <bool> (getSymbolFlags(Symb) & SymbolRef
::SF_Common) ? void (0) : __assert_fail ("getSymbolFlags(Symb) & SymbolRef::SF_Common"
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Object/ObjectFile.h"
, 261, __extension__ __PRETTY_FUNCTION__))
;
262 return getCommonSymbolSizeImpl(Symb);
263 }
264
265 using symbol_iterator_range = iterator_range<symbol_iterator>;
266 symbol_iterator_range symbols() const {
267 return symbol_iterator_range(symbol_begin(), symbol_end());
268 }
269
270 virtual section_iterator section_begin() const = 0;
271 virtual section_iterator section_end() const = 0;
272
273 using section_iterator_range = iterator_range<section_iterator>;
274 section_iterator_range sections() const {
275 return section_iterator_range(section_begin(), section_end());
276 }
277
278 /// @brief The number of bytes used to represent an address in this object
279 /// file format.
280 virtual uint8_t getBytesInAddress() const = 0;
281
282 virtual StringRef getFileFormatName() const = 0;
283 virtual Triple::ArchType getArch() const = 0;
284 virtual SubtargetFeatures getFeatures() const = 0;
285 virtual void setARMSubArch(Triple &TheTriple) const { }
286
287 /// @brief Create a triple from the data in this object file.
288 Triple makeTriple() const;
289
290 virtual std::error_code
291 getBuildAttributes(ARMAttributeParser &Attributes) const {
292 return std::error_code();
293 }
294
295 /// Maps a debug section name to a standard DWARF section name.
296 virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
297
298 /// True if this is a relocatable object (.o/.obj).
299 virtual bool isRelocatableObject() const = 0;
300
301 /// @returns Pointer to ObjectFile subclass to handle this type of object.
302 /// @param ObjectPath The path to the object file. ObjectPath.isObject must
303 /// return true.
304 /// @brief Create ObjectFile from path.
305 static Expected<OwningBinary<ObjectFile>>
306 createObjectFile(StringRef ObjectPath);
307
308 static Expected<std::unique_ptr<ObjectFile>>
309 createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
310 static Expected<std::unique_ptr<ObjectFile>>
311 createObjectFile(MemoryBufferRef Object) {
312 return createObjectFile(Object, llvm::file_magic::unknown);
313 }
314
315 static bool classof(const Binary *v) {
316 return v->isObject();
317 }
318
319 static Expected<std::unique_ptr<COFFObjectFile>>
320 createCOFFObjectFile(MemoryBufferRef Object);
321
322 static Expected<std::unique_ptr<ObjectFile>>
323 createELFObjectFile(MemoryBufferRef Object);
324
325 static Expected<std::unique_ptr<MachOObjectFile>>
326 createMachOObjectFile(MemoryBufferRef Object,
327 uint32_t UniversalCputype = 0,
328 uint32_t UniversalIndex = 0);
329
330 static Expected<std::unique_ptr<WasmObjectFile>>
331 createWasmObjectFile(MemoryBufferRef Object);
332};
333
334// Inline function definitions.
335inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
336 : BasicSymbolRef(SymbolP, Owner) {}
337
338inline Expected<StringRef> SymbolRef::getName() const {
339 return getObject()->getSymbolName(getRawDataRefImpl());
340}
341
342inline Expected<uint64_t> SymbolRef::getAddress() const {
343 return getObject()->getSymbolAddress(getRawDataRefImpl());
31
Calling 'SymbolRef::getObject'
54
Returning from 'SymbolRef::getObject'
55
Calling 'BasicSymbolRef::getRawDataRefImpl'
56
Returning from 'BasicSymbolRef::getRawDataRefImpl'
344}
345
346inline uint64_t SymbolRef::getValue() const {
347 return getObject()->getSymbolValue(getRawDataRefImpl());
348}
349
350inline uint32_t SymbolRef::getAlignment() const {
351 return getObject()->getSymbolAlignment(getRawDataRefImpl());
352}
353
354inline uint64_t SymbolRef::getCommonSize() const {
355 return getObject()->getCommonSymbolSize(getRawDataRefImpl());
356}
357
358inline Expected<section_iterator> SymbolRef::getSection() const {
359 return getObject()->getSymbolSection(getRawDataRefImpl());
360}
361
362inline Expected<SymbolRef::Type> SymbolRef::getType() const {
363 return getObject()->getSymbolType(getRawDataRefImpl());
364}
365
366inline const ObjectFile *SymbolRef::getObject() const {
367 const SymbolicFile *O = BasicSymbolRef::getObject();
32
Calling 'BasicSymbolRef::getObject'
33
Returning from 'BasicSymbolRef::getObject'
368 return cast<ObjectFile>(O);
34
Calling 'cast'
53
Returning from 'cast'
369}
370
371/// SectionRef
372inline SectionRef::SectionRef(DataRefImpl SectionP,
373 const ObjectFile *Owner)
374 : SectionPimpl(SectionP)
375 , OwningObject(Owner) {}
376
377inline bool SectionRef::operator==(const SectionRef &Other) const {
378 return SectionPimpl == Other.SectionPimpl;
379}
380
381inline bool SectionRef::operator!=(const SectionRef &Other) const {
382 return SectionPimpl != Other.SectionPimpl;
383}
384
385inline bool SectionRef::operator<(const SectionRef &Other) const {
386 return SectionPimpl < Other.SectionPimpl;
387}
388
389inline void SectionRef::moveNext() {
390 return OwningObject->moveSectionNext(SectionPimpl);
391}
392
393inline std::error_code SectionRef::getName(StringRef &Result) const {
394 return OwningObject->getSectionName(SectionPimpl, Result);
395}
396
397inline uint64_t SectionRef::getAddress() const {
398 return OwningObject->getSectionAddress(SectionPimpl);
399}
400
401inline uint64_t SectionRef::getIndex() const {
402 return OwningObject->getSectionIndex(SectionPimpl);
403}
404
405inline uint64_t SectionRef::getSize() const {
406 return OwningObject->getSectionSize(SectionPimpl);
407}
408
409inline std::error_code SectionRef::getContents(StringRef &Result) const {
410 return OwningObject->getSectionContents(SectionPimpl, Result);
411}
412
413inline uint64_t SectionRef::getAlignment() const {
414 return OwningObject->getSectionAlignment(SectionPimpl);
415}
416
417inline bool SectionRef::isCompressed() const {
418 return OwningObject->isSectionCompressed(SectionPimpl);
419}
420
421inline bool SectionRef::isText() const {
422 return OwningObject->isSectionText(SectionPimpl);
423}
424
425inline bool SectionRef::isData() const {
426 return OwningObject->isSectionData(SectionPimpl);
427}
428
429inline bool SectionRef::isBSS() const {
430 return OwningObject->isSectionBSS(SectionPimpl);
431}
432
433inline bool SectionRef::isVirtual() const {
434 return OwningObject->isSectionVirtual(SectionPimpl);
435}
436
437inline bool SectionRef::isBitcode() const {
438 return OwningObject->isSectionBitcode(SectionPimpl);
439}
440
441inline bool SectionRef::isStripped() const {
442 return OwningObject->isSectionStripped(SectionPimpl);
443}
444
445inline relocation_iterator SectionRef::relocation_begin() const {
446 return OwningObject->section_rel_begin(SectionPimpl);
447}
448
449inline relocation_iterator SectionRef::relocation_end() const {
450 return OwningObject->section_rel_end(SectionPimpl);
451}
452
453inline section_iterator SectionRef::getRelocatedSection() const {
454 return OwningObject->getRelocatedSection(SectionPimpl);
455}
456
457inline DataRefImpl SectionRef::getRawDataRefImpl() const {
458 return SectionPimpl;
459}
460
461inline const ObjectFile *SectionRef::getObject() const {
462 return OwningObject;
463}
464
465/// RelocationRef
466inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
467 const ObjectFile *Owner)
468 : RelocationPimpl(RelocationP)
469 , OwningObject(Owner) {}
470
471inline bool RelocationRef::operator==(const RelocationRef &Other) const {
472 return RelocationPimpl == Other.RelocationPimpl;
473}
474
475inline void RelocationRef::moveNext() {
476 return OwningObject->moveRelocationNext(RelocationPimpl);
477}
478
479inline uint64_t RelocationRef::getOffset() const {
480 return OwningObject->getRelocationOffset(RelocationPimpl);
481}
482
483inline symbol_iterator RelocationRef::getSymbol() const {
484 return OwningObject->getRelocationSymbol(RelocationPimpl);
485}
486
487inline uint64_t RelocationRef::getType() const {
488 return OwningObject->getRelocationType(RelocationPimpl);
489}
490
491inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
492 return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
493}
494
495inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
496 return RelocationPimpl;
497}
498
499inline const ObjectFile *RelocationRef::getObject() const {
500 return OwningObject;
501}
502
503} // end namespace object
504
505} // end namespace llvm
506
507#endif // LLVM_OBJECT_OBJECTFILE_H

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Object/SymbolicFile.h

1//===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the SymbolicFile interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_SYMBOLICFILE_H
15#define LLVM_OBJECT_SYMBOLICFILE_H
16
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/iterator_range.h"
19#include "llvm/BinaryFormat/Magic.h"
20#include "llvm/Object/Binary.h"
21#include "llvm/Support/Error.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/Format.h"
24#include "llvm/Support/MemoryBuffer.h"
25#include <cinttypes>
26#include <cstdint>
27#include <cstring>
28#include <iterator>
29#include <memory>
30#include <system_error>
31
32namespace llvm {
33namespace object {
34
35union DataRefImpl {
36 // This entire union should probably be a
37 // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
38 struct {
39 uint32_t a, b;
40 } d;
41 uintptr_t p;
42
43 DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
44};
45
46template <typename OStream>
47OStream& operator<<(OStream &OS, const DataRefImpl &D) {
48 OS << "(" << format("0x%08" PRIxPTR"l" "x", D.p) << " (" << format("0x%08x", D.d.a)
49 << ", " << format("0x%08x", D.d.b) << "))";
50 return OS;
51}
52
53inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
54 // Check bitwise identical. This is the only legal way to compare a union w/o
55 // knowing which member is in use.
56 return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
57}
58
59inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
60 return !operator==(a, b);
61}
62
63inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
64 // Check bitwise identical. This is the only legal way to compare a union w/o
65 // knowing which member is in use.
66 return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
67}
68
69template <class content_type>
70class content_iterator
71 : public std::iterator<std::forward_iterator_tag, content_type> {
72 content_type Current;
73
74public:
75 content_iterator(content_type symb) : Current(std::move(symb)) {}
76
77 const content_type *operator->() const { return &Current; }
78
79 const content_type &operator*() const { return Current; }
80
81 bool operator==(const content_iterator &other) const {
82 return Current == other.Current;
83 }
84
85 bool operator!=(const content_iterator &other) const {
86 return !(*this == other);
87 }
88
89 content_iterator &operator++() { // preincrement
90 Current.moveNext();
91 return *this;
92 }
93};
94
95class SymbolicFile;
96
97/// This is a value type class that represents a single symbol in the list of
98/// symbols in the object file.
99class BasicSymbolRef {
100 DataRefImpl SymbolPimpl;
101 const SymbolicFile *OwningObject = nullptr;
102
103public:
104 enum Flags : unsigned {
105 SF_None = 0,
106 SF_Undefined = 1U << 0, // Symbol is defined in another object file
107 SF_Global = 1U << 1, // Global symbol
108 SF_Weak = 1U << 2, // Weak symbol
109 SF_Absolute = 1U << 3, // Absolute symbol
110 SF_Common = 1U << 4, // Symbol has common linkage
111 SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
112 SF_Exported = 1U << 6, // Symbol is visible to other DSOs
113 SF_FormatSpecific = 1U << 7, // Specific to the object file format
114 // (e.g. section symbols)
115 SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
116 SF_Hidden = 1U << 9, // Symbol has hidden visibility
117 SF_Const = 1U << 10, // Symbol value is constant
118 SF_Executable = 1U << 11, // Symbol points to an executable section
119 // (IR only)
120 };
121
122 BasicSymbolRef() = default;
22
Calling default constructor for 'DataRefImpl'
23
Returning from default constructor for 'DataRefImpl'
123 BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
124
125 bool operator==(const BasicSymbolRef &Other) const;
126 bool operator<(const BasicSymbolRef &Other) const;
127
128 void moveNext();
129
130 std::error_code printName(raw_ostream &OS) const;
131
132 /// Get symbol flags (bitwise OR of SymbolRef::Flags)
133 uint32_t getFlags() const;
134
135 DataRefImpl getRawDataRefImpl() const;
136 const SymbolicFile *getObject() const;
137};
138
139using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
140
141class SymbolicFile : public Binary {
142public:
143 SymbolicFile(unsigned int Type, MemoryBufferRef Source);
144 ~SymbolicFile() override;
145
146 // virtual interface.
147 virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
148
149 virtual std::error_code printSymbolName(raw_ostream &OS,
150 DataRefImpl Symb) const = 0;
151
152 virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
153
154 virtual basic_symbol_iterator symbol_begin() const = 0;
155
156 virtual basic_symbol_iterator symbol_end() const = 0;
157
158 // convenience wrappers.
159 using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
160 basic_symbol_iterator_range symbols() const {
161 return basic_symbol_iterator_range(symbol_begin(), symbol_end());
162 }
163
164 // construction aux.
165 static Expected<std::unique_ptr<SymbolicFile>>
166 createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
167 LLVMContext *Context);
168
169 static Expected<std::unique_ptr<SymbolicFile>>
170 createSymbolicFile(MemoryBufferRef Object) {
171 return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
172 }
173 static Expected<OwningBinary<SymbolicFile>>
174 createSymbolicFile(StringRef ObjectPath);
175
176 static bool classof(const Binary *v) {
177 return v->isSymbolic();
178 }
179};
180
181inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
182 const SymbolicFile *Owner)
183 : SymbolPimpl(SymbolP), OwningObject(Owner) {}
184
185inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
186 return SymbolPimpl == Other.SymbolPimpl;
187}
188
189inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
190 return SymbolPimpl < Other.SymbolPimpl;
191}
192
193inline void BasicSymbolRef::moveNext() {
194 return OwningObject->moveSymbolNext(SymbolPimpl);
195}
196
197inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
198 return OwningObject->printSymbolName(OS, SymbolPimpl);
199}
200
201inline uint32_t BasicSymbolRef::getFlags() const {
202 return OwningObject->getSymbolFlags(SymbolPimpl);
203}
204
205inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
206 return SymbolPimpl;
207}
208
209inline const SymbolicFile *BasicSymbolRef::getObject() const {
210 return OwningObject;
211}
212
213} // end namespace object
214} // end namespace llvm
215
216#endif // LLVM_OBJECT_SYMBOLICFILE_H

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/system_error

1// <system_error> -*- C++ -*-
2
3// Copyright (C) 2007-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/system_error
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_SYSTEM_ERROR1
30#define _GLIBCXX_SYSTEM_ERROR1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201103L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <bits/c++config.h>
39#include <bits/error_constants.h>
40#include <iosfwd>
41#include <stdexcept>
42
43namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47 class error_code;
48 class error_condition;
49 class system_error;
50
51 /// is_error_code_enum
52 template<typename _Tp>
53 struct is_error_code_enum : public false_type { };
54
55 /// is_error_condition_enum
56 template<typename _Tp>
57 struct is_error_condition_enum : public false_type { };
58
59 template<>
60 struct is_error_condition_enum<errc>
61 : public true_type { };
62
63#if __cplusplus201103L > 201402L
64 template <typename _Tp>
65 inline constexpr bool is_error_code_enum_v =
66 is_error_code_enum<_Tp>::value;
67 template <typename _Tp>
68 inline constexpr bool is_error_condition_enum_v =
69 is_error_condition_enum<_Tp>::value;
70#endif // C++17
71 inline namespace _V2 {
72
73 /// error_category
74 class error_category
75 {
76 public:
77 constexpr error_category() noexcept = default;
78
79 virtual ~error_category();
80
81 error_category(const error_category&) = delete;
82 error_category& operator=(const error_category&) = delete;
83
84 virtual const char*
85 name() const noexcept = 0;
86
87 // We need two different virtual functions here, one returning a
88 // COW string and one returning an SSO string. Their positions in the
89 // vtable must be consistent for dynamic dispatch to work, but which one
90 // the name "message()" finds depends on which ABI the caller is using.
91#if _GLIBCXX_USE_CXX11_ABI1
92 private:
93 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
94 virtual __cow_string
95 _M_message(int) const;
96
97 public:
98 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
99 virtual string
100 message(int) const = 0;
101#else
102 virtual string
103 message(int) const = 0;
104
105 private:
106 virtual __sso_string
107 _M_message(int) const;
108#endif
109
110 public:
111 virtual error_condition
112 default_error_condition(int __i) const noexcept;
113
114 virtual bool
115 equivalent(int __i, const error_condition& __cond) const noexcept;
116
117 virtual bool
118 equivalent(const error_code& __code, int __i) const noexcept;
119
120 bool
121 operator<(const error_category& __other) const noexcept
122 { return less<const error_category*>()(this, &__other); }
123
124 bool
125 operator==(const error_category& __other) const noexcept
126 { return this == &__other; }
127
128 bool
129 operator!=(const error_category& __other) const noexcept
130 { return this != &__other; }
131 };
132
133 // DR 890.
134 _GLIBCXX_CONST__attribute__ ((__const__)) const error_category& system_category() noexcept;
135 _GLIBCXX_CONST__attribute__ ((__const__)) const error_category& generic_category() noexcept;
136
137 } // end inline namespace
138
139 error_code make_error_code(errc) noexcept;
140
141 template<typename _Tp>
142 struct hash;
143
144 /// error_code
145 // Implementation-specific error identification
146 struct error_code
147 {
148 error_code() noexcept
149 : _M_value(0), _M_cat(&system_category()) { }
150
151 error_code(int __v, const error_category& __cat) noexcept
152 : _M_value(__v), _M_cat(&__cat) { }
153
154 template<typename _ErrorCodeEnum, typename = typename
155 enable_if<is_error_code_enum<_ErrorCodeEnum>::value>::type>
156 error_code(_ErrorCodeEnum __e) noexcept
157 { *this = make_error_code(__e); }
158
159 void
160 assign(int __v, const error_category& __cat) noexcept
161 {
162 _M_value = __v;
163 _M_cat = &__cat;
164 }
165
166 void
167 clear() noexcept
168 { assign(0, system_category()); }
169
170 // DR 804.
171 template<typename _ErrorCodeEnum>
172 typename enable_if<is_error_code_enum<_ErrorCodeEnum>::value,
173 error_code&>::type
174 operator=(_ErrorCodeEnum __e) noexcept
175 { return *this = make_error_code(__e); }
176
177 int
178 value() const noexcept { return _M_value; }
179
180 const error_category&
181 category() const noexcept { return *_M_cat; }
182
183 error_condition
184 default_error_condition() const noexcept;
185
186 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
187 string
188 message() const
189 { return category().message(value()); }
190
191 explicit operator bool() const noexcept
192 { return _M_value != 0; }
27
Assuming the condition is false
193
194 // DR 804.
195 private:
196 friend class hash<error_code>;
197
198 int _M_value;
199 const error_category* _M_cat;
200 };
201
202 // 19.4.2.6 non-member functions
203 inline error_code
204 make_error_code(errc __e) noexcept
205 { return error_code(static_cast<int>(__e), generic_category()); }
206
207 inline bool
208 operator<(const error_code& __lhs, const error_code& __rhs) noexcept
209 {
210 return (__lhs.category() < __rhs.category()
211 || (__lhs.category() == __rhs.category()
212 && __lhs.value() < __rhs.value()));
213 }
214
215 template<typename _CharT, typename _Traits>
216 basic_ostream<_CharT, _Traits>&
217 operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)
218 { return (__os << __e.category().name() << ':' << __e.value()); }
219
220 error_condition make_error_condition(errc) noexcept;
221
222 /// error_condition
223 // Portable error identification
224 struct error_condition
225 {
226 error_condition() noexcept
227 : _M_value(0), _M_cat(&generic_category()) { }
228
229 error_condition(int __v, const error_category& __cat) noexcept
230 : _M_value(__v), _M_cat(&__cat) { }
231
232 template<typename _ErrorConditionEnum, typename = typename
233 enable_if<is_error_condition_enum<_ErrorConditionEnum>::value>::type>
234 error_condition(_ErrorConditionEnum __e) noexcept
235 { *this = make_error_condition(__e); }
236
237 void
238 assign(int __v, const error_category& __cat) noexcept
239 {
240 _M_value = __v;
241 _M_cat = &__cat;
242 }
243
244 // DR 804.
245 template<typename _ErrorConditionEnum>
246 typename enable_if<is_error_condition_enum
247 <_ErrorConditionEnum>::value, error_condition&>::type
248 operator=(_ErrorConditionEnum __e) noexcept
249 { return *this = make_error_condition(__e); }
250
251 void
252 clear() noexcept
253 { assign(0, generic_category()); }
254
255 // 19.4.3.4 observers
256 int
257 value() const noexcept { return _M_value; }
258
259 const error_category&
260 category() const noexcept { return *_M_cat; }
261
262 _GLIBCXX_DEFAULT_ABI_TAG__attribute ((__abi_tag__ ("cxx11")))
263 string
264 message() const
265 { return category().message(value()); }
266
267 explicit operator bool() const noexcept
268 { return _M_value != 0; }
269
270 // DR 804.
271 private:
272 int _M_value;
273 const error_category* _M_cat;
274 };
275
276 // 19.4.3.6 non-member functions
277 inline error_condition
278 make_error_condition(errc __e) noexcept
279 { return error_condition(static_cast<int>(__e), generic_category()); }
280
281 inline bool
282 operator<(const error_condition& __lhs,
283 const error_condition& __rhs) noexcept
284 {
285 return (__lhs.category() < __rhs.category()
286 || (__lhs.category() == __rhs.category()
287 && __lhs.value() < __rhs.value()));
288 }
289
290 // 19.4.4 Comparison operators
291 inline bool
292 operator==(const error_code& __lhs, const error_code& __rhs) noexcept
293 { return (__lhs.category() == __rhs.category()
294 && __lhs.value() == __rhs.value()); }
295
296 inline bool
297 operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
298 {
299 return (__lhs.category().equivalent(__lhs.value(), __rhs)
300 || __rhs.category().equivalent(__lhs, __rhs.value()));
301 }
302
303 inline bool
304 operator==(const error_condition& __lhs, const error_code& __rhs) noexcept
305 {
306 return (__rhs.category().equivalent(__rhs.value(), __lhs)
307 || __lhs.category().equivalent(__rhs, __lhs.value()));
308 }
309
310 inline bool
311 operator==(const error_condition& __lhs,
312 const error_condition& __rhs) noexcept
313 {
314 return (__lhs.category() == __rhs.category()
315 && __lhs.value() == __rhs.value());
316 }
317
318 inline bool
319 operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
320 { return !(__lhs == __rhs); }
321
322 inline bool
323 operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
324 { return !(__lhs == __rhs); }
325
326 inline bool
327 operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
328 { return !(__lhs == __rhs); }
329
330 inline bool
331 operator!=(const error_condition& __lhs,
332 const error_condition& __rhs) noexcept
333 { return !(__lhs == __rhs); }
334
335
336 /**
337 * @brief Thrown to indicate error code of underlying system.
338 *
339 * @ingroup exceptions
340 */
341 class system_error : public std::runtime_error
342 {
343 private:
344 error_code _M_code;
345
346 public:
347 system_error(error_code __ec = error_code())
348 : runtime_error(__ec.message()), _M_code(__ec) { }
349
350 system_error(error_code __ec, const string& __what)
351 : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { }
352
353 system_error(error_code __ec, const char* __what)
354 : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { }
355
356 system_error(int __v, const error_category& __ecat, const char* __what)
357 : system_error(error_code(__v, __ecat), __what) { }
358
359 system_error(int __v, const error_category& __ecat)
360 : runtime_error(error_code(__v, __ecat).message()),
361 _M_code(__v, __ecat) { }
362
363 system_error(int __v, const error_category& __ecat, const string& __what)
364 : runtime_error(__what + ": " + error_code(__v, __ecat).message()),
365 _M_code(__v, __ecat) { }
366
367 virtual ~system_error() noexcept;
368
369 const error_code&
370 code() const noexcept { return _M_code; }
371 };
372
373_GLIBCXX_END_NAMESPACE_VERSION
374} // namespace
375
376#include <bits/functional_hash.h>
377
378namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
379{
380_GLIBCXX_BEGIN_NAMESPACE_VERSION
381
382#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
383 // DR 1182.
384 /// std::hash specialization for error_code.
385 template<>
386 struct hash<error_code>
387 : public __hash_base<size_t, error_code>
388 {
389 size_t
390 operator()(const error_code& __e) const noexcept
391 {
392 const size_t __tmp = std::_Hash_impl::hash(__e._M_value);
393 return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp);
394 }
395 };
396#endif // _GLIBCXX_COMPATIBILITY_CXX0X
397
398#if __cplusplus201103L > 201402L
399 // DR 2686.
400 /// std::hash specialization for error_condition.
401 template<>
402 struct hash<error_condition>
403 : public __hash_base<size_t, error_condition>
404 {
405 size_t
406 operator()(const error_condition& __e) const noexcept
407 {
408 const size_t __tmp = std::_Hash_impl::hash(__e.value());
409 return std::_Hash_impl::__hash_combine(__e.category(), __tmp);
410 }
411 };
412#endif
413
414_GLIBCXX_END_NAMESPACE_VERSION
415} // namespace
416
417#endif // C++11
418
419#endif // _GLIBCXX_SYSTEM_ERROR

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h

1//===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
11// and dyn_cast_or_null<X>() templates.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_CASTING_H
16#define LLVM_SUPPORT_CASTING_H
17
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/type_traits.h"
20#include <cassert>
21#include <memory>
22#include <type_traits>
23
24namespace llvm {
25
26//===----------------------------------------------------------------------===//
27// isa<x> Support Templates
28//===----------------------------------------------------------------------===//
29
30// Define a template that can be specialized by smart pointers to reflect the
31// fact that they are automatically dereferenced, and are not involved with the
32// template selection process... the default implementation is a noop.
33//
34template<typename From> struct simplify_type {
35 using SimpleType = From; // The real type this represents...
36
37 // An accessor to get the real value...
38 static SimpleType &getSimplifiedValue(From &Val) { return Val; }
39};
40
41template<typename From> struct simplify_type<const From> {
42 using NonConstSimpleType = typename simplify_type<From>::SimpleType;
43 using SimpleType =
44 typename add_const_past_pointer<NonConstSimpleType>::type;
45 using RetType =
46 typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
47
48 static RetType getSimplifiedValue(const From& Val) {
49 return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
38
Calling 'simplify_type::getSimplifiedValue'
39
Returning from 'simplify_type::getSimplifiedValue'
50 }
51};
52
53// The core of the implementation of isa<X> is here; To and From should be
54// the names of classes. This template can be specialized to customize the
55// implementation of isa<> without rewriting it from scratch.
56template <typename To, typename From, typename Enabler = void>
57struct isa_impl {
58 static inline bool doit(const From &Val) {
59 return To::classof(&Val);
45
Calling 'ObjectFile::classof'
46
Returning from 'ObjectFile::classof'
60 }
61};
62
63/// \brief Always allow upcasts, and perform no dynamic check for them.
64template <typename To, typename From>
65struct isa_impl<
66 To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
67 static inline bool doit(const From &) { return true; }
68};
69
70template <typename To, typename From> struct isa_impl_cl {
71 static inline bool doit(const From &Val) {
72 return isa_impl<To, From>::doit(Val);
73 }
74};
75
76template <typename To, typename From> struct isa_impl_cl<To, const From> {
77 static inline bool doit(const From &Val) {
78 return isa_impl<To, From>::doit(Val);
79 }
80};
81
82template <typename To, typename From>
83struct isa_impl_cl<To, const std::unique_ptr<From>> {
84 static inline bool doit(const std::unique_ptr<From> &Val) {
85 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 85, __extension__ __PRETTY_FUNCTION__))
;
86 return isa_impl_cl<To, From>::doit(*Val);
87 }
88};
89
90template <typename To, typename From> struct isa_impl_cl<To, From*> {
91 static inline bool doit(const From *Val) {
92 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 92, __extension__ __PRETTY_FUNCTION__))
;
93 return isa_impl<To, From>::doit(*Val);
94 }
95};
96
97template <typename To, typename From> struct isa_impl_cl<To, From*const> {
98 static inline bool doit(const From *Val) {
99 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 99, __extension__ __PRETTY_FUNCTION__))
;
100 return isa_impl<To, From>::doit(*Val);
101 }
102};
103
104template <typename To, typename From> struct isa_impl_cl<To, const From*> {
105 static inline bool doit(const From *Val) {
106 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 106, __extension__ __PRETTY_FUNCTION__))
;
43
Within the expansion of the macro 'assert':
a
Assuming 'Val' is non-null
107 return isa_impl<To, From>::doit(*Val);
44
Calling 'isa_impl::doit'
47
Returning from 'isa_impl::doit'
108 }
109};
110
111template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
112 static inline bool doit(const From *Val) {
113 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 113, __extension__ __PRETTY_FUNCTION__))
;
114 return isa_impl<To, From>::doit(*Val);
115 }
116};
117
118template<typename To, typename From, typename SimpleFrom>
119struct isa_impl_wrap {
120 // When From != SimplifiedType, we can simplify the type some more by using
121 // the simplify_type template.
122 static bool doit(const From &Val) {
123 return isa_impl_wrap<To, SimpleFrom,
41
Calling 'isa_impl_wrap::doit'
49
Returning from 'isa_impl_wrap::doit'
124 typename simplify_type<SimpleFrom>::SimpleType>::doit(
125 simplify_type<const From>::getSimplifiedValue(Val));
37
Calling 'simplify_type::getSimplifiedValue'
40
Returning from 'simplify_type::getSimplifiedValue'
126 }
127};
128
129template<typename To, typename FromTy>
130struct isa_impl_wrap<To, FromTy, FromTy> {
131 // When From == SimpleType, we are as simple as we are going to get.
132 static bool doit(const FromTy &Val) {
133 return isa_impl_cl<To,FromTy>::doit(Val);
42
Calling 'isa_impl_cl::doit'
48
Returning from 'isa_impl_cl::doit'
134 }
135};
136
137// isa<X> - Return true if the parameter to the template is an instance of the
138// template type argument. Used like this:
139//
140// if (isa<Type>(myVal)) { ... }
141//
142template <class X, class Y> LLVM_NODISCARD[[clang::warn_unused_result]] inline bool isa(const Y &Val) {
143 return isa_impl_wrap<X, const Y,
36
Calling 'isa_impl_wrap::doit'
50
Returning from 'isa_impl_wrap::doit'
144 typename simplify_type<const Y>::SimpleType>::doit(Val);
145}
146
147//===----------------------------------------------------------------------===//
148// cast<x> Support Templates
149//===----------------------------------------------------------------------===//
150
151template<class To, class From> struct cast_retty;
152
153// Calculate what type the 'cast' function should return, based on a requested
154// type of To and a source type of From.
155template<class To, class From> struct cast_retty_impl {
156 using ret_type = To &; // Normal case, return Ty&
157};
158template<class To, class From> struct cast_retty_impl<To, const From> {
159 using ret_type = const To &; // Normal case, return Ty&
160};
161
162template<class To, class From> struct cast_retty_impl<To, From*> {
163 using ret_type = To *; // Pointer arg case, return Ty*
164};
165
166template<class To, class From> struct cast_retty_impl<To, const From*> {
167 using ret_type = const To *; // Constant pointer arg case, return const Ty*
168};
169
170template<class To, class From> struct cast_retty_impl<To, const From*const> {
171 using ret_type = const To *; // Constant pointer arg case, return const Ty*
172};
173
174template <class To, class From>
175struct cast_retty_impl<To, std::unique_ptr<From>> {
176private:
177 using PointerType = typename cast_retty_impl<To, From *>::ret_type;
178 using ResultType = typename std::remove_pointer<PointerType>::type;
179
180public:
181 using ret_type = std::unique_ptr<ResultType>;
182};
183
184template<class To, class From, class SimpleFrom>
185struct cast_retty_wrap {
186 // When the simplified type and the from type are not the same, use the type
187 // simplifier to reduce the type, then reuse cast_retty_impl to get the
188 // resultant type.
189 using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
190};
191
192template<class To, class FromTy>
193struct cast_retty_wrap<To, FromTy, FromTy> {
194 // When the simplified type is equal to the from type, use it directly.
195 using ret_type = typename cast_retty_impl<To,FromTy>::ret_type;
196};
197
198template<class To, class From>
199struct cast_retty {
200 using ret_type = typename cast_retty_wrap<
201 To, From, typename simplify_type<From>::SimpleType>::ret_type;
202};
203
204// Ensure the non-simple values are converted using the simplify_type template
205// that may be specialized by smart pointers...
206//
207template<class To, class From, class SimpleFrom> struct cast_convert_val {
208 // This is not a simple type, use the template to simplify it...
209 static typename cast_retty<To, From>::ret_type doit(From &Val) {
210 return cast_convert_val<To, SimpleFrom,
211 typename simplify_type<SimpleFrom>::SimpleType>::doit(
212 simplify_type<From>::getSimplifiedValue(Val));
213 }
214};
215
216template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
217 // This _is_ a simple type, just cast it.
218 static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
219 typename cast_retty<To, FromTy>::ret_type Res2
220 = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
221 return Res2;
222 }
223};
224
225template <class X> struct is_simple_type {
226 static const bool value =
227 std::is_same<X, typename simplify_type<X>::SimpleType>::value;
228};
229
230// cast<X> - Return the argument parameter cast to the specified type. This
231// casting operator asserts that the type is correct, so it does not return null
232// on failure. It does not allow a null argument (use cast_or_null for that).
233// It is typically used like this:
234//
235// cast<Instruction>(myVal)->getParent()
236//
237template <class X, class Y>
238inline typename std::enable_if<!is_simple_type<Y>::value,
239 typename cast_retty<X, const Y>::ret_type>::type
240cast(const Y &Val) {
241 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 241, __extension__ __PRETTY_FUNCTION__))
;
242 return cast_convert_val<
243 X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
244}
245
246template <class X, class Y>
247inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
248 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 248, __extension__ __PRETTY_FUNCTION__))
;
249 return cast_convert_val<X, Y,
250 typename simplify_type<Y>::SimpleType>::doit(Val);
251}
252
253template <class X, class Y>
254inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
255 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 255, __extension__ __PRETTY_FUNCTION__))
;
35
Within the expansion of the macro 'assert':
a
Calling 'isa'
b
Returning from 'isa'
c
Assuming the condition is true
256 return cast_convert_val<X, Y*,
51
Calling 'cast_convert_val::doit'
52
Returning from 'cast_convert_val::doit'
257 typename simplify_type<Y*>::SimpleType>::doit(Val);
258}
259
260template <class X, class Y>
261inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
262cast(std::unique_ptr<Y> &&Val) {
263 assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val.get()) &&
"cast<Ty>() argument of incompatible type!") ? void (0
) : __assert_fail ("isa<X>(Val.get()) && \"cast<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 263, __extension__ __PRETTY_FUNCTION__))
;
264 using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type;
265 return ret_type(
266 cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit(
267 Val.release()));
268}
269
270// cast_or_null<X> - Functionally identical to cast, except that a null value is
271// accepted.
272//
273template <class X, class Y>
274LLVM_NODISCARD[[clang::warn_unused_result]] inline
275 typename std::enable_if<!is_simple_type<Y>::value,
276 typename cast_retty<X, const Y>::ret_type>::type
277 cast_or_null(const Y &Val) {
278 if (!Val)
279 return nullptr;
280 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 280, __extension__ __PRETTY_FUNCTION__))
;
281 return cast<X>(Val);
282}
283
284template <class X, class Y>
285LLVM_NODISCARD[[clang::warn_unused_result]] inline
286 typename std::enable_if<!is_simple_type<Y>::value,
287 typename cast_retty<X, Y>::ret_type>::type
288 cast_or_null(Y &Val) {
289 if (!Val)
290 return nullptr;
291 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 291, __extension__ __PRETTY_FUNCTION__))
;
292 return cast<X>(Val);
293}
294
295template <class X, class Y>
296LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type
297cast_or_null(Y *Val) {
298 if (!Val) return nullptr;
299 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_or_null<Ty>() argument of incompatible type!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Casting.h"
, 299, __extension__ __PRETTY_FUNCTION__))
;
300 return cast<X>(Val);
301}
302
303template <class X, class Y>
304inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
305cast_or_null(std::unique_ptr<Y> &&Val) {
306 if (!Val)
307 return nullptr;
308 return cast<X>(std::move(Val));
309}
310
311// dyn_cast<X> - Return the argument parameter cast to the specified type. This
312// casting operator returns null if the argument is of the wrong type, so it can
313// be used to test for a type as well as cast if successful. This should be
314// used in the context of an if statement like this:
315//
316// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
317//
318
319template <class X, class Y>
320LLVM_NODISCARD[[clang::warn_unused_result]] inline
321 typename std::enable_if<!is_simple_type<Y>::value,
322 typename cast_retty<X, const Y>::ret_type>::type
323 dyn_cast(const Y &Val) {
324 return isa<X>(Val) ? cast<X>(Val) : nullptr;
325}
326
327template <class X, class Y>
328LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
329 return isa<X>(Val) ? cast<X>(Val) : nullptr;
330}
331
332template <class X, class Y>
333LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
334 return isa<X>(Val) ? cast<X>(Val) : nullptr;
335}
336
337// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
338// value is accepted.
339//
340template <class X, class Y>
341LLVM_NODISCARD[[clang::warn_unused_result]] inline
342 typename std::enable_if<!is_simple_type<Y>::value,
343 typename cast_retty<X, const Y>::ret_type>::type
344 dyn_cast_or_null(const Y &Val) {
345 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
346}
347
348template <class X, class Y>
349LLVM_NODISCARD[[clang::warn_unused_result]] inline
350 typename std::enable_if<!is_simple_type<Y>::value,
351 typename cast_retty<X, Y>::ret_type>::type
352 dyn_cast_or_null(Y &Val) {
353 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
354}
355
356template <class X, class Y>
357LLVM_NODISCARD[[clang::warn_unused_result]] inline typename cast_retty<X, Y *>::ret_type
358dyn_cast_or_null(Y *Val) {
359 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
360}
361
362// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
363// taking ownership of the input pointer iff isa<X>(Val) is true. If the
364// cast is successful, From refers to nullptr on exit and the casted value
365// is returned. If the cast is unsuccessful, the function returns nullptr
366// and From is unchanged.
367template <class X, class Y>
368LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
369 -> decltype(cast<X>(Val)) {
370 if (!isa<X>(Val))
371 return nullptr;
372 return cast<X>(std::move(Val));
373}
374
375template <class X, class Y>
376LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
377 -> decltype(cast<X>(Val)) {
378 return unique_dyn_cast<X, Y>(Val);
379}
380
381// dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that
382// a null value is accepted.
383template <class X, class Y>
384LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val)
385 -> decltype(cast<X>(Val)) {
386 if (!Val)
387 return nullptr;
388 return unique_dyn_cast<X, Y>(Val);
389}
390
391template <class X, class Y>
392LLVM_NODISCARD[[clang::warn_unused_result]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val)
393 -> decltype(cast<X>(Val)) {
394 return unique_dyn_cast_or_null<X, Y>(Val);
395}
396
397} // end namespace llvm
398
399#endif // LLVM_SUPPORT_CASTING_H

/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h

1//===- llvm/Support/Error.h - Recoverable error handling --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an API used to report recoverable errors.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_ERROR_H
15#define LLVM_SUPPORT_ERROR_H
16
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/ADT/Twine.h"
21#include "llvm/Config/abi-breaking.h"
22#include "llvm/Support/AlignOf.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/ErrorOr.h"
27#include "llvm/Support/raw_ostream.h"
28#include <algorithm>
29#include <cassert>
30#include <cstdint>
31#include <cstdlib>
32#include <functional>
33#include <memory>
34#include <new>
35#include <string>
36#include <system_error>
37#include <type_traits>
38#include <utility>
39#include <vector>
40
41namespace llvm {
42
43class ErrorSuccess;
44
45/// Base class for error info classes. Do not extend this directly: Extend
46/// the ErrorInfo template subclass instead.
47class ErrorInfoBase {
48public:
49 virtual ~ErrorInfoBase() = default;
50
51 /// Print an error message to an output stream.
52 virtual void log(raw_ostream &OS) const = 0;
53
54 /// Return the error message as a string.
55 virtual std::string message() const {
56 std::string Msg;
57 raw_string_ostream OS(Msg);
58 log(OS);
59 return OS.str();
60 }
61
62 /// Convert this error to a std::error_code.
63 ///
64 /// This is a temporary crutch to enable interaction with code still
65 /// using std::error_code. It will be removed in the future.
66 virtual std::error_code convertToErrorCode() const = 0;
67
68 // Returns the class ID for this type.
69 static const void *classID() { return &ID; }
70
71 // Returns the class ID for the dynamic type of this ErrorInfoBase instance.
72 virtual const void *dynamicClassID() const = 0;
73
74 // Check whether this instance is a subclass of the class identified by
75 // ClassID.
76 virtual bool isA(const void *const ClassID) const {
77 return ClassID == classID();
78 }
79
80 // Check whether this instance is a subclass of ErrorInfoT.
81 template <typename ErrorInfoT> bool isA() const {
82 return isA(ErrorInfoT::classID());
83 }
84
85private:
86 virtual void anchor();
87
88 static char ID;
89};
90
91/// Lightweight error class with error context and mandatory checking.
92///
93/// Instances of this class wrap a ErrorInfoBase pointer. Failure states
94/// are represented by setting the pointer to a ErrorInfoBase subclass
95/// instance containing information describing the failure. Success is
96/// represented by a null pointer value.
97///
98/// Instances of Error also contains a 'Checked' flag, which must be set
99/// before the destructor is called, otherwise the destructor will trigger a
100/// runtime error. This enforces at runtime the requirement that all Error
101/// instances be checked or returned to the caller.
102///
103/// There are two ways to set the checked flag, depending on what state the
104/// Error instance is in. For Error instances indicating success, it
105/// is sufficient to invoke the boolean conversion operator. E.g.:
106///
107/// @code{.cpp}
108/// Error foo(<...>);
109///
110/// if (auto E = foo(<...>))
111/// return E; // <- Return E if it is in the error state.
112/// // We have verified that E was in the success state. It can now be safely
113/// // destroyed.
114/// @endcode
115///
116/// A success value *can not* be dropped. For example, just calling 'foo(<...>)'
117/// without testing the return value will raise a runtime error, even if foo
118/// returns success.
119///
120/// For Error instances representing failure, you must use either the
121/// handleErrors or handleAllErrors function with a typed handler. E.g.:
122///
123/// @code{.cpp}
124/// class MyErrorInfo : public ErrorInfo<MyErrorInfo> {
125/// // Custom error info.
126/// };
127///
128/// Error foo(<...>) { return make_error<MyErrorInfo>(...); }
129///
130/// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo.
131/// auto NewE =
132/// handleErrors(E,
133/// [](const MyErrorInfo &M) {
134/// // Deal with the error.
135/// },
136/// [](std::unique_ptr<OtherError> M) -> Error {
137/// if (canHandle(*M)) {
138/// // handle error.
139/// return Error::success();
140/// }
141/// // Couldn't handle this error instance. Pass it up the stack.
142/// return Error(std::move(M));
143/// );
144/// // Note - we must check or return NewE in case any of the handlers
145/// // returned a new error.
146/// @endcode
147///
148/// The handleAllErrors function is identical to handleErrors, except
149/// that it has a void return type, and requires all errors to be handled and
150/// no new errors be returned. It prevents errors (assuming they can all be
151/// handled) from having to be bubbled all the way to the top-level.
152///
153/// *All* Error instances must be checked before destruction, even if
154/// they're moved-assigned or constructed from Success values that have already
155/// been checked. This enforces checking through all levels of the call stack.
156class LLVM_NODISCARD[[clang::warn_unused_result]] Error {
157 // ErrorList needs to be able to yank ErrorInfoBase pointers out of this
158 // class to add to the error list.
159 friend class ErrorList;
160
161 // handleErrors needs to be able to set the Checked flag.
162 template <typename... HandlerTs>
163 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
164
165 // Expected<T> needs to be able to steal the payload when constructed from an
166 // error.
167 template <typename T> friend class Expected;
168
169protected:
170 /// Create a success value. Prefer using 'Error::success()' for readability
171 Error() {
172 setPtr(nullptr);
173 setChecked(false);
174 }
175
176public:
177 /// Create a success value.
178 static ErrorSuccess success();
179
180 // Errors are not copy-constructable.
181 Error(const Error &Other) = delete;
182
183 /// Move-construct an error value. The newly constructed error is considered
184 /// unchecked, even if the source error had been checked. The original error
185 /// becomes a checked Success value, regardless of its original state.
186 Error(Error &&Other) {
187 setChecked(true);
188 *this = std::move(Other);
189 }
190
191 /// Create an error value. Prefer using the 'make_error' function, but
192 /// this constructor can be useful when "re-throwing" errors from handlers.
193 Error(std::unique_ptr<ErrorInfoBase> Payload) {
194 setPtr(Payload.release());
195 setChecked(false);
196 }
197
198 // Errors are not copy-assignable.
199 Error &operator=(const Error &Other) = delete;
200
201 /// Move-assign an error value. The current error must represent success, you
202 /// you cannot overwrite an unhandled error. The current error is then
203 /// considered unchecked. The source error becomes a checked success value,
204 /// regardless of its original state.
205 Error &operator=(Error &&Other) {
206 // Don't allow overwriting of unchecked values.
207 assertIsChecked();
208 setPtr(Other.getPtr());
209
210 // This Error is unchecked, even if the source error was checked.
211 setChecked(false);
212
213 // Null out Other's payload and set its checked bit.
214 Other.setPtr(nullptr);
215 Other.setChecked(true);
216
217 return *this;
218 }
219
220 /// Destroy a Error. Fails with a call to abort() if the error is
221 /// unchecked.
222 ~Error() {
223 assertIsChecked();
224 delete getPtr();
225 }
226
227 /// Bool conversion. Returns true if this Error is in a failure state,
228 /// and false if it is in an accept state. If the error is in a Success state
229 /// it will be considered checked.
230 explicit operator bool() {
231 setChecked(getPtr() == nullptr);
232 return getPtr() != nullptr;
233 }
234
235 /// Check whether one error is a subclass of another.
236 template <typename ErrT> bool isA() const {
237 return getPtr() && getPtr()->isA(ErrT::classID());
238 }
239
240 /// Returns the dynamic class id of this error, or null if this is a success
241 /// value.
242 const void* dynamicClassID() const {
243 if (!getPtr())
244 return nullptr;
245 return getPtr()->dynamicClassID();
246 }
247
248private:
249#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
250 // assertIsChecked() happens very frequently, but under normal circumstances
251 // is supposed to be a no-op. So we want it to be inlined, but having a bunch
252 // of debug prints can cause the function to be too large for inlining. So
253 // it's important that we define this function out of line so that it can't be
254 // inlined.
255 LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
256 void fatalUncheckedError() const;
257#endif
258
259 void assertIsChecked() {
260#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
261 if (LLVM_UNLIKELY(!getChecked() || getPtr())__builtin_expect((bool)(!getChecked() || getPtr()), false))
262 fatalUncheckedError();
263#endif
264 }
265
266 ErrorInfoBase *getPtr() const {
267 return reinterpret_cast<ErrorInfoBase*>(
268 reinterpret_cast<uintptr_t>(Payload) &
269 ~static_cast<uintptr_t>(0x1));
270 }
271
272 void setPtr(ErrorInfoBase *EI) {
273#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
274 Payload = reinterpret_cast<ErrorInfoBase*>(
275 (reinterpret_cast<uintptr_t>(EI) &
276 ~static_cast<uintptr_t>(0x1)) |
277 (reinterpret_cast<uintptr_t>(Payload) & 0x1));
278#else
279 Payload = EI;
280#endif
281 }
282
283 bool getChecked() const {
284#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
285 return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0;
286#else
287 return true;
288#endif
289 }
290
291 void setChecked(bool V) {
292 Payload = reinterpret_cast<ErrorInfoBase*>(
293 (reinterpret_cast<uintptr_t>(Payload) &
294 ~static_cast<uintptr_t>(0x1)) |
295 (V ? 0 : 1));
296 }
297
298 std::unique_ptr<ErrorInfoBase> takePayload() {
299 std::unique_ptr<ErrorInfoBase> Tmp(getPtr());
300 setPtr(nullptr);
301 setChecked(true);
302 return Tmp;
303 }
304
305 ErrorInfoBase *Payload = nullptr;
306};
307
308/// Subclass of Error for the sole purpose of identifying the success path in
309/// the type system. This allows to catch invalid conversion to Expected<T> at
310/// compile time.
311class ErrorSuccess : public Error {};
312
313inline ErrorSuccess Error::success() { return ErrorSuccess(); }
314
315/// Make a Error instance representing failure using the given error info
316/// type.
317template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
318 return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
319}
320
321/// Base class for user error types. Users should declare their error types
322/// like:
323///
324/// class MyError : public ErrorInfo<MyError> {
325/// ....
326/// };
327///
328/// This class provides an implementation of the ErrorInfoBase::kind
329/// method, which is used by the Error RTTI system.
330template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
331class ErrorInfo : public ParentErrT {
332public:
333 static const void *classID() { return &ThisErrT::ID; }
334
335 const void *dynamicClassID() const override { return &ThisErrT::ID; }
336
337 bool isA(const void *const ClassID) const override {
338 return ClassID == classID() || ParentErrT::isA(ClassID);
339 }
340};
341
342/// Special ErrorInfo subclass representing a list of ErrorInfos.
343/// Instances of this class are constructed by joinError.
344class ErrorList final : public ErrorInfo<ErrorList> {
345 // handleErrors needs to be able to iterate the payload list of an
346 // ErrorList.
347 template <typename... HandlerTs>
348 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
349
350 // joinErrors is implemented in terms of join.
351 friend Error joinErrors(Error, Error);
352
353public:
354 void log(raw_ostream &OS) const override {
355 OS << "Multiple errors:\n";
356 for (auto &ErrPayload : Payloads) {
357 ErrPayload->log(OS);
358 OS << "\n";
359 }
360 }
361
362 std::error_code convertToErrorCode() const override;
363
364 // Used by ErrorInfo::classID.
365 static char ID;
366
367private:
368 ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
369 std::unique_ptr<ErrorInfoBase> Payload2) {
370 assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&(static_cast <bool> (!Payload1->isA<ErrorList>
() && !Payload2->isA<ErrorList>() &&
"ErrorList constructor payloads should be singleton errors")
? void (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 371, __extension__ __PRETTY_FUNCTION__))
371 "ErrorList constructor payloads should be singleton errors")(static_cast <bool> (!Payload1->isA<ErrorList>
() && !Payload2->isA<ErrorList>() &&
"ErrorList constructor payloads should be singleton errors")
? void (0) : __assert_fail ("!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && \"ErrorList constructor payloads should be singleton errors\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 371, __extension__ __PRETTY_FUNCTION__))
;
372 Payloads.push_back(std::move(Payload1));
373 Payloads.push_back(std::move(Payload2));
374 }
375
376 static Error join(Error E1, Error E2) {
377 if (!E1)
378 return E2;
379 if (!E2)
380 return E1;
381 if (E1.isA<ErrorList>()) {
382 auto &E1List = static_cast<ErrorList &>(*E1.getPtr());
383 if (E2.isA<ErrorList>()) {
384 auto E2Payload = E2.takePayload();
385 auto &E2List = static_cast<ErrorList &>(*E2Payload);
386 for (auto &Payload : E2List.Payloads)
387 E1List.Payloads.push_back(std::move(Payload));
388 } else
389 E1List.Payloads.push_back(E2.takePayload());
390
391 return E1;
392 }
393 if (E2.isA<ErrorList>()) {
394 auto &E2List = static_cast<ErrorList &>(*E2.getPtr());
395 E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
396 return E2;
397 }
398 return Error(std::unique_ptr<ErrorList>(
399 new ErrorList(E1.takePayload(), E2.takePayload())));
400 }
401
402 std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
403};
404
405/// Concatenate errors. The resulting Error is unchecked, and contains the
406/// ErrorInfo(s), if any, contained in E1, followed by the
407/// ErrorInfo(s), if any, contained in E2.
408inline Error joinErrors(Error E1, Error E2) {
409 return ErrorList::join(std::move(E1), std::move(E2));
410}
411
412/// Tagged union holding either a T or a Error.
413///
414/// This class parallels ErrorOr, but replaces error_code with Error. Since
415/// Error cannot be copied, this class replaces getError() with
416/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the
417/// error class type.
418template <class T> class LLVM_NODISCARD[[clang::warn_unused_result]] Expected {
419 template <class T1> friend class ExpectedAsOutParameter;
420 template <class OtherT> friend class Expected;
421
422 static const bool isRef = std::is_reference<T>::value;
423
424 using wrap = ReferenceStorage<typename std::remove_reference<T>::type>;
425
426 using error_type = std::unique_ptr<ErrorInfoBase>;
427
428public:
429 using storage_type = typename std::conditional<isRef, wrap, T>::type;
430 using value_type = T;
431
432private:
433 using reference = typename std::remove_reference<T>::type &;
434 using const_reference = const typename std::remove_reference<T>::type &;
435 using pointer = typename std::remove_reference<T>::type *;
436 using const_pointer = const typename std::remove_reference<T>::type *;
437
438public:
439 /// Create an Expected<T> error value from the given Error.
440 Expected(Error Err)
441 : HasError(true)
442#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
443 // Expected is unchecked upon construction in Debug builds.
444 , Unchecked(true)
445#endif
446 {
447 assert(Err && "Cannot create Expected<T> from Error success value.")(static_cast <bool> (Err && "Cannot create Expected<T> from Error success value."
) ? void (0) : __assert_fail ("Err && \"Cannot create Expected<T> from Error success value.\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 447, __extension__ __PRETTY_FUNCTION__))
;
448 new (getErrorStorage()) error_type(Err.takePayload());
449 }
450
451 /// Forbid to convert from Error::success() implicitly, this avoids having
452 /// Expected<T> foo() { return Error::success(); } which compiles otherwise
453 /// but triggers the assertion above.
454 Expected(ErrorSuccess) = delete;
455
456 /// Create an Expected<T> success value from the given OtherT value, which
457 /// must be convertible to T.
458 template <typename OtherT>
459 Expected(OtherT &&Val,
460 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
461 * = nullptr)
462 : HasError(false)
463#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
464 // Expected is unchecked upon construction in Debug builds.
465 , Unchecked(true)
466#endif
467 {
468 new (getStorage()) storage_type(std::forward<OtherT>(Val));
469 }
470
471 /// Move construct an Expected<T> value.
472 Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
59
Calling 'move'
60
Returning from 'move'
61
Calling 'Expected::moveConstruct'
142
Returning from 'Expected::moveConstruct'
473
474 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
475 /// must be convertible to T.
476 template <class OtherT>
477 Expected(Expected<OtherT> &&Other,
478 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
479 * = nullptr) {
480 moveConstruct(std::move(Other));
481 }
482
483 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
484 /// isn't convertible to T.
485 template <class OtherT>
486 explicit Expected(
487 Expected<OtherT> &&Other,
488 typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
489 nullptr) {
490 moveConstruct(std::move(Other));
491 }
492
493 /// Move-assign from another Expected<T>.
494 Expected &operator=(Expected &&Other) {
495 moveAssign(std::move(Other));
496 return *this;
497 }
498
499 /// Destroy an Expected<T>.
500 ~Expected() {
501 assertIsChecked();
156
Calling 'Expected::assertIsChecked'
159
Returning from 'Expected::assertIsChecked'
502 if (!HasError)
160
Assuming the condition is true
161
Taking true branch
503 getStorage()->~storage_type();
162
Calling 'Expected::getStorage'
164
Returning from 'Expected::getStorage'
504 else
505 getErrorStorage()->~error_type();
506 }
507
508 /// \brief Return false if there is an error.
509 explicit operator bool() {
510#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
511 Unchecked = HasError;
512#endif
513 return !HasError;
514 }
515
516 /// \brief Returns a reference to the stored T value.
517 reference get() {
518 assertIsChecked();
519 return *getStorage();
520 }
521
522 /// \brief Returns a const reference to the stored T value.
523 const_reference get() const {
524 assertIsChecked();
525 return const_cast<Expected<T> *>(this)->get();
526 }
527
528 /// \brief Check that this Expected<T> is an error of type ErrT.
529 template <typename ErrT> bool errorIsA() const {
530 return HasError && (*getErrorStorage())->template isA<ErrT>();
531 }
532
533 /// \brief Take ownership of the stored error.
534 /// After calling this the Expected<T> is in an indeterminate state that can
535 /// only be safely destructed. No further calls (beside the destructor) should
536 /// be made on the Expected<T> vaule.
537 Error takeError() {
538#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
539 Unchecked = false;
540#endif
541 return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
148
'?' condition is true
149
Calling 'Expected::getErrorStorage'
151
Returning from 'Expected::getErrorStorage'
152
Calling 'move'
153
Returning from 'move'
542 }
543
544 /// \brief Returns a pointer to the stored T value.
545 pointer operator->() {
546 assertIsChecked();
547 return toPointer(getStorage());
548 }
549
550 /// \brief Returns a const pointer to the stored T value.
551 const_pointer operator->() const {
552 assertIsChecked();
553 return toPointer(getStorage());
554 }
555
556 /// \brief Returns a reference to the stored T value.
557 reference operator*() {
558 assertIsChecked();
559 return *getStorage();
560 }
561
562 /// \brief Returns a const reference to the stored T value.
563 const_reference operator*() const {
564 assertIsChecked();
565 return *getStorage();
566 }
567
568private:
569 template <class T1>
570 static bool compareThisIfSameType(const T1 &a, const T1 &b) {
571 return &a == &b;
572 }
573
574 template <class T1, class T2>
575 static bool compareThisIfSameType(const T1 &a, const T2 &b) {
576 return false;
577 }
578
579 template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
580 HasError = Other.HasError;
581#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
582 Unchecked = true;
583 Other.Unchecked = false;
584#endif
585
586 if (!HasError)
62
Assuming the condition is false
63
Taking false branch
587 new (getStorage()) storage_type(std::move(*Other.getStorage()));
588 else
589 new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
64
Calling 'Expected::getErrorStorage'
66
Returning from 'Expected::getErrorStorage'
67
Calling 'operator new'
68
Returning from 'operator new'
69
Calling 'Expected::getErrorStorage'
71
Returning from 'Expected::getErrorStorage'
72
Calling 'move'
73
Returning from 'move'
74
Calling move constructor for 'unique_ptr'
141
Returning from move constructor for 'unique_ptr'
590 }
591
592 template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
593 assertIsChecked();
594
595 if (compareThisIfSameType(*this, Other))
596 return;
597
598 this->~Expected();
599 new (this) Expected(std::move(Other));
600 }
601
602 pointer toPointer(pointer Val) { return Val; }
603
604 const_pointer toPointer(const_pointer Val) const { return Val; }
605
606 pointer toPointer(wrap *Val) { return &Val->get(); }
607
608 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
609
610 storage_type *getStorage() {
611 assert(!HasError && "Cannot get value when an error exists!")(static_cast <bool> (!HasError && "Cannot get value when an error exists!"
) ? void (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 611, __extension__ __PRETTY_FUNCTION__))
;
163
Within the expansion of the macro 'assert':
612 return reinterpret_cast<storage_type *>(TStorage.buffer);
613 }
614
615 const storage_type *getStorage() const {
616 assert(!HasError && "Cannot get value when an error exists!")(static_cast <bool> (!HasError && "Cannot get value when an error exists!"
) ? void (0) : __assert_fail ("!HasError && \"Cannot get value when an error exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 616, __extension__ __PRETTY_FUNCTION__))
;
617 return reinterpret_cast<const storage_type *>(TStorage.buffer);
618 }
619
620 error_type *getErrorStorage() {
621 assert(HasError && "Cannot get error when a value exists!")(static_cast <bool> (HasError && "Cannot get error when a value exists!"
) ? void (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 621, __extension__ __PRETTY_FUNCTION__))
;
65
Within the expansion of the macro 'assert':
70
Within the expansion of the macro 'assert':
150
Within the expansion of the macro 'assert':
622 return reinterpret_cast<error_type *>(ErrorStorage.buffer);
623 }
624
625 const error_type *getErrorStorage() const {
626 assert(HasError && "Cannot get error when a value exists!")(static_cast <bool> (HasError && "Cannot get error when a value exists!"
) ? void (0) : __assert_fail ("HasError && \"Cannot get error when a value exists!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 626, __extension__ __PRETTY_FUNCTION__))
;
627 return reinterpret_cast<const error_type *>(ErrorStorage.buffer);
628 }
629
630 // Used by ExpectedAsOutParameter to reset the checked flag.
631 void setUnchecked() {
632#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
633 Unchecked = true;
634#endif
635 }
636
637#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
638 LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn))
639 LLVM_ATTRIBUTE_NOINLINE__attribute__((noinline))
640 void fatalUncheckedExpected() const {
641 dbgs() << "Expected<T> must be checked before access or destruction.\n";
642 if (HasError) {
643 dbgs() << "Unchecked Expected<T> contained error:\n";
644 (*getErrorStorage())->log(dbgs());
645 } else
646 dbgs() << "Expected<T> value was in success state. (Note: Expected<T> "
647 "values in success mode must still be checked prior to being "
648 "destroyed).\n";
649 abort();
650 }
651#endif
652
653 void assertIsChecked() {
654#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
655 if (LLVM_UNLIKELY(Unchecked)__builtin_expect((bool)(Unchecked), false))
157
Within the expansion of the macro 'LLVM_UNLIKELY':
a
Assuming the condition is false
158
Taking false branch
656 fatalUncheckedExpected();
657#endif
658 }
659
660 union {
661 AlignedCharArrayUnion<storage_type> TStorage;
662 AlignedCharArrayUnion<error_type> ErrorStorage;
663 };
664 bool HasError : 1;
665#if LLVM_ENABLE_ABI_BREAKING_CHECKS1
666 bool Unchecked : 1;
667#endif
668};
669
670/// Report a serious error, calling any installed error handler. See
671/// ErrorHandling.h.
672LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) void report_fatal_error(Error Err,
673 bool gen_crash_diag = true);
674
675/// Report a fatal error if Err is a failure value.
676///
677/// This function can be used to wrap calls to fallible functions ONLY when it
678/// is known that the Error will always be a success value. E.g.
679///
680/// @code{.cpp}
681/// // foo only attempts the fallible operation if DoFallibleOperation is
682/// // true. If DoFallibleOperation is false then foo always returns
683/// // Error::success().
684/// Error foo(bool DoFallibleOperation);
685///
686/// cantFail(foo(false));
687/// @endcode
688inline void cantFail(Error Err, const char *Msg = nullptr) {
689 if (Err) {
690 if (!Msg)
691 Msg = "Failure value returned from cantFail wrapped call";
692 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 692)
;
693 }
694}
695
696/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
697/// returns the contained value.
698///
699/// This function can be used to wrap calls to fallible functions ONLY when it
700/// is known that the Error will always be a success value. E.g.
701///
702/// @code{.cpp}
703/// // foo only attempts the fallible operation if DoFallibleOperation is
704/// // true. If DoFallibleOperation is false then foo always returns an int.
705/// Expected<int> foo(bool DoFallibleOperation);
706///
707/// int X = cantFail(foo(false));
708/// @endcode
709template <typename T>
710T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) {
711 if (ValOrErr)
712 return std::move(*ValOrErr);
713 else {
714 if (!Msg)
715 Msg = "Failure value returned from cantFail wrapped call";
716 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 716)
;
717 }
718}
719
720/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
721/// returns the contained reference.
722///
723/// This function can be used to wrap calls to fallible functions ONLY when it
724/// is known that the Error will always be a success value. E.g.
725///
726/// @code{.cpp}
727/// // foo only attempts the fallible operation if DoFallibleOperation is
728/// // true. If DoFallibleOperation is false then foo always returns a Bar&.
729/// Expected<Bar&> foo(bool DoFallibleOperation);
730///
731/// Bar &X = cantFail(foo(false));
732/// @endcode
733template <typename T>
734T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) {
735 if (ValOrErr)
736 return *ValOrErr;
737 else {
738 if (!Msg)
739 Msg = "Failure value returned from cantFail wrapped call";
740 llvm_unreachable(Msg)::llvm::llvm_unreachable_internal(Msg, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 740)
;
741 }
742}
743
744/// Helper for testing applicability of, and applying, handlers for
745/// ErrorInfo types.
746template <typename HandlerT>
747class ErrorHandlerTraits
748 : public ErrorHandlerTraits<decltype(
749 &std::remove_reference<HandlerT>::type::operator())> {};
750
751// Specialization functions of the form 'Error (const ErrT&)'.
752template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
753public:
754 static bool appliesTo(const ErrorInfoBase &E) {
755 return E.template isA<ErrT>();
756 }
757
758 template <typename HandlerT>
759 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
760 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 760, __extension__ __PRETTY_FUNCTION__))
;
761 return H(static_cast<ErrT &>(*E));
762 }
763};
764
765// Specialization functions of the form 'void (const ErrT&)'.
766template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
767public:
768 static bool appliesTo(const ErrorInfoBase &E) {
769 return E.template isA<ErrT>();
770 }
771
772 template <typename HandlerT>
773 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
774 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 774, __extension__ __PRETTY_FUNCTION__))
;
775 H(static_cast<ErrT &>(*E));
776 return Error::success();
777 }
778};
779
780/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
781template <typename ErrT>
782class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
783public:
784 static bool appliesTo(const ErrorInfoBase &E) {
785 return E.template isA<ErrT>();
786 }
787
788 template <typename HandlerT>
789 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
790 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 790, __extension__ __PRETTY_FUNCTION__))
;
791 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
792 return H(std::move(SubE));
793 }
794};
795
796/// Specialization for functions of the form 'void (std::unique_ptr<ErrT>)'.
797template <typename ErrT>
798class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
799public:
800 static bool appliesTo(const ErrorInfoBase &E) {
801 return E.template isA<ErrT>();
802 }
803
804 template <typename HandlerT>
805 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
806 assert(appliesTo(*E) && "Applying incorrect handler")(static_cast <bool> (appliesTo(*E) && "Applying incorrect handler"
) ? void (0) : __assert_fail ("appliesTo(*E) && \"Applying incorrect handler\""
, "/build/llvm-toolchain-snapshot-7~svn325874/include/llvm/Support/Error.h"
, 806, __extension__ __PRETTY_FUNCTION__))
;
807 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
808 H(std::move(SubE));
809 return Error::success();
810 }
811};
812
813// Specialization for member functions of the form 'RetT (const ErrT&)'.
814template <typename C, typename RetT, typename ErrT>
815class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
816 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
817
818// Specialization for member functions of the form 'RetT (const ErrT&) const'.
819template <typename C, typename RetT, typename ErrT>
820class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
821 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
822
823// Specialization for member functions of the form 'RetT (const ErrT&)'.
824template <typename C, typename RetT, typename ErrT>
825class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
826 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
827
828// Specialization for member functions of the form 'RetT (const ErrT&) const'.
829template <typename C, typename RetT, typename ErrT>
830class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
831 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
832
833/// Specialization for member functions of the form
834/// 'RetT (std::unique_ptr<ErrT>)'.
835template <typename C, typename RetT, typename ErrT>
836class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
837 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
838
839/// Specialization for member functions of the form
840/// 'RetT (std::unique_ptr<ErrT>) const'.
841template <typename C, typename RetT, typename ErrT>
842class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
843 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
844
845inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
846 return Error(std::move(Payload));
847}
848
849template <typename HandlerT, typename... HandlerTs>
850Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
851 HandlerT &&Handler, HandlerTs &&... Handlers) {
852 if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
853 return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
854 std::move(Payload));
855 return handleErrorImpl(std::move(Payload),
856 std::forward<HandlerTs>(Handlers)...);
857}
858
859/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
860/// unhandled errors (or Errors returned by handlers) are re-concatenated and
861/// returned.
862/// Because this function returns an error, its result must also be checked
863/// or returned. If you intend to handle all errors use handleAllErrors
864/// (which returns void, and will abort() on unhandled errors) instead.
865template <typename... HandlerTs>
866Error handleErrors(Error E, HandlerTs &&... Hs) {
867 if (!E)
868 return Error::success();
869
870 std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
871
872 if (Payload->isA<ErrorList>()) {
873 ErrorList &List = static_cast<ErrorList &>(*Payload);
874 Error R;
875 for (auto &P : List.Payloads)
876 R = ErrorList::join(
877 std::move(R),
878 handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
879 return R;
880 }
881
882 return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...);
883}
884
885/// Behaves the same as handleErrors, except that it requires that all
886/// errors be handled by the given handlers. If any unhandled error remains
887/// after the handlers have run, report_fatal_error() will be called.
888template <typename... HandlerTs>
889void handleAllErrors(Error E, HandlerTs &&... Handlers) {
890 cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...));
891}
892
893/// Check that E is a non-error, then drop it.
894/// If E is an error report_fatal_error will be called.
895inline void handleAllErrors(Error E) {
896 cantFail(std::move(E));
897}
898
899/// Handle any errors (if present) in an Expected<T>, then try a recovery path.
900///
901/// If the incoming value is a success value it is returned unmodified. If it
902/// is a failure value then it the contained error is passed to handleErrors.
903/// If handleErrors is able to handle the error then the RecoveryPath functor
904/// is called to supply the final result. If handleErrors is not able to
905/// handle all errors then the unhandled errors are returned.
906///
907/// This utility enables the follow pattern:
908///
909/// @code{.cpp}
910/// enum FooStrategy { Aggressive, Conservative };
911/// Expected<Foo> foo(FooStrategy S);
912///
913/// auto ResultOrErr =
914/// handleExpected(
915/// foo(Aggressive),
916/// []() { return foo(Conservative); },
917/// [](AggressiveStrategyError&) {
918/// // Implicitly conusme this - we'll recover by using a conservative
919/// // strategy.
920/// });
921///
922/// @endcode
923template <typename T, typename RecoveryFtor, typename... HandlerTs>
924Expected<T> handleExpected(Expected<T> ValOrErr, RecoveryFtor &&RecoveryPath,
925 HandlerTs &&... Handlers) {
926 if (ValOrErr)
927 return ValOrErr;
928
929 if (auto Err = handleErrors(ValOrErr.takeError(),
930 std::forward<HandlerTs>(Handlers)...))
931 return std::move(Err);
932
933 return RecoveryPath();
934}
935
936/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
937/// will be printed before the first one is logged. A newline will be printed
938/// after each error.
939///
940/// This is useful in the base level of your program to allow clean termination
941/// (allowing clean deallocation of resources, etc.), while reporting error
942/// information to the user.
943void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner);
944
945/// Write all error messages (if any) in E to a string. The newline character
946/// is used to separate error messages.
947inline std::string toString(Error E) {
948 SmallVector<std::string, 2> Errors;
949 handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) {
950 Errors.push_back(EI.message());
951 });
952 return join(Errors.begin(), Errors.end(), "\n");
953}
954
955/// Consume a Error without doing anything. This method should be used
956/// only where an error can be considered a reasonable and expected return
957/// value.
958///
959/// Uses of this method are potentially indicative of design problems: If it's
960/// legitimate to do nothing while processing an "error", the error-producer
961/// might be more clearly refactored to return an Optional<T>.
962inline void consumeError(Error Err) {
963 handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
964}
965
966/// Helper for converting an Error to a bool.
967///
968/// This method returns true if Err is in an error state, or false if it is
969/// in a success state. Puts Err in a checked state in both cases (unlike
970/// Error::operator bool(), which only does this for success states).
971inline bool errorToBool(Error Err) {
972 bool IsError = static_cast<bool>(Err);
973 if (IsError)
974 consumeError(std::move(Err));
975 return IsError;
976}
977
978/// Helper for Errors used as out-parameters.
979///
980/// This helper is for use with the Error-as-out-parameter idiom, where an error
981/// is passed to a function or method by reference, rather than being returned.
982/// In such cases it is helpful to set the checked bit on entry to the function
983/// so that the error can be written to (unchecked Errors abort on assignment)
984/// and clear the checked bit on exit so that clients cannot accidentally forget
985/// to check the result. This helper performs these actions automatically using
986/// RAII:
987///
988/// @code{.cpp}
989/// Result foo(Error &Err) {
990/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
991/// // <body of foo>
992/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
993/// }
994/// @endcode
995///
996/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
997/// used with optional Errors (Error pointers that are allowed to be null). If
998/// ErrorAsOutParameter took an Error reference, an instance would have to be
999/// created inside every condition that verified that Error was non-null. By
1000/// taking an Error pointer we can just create one instance at the top of the
1001/// function.
1002class ErrorAsOutParameter {
1003public:
1004 ErrorAsOutParameter(Error *Err) : Err(Err) {
1005 // Raise the checked bit if Err is success.
1006 if (Err)
1007 (void)!!*Err;
1008 }
1009
1010 ~ErrorAsOutParameter() {
1011 // Clear the checked bit.
1012 if (Err && !*Err)
1013 *Err = Error::success();
1014 }
1015
1016private:
1017 Error *Err;
1018};
1019
1020/// Helper for Expected<T>s used as out-parameters.
1021///
1022/// See ErrorAsOutParameter.
1023template <typename T>
1024class ExpectedAsOutParameter {
1025public:
1026 ExpectedAsOutParameter(Expected<T> *ValOrErr)
1027 : ValOrErr(ValOrErr) {
1028 if (ValOrErr)
1029 (void)!!*ValOrErr;
1030 }
1031
1032 ~ExpectedAsOutParameter() {
1033 if (ValOrErr)
1034 ValOrErr->setUnchecked();
1035 }
1036
1037private:
1038 Expected<T> *ValOrErr;
1039};
1040
1041/// This class wraps a std::error_code in a Error.
1042///
1043/// This is useful if you're writing an interface that returns a Error
1044/// (or Expected) and you want to call code that still returns
1045/// std::error_codes.
1046class ECError : public ErrorInfo<ECError> {
1047 friend Error errorCodeToError(std::error_code);
1048
1049public:
1050 void setErrorCode(std::error_code EC) { this->EC = EC; }
1051 std::error_code convertToErrorCode() const override { return EC; }
1052 void log(raw_ostream &OS) const override { OS << EC.message(); }
1053
1054 // Used by ErrorInfo::classID.
1055 static char ID;
1056
1057protected:
1058 ECError() = default;
1059 ECError(std::error_code EC) : EC(EC) {}
1060
1061 std::error_code EC;
1062};
1063
1064/// The value returned by this function can be returned from convertToErrorCode
1065/// for Error values where no sensible translation to std::error_code exists.
1066/// It should only be used in this situation, and should never be used where a
1067/// sensible conversion to std::error_code is available, as attempts to convert
1068/// to/from this error will result in a fatal error. (i.e. it is a programmatic
1069///error to try to convert such a value).
1070std::error_code inconvertibleErrorCode();
1071
1072/// Helper for converting an std::error_code to a Error.
1073Error errorCodeToError(std::error_code EC);
1074
1075/// Helper for converting an ECError to a std::error_code.
1076///
1077/// This method requires that Err be Error() or an ECError, otherwise it
1078/// will trigger a call to abort().
1079std::error_code errorToErrorCode(Error Err);
1080
1081/// Convert an ErrorOr<T> to an Expected<T>.
1082template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
1083 if (auto EC = EO.getError())
1084 return errorCodeToError(EC);
1085 return std::move(*EO);
1086}
1087
1088/// Convert an Expected<T> to an ErrorOr<T>.
1089template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
1090 if (auto Err = E.takeError())
1091 return errorToErrorCode(std::move(Err));
1092 return std::move(*E);
1093}
1094
1095/// This class wraps a string in an Error.
1096///
1097/// StringError is useful in cases where the client is not expected to be able
1098/// to consume the specific error message programmatically (for example, if the
1099/// error message is to be presented to the user).
1100class StringError : public ErrorInfo<StringError> {
1101public:
1102 static char ID;
1103
1104 StringError(const Twine &S, std::error_code EC);
1105
1106 void log(raw_ostream &OS) const override;
1107 std::error_code convertToErrorCode() const override;
1108
1109 const std::string &getMessage() const { return Msg; }
1110
1111private:
1112 std::string Msg;
1113 std::error_code EC;
1114};
1115
1116/// Helper for check-and-exit error handling.
1117///
1118/// For tool use only. NOT FOR USE IN LIBRARY CODE.
1119///
1120class ExitOnError {
1121public:
1122 /// Create an error on exit helper.
1123 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
1124 : Banner(std::move(Banner)),
1125 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
1126
1127 /// Set the banner string for any errors caught by operator().
1128 void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
1129
1130 /// Set the exit-code mapper function.
1131 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
1132 this->GetExitCode = std::move(GetExitCode);
1133 }
1134
1135 /// Check Err. If it's in a failure state log the error(s) and exit.
1136 void operator()(Error Err) const { checkError(std::move(Err)); }
1137
1138 /// Check E. If it's in a success state then return the contained value. If
1139 /// it's in a failure state log the error(s) and exit.
1140 template <typename T> T operator()(Expected<T> &&E) const {
1141 checkError(E.takeError());
1142 return std::move(*E);
1143 }
1144
1145 /// Check E. If it's in a success state then return the contained reference. If
1146 /// it's in a failure state log the error(s) and exit.
1147 template <typename T> T& operator()(Expected<T&> &&E) const {
1148 checkError(E.takeError());
1149 return *E;
1150 }
1151
1152private:
1153 void checkError(Error Err) const {
1154 if (Err) {
1155 int ExitCode = GetExitCode(Err);
1156 logAllUnhandledErrors(std::move(Err), errs(), Banner);
1157 exit(ExitCode);
1158 }
1159 }
1160
1161 std::string Banner;
1162 std::function<int(const Error &)> GetExitCode;
1163};
1164
1165} // end namespace llvm
1166
1167#endif // LLVM_SUPPORT_ERROR_H

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/unique_ptr.h

1// unique_ptr implementation -*- C++ -*-
2
3// Copyright (C) 2008-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file bits/unique_ptr.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{memory}
28 */
29
30#ifndef _UNIQUE_PTR_H1
31#define _UNIQUE_PTR_H1 1
32
33#include <bits/c++config.h>
34#include <debug/assertions.h>
35#include <type_traits>
36#include <utility>
37#include <tuple>
38#include <bits/stl_function.h>
39#include <bits/functional_hash.h>
40
41namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
42{
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
44
45 /**
46 * @addtogroup pointer_abstractions
47 * @{
48 */
49
50#if _GLIBCXX_USE_DEPRECATED1
51 template<typename> class auto_ptr;
52#endif
53
54 /// Primary template of default_delete, used by unique_ptr
55 template<typename _Tp>
56 struct default_delete
57 {
58 /// Default constructor
59 constexpr default_delete() noexcept = default;
60
61 /** @brief Converting constructor.
62 *
63 * Allows conversion from a deleter for arrays of another type, @p _Up,
64 * only if @p _Up* is convertible to @p _Tp*.
65 */
66 template<typename _Up, typename = typename
67 enable_if<is_convertible<_Up*, _Tp*>::value>::type>
68 default_delete(const default_delete<_Up>&) noexcept { }
69
70 /// Calls @c delete @p __ptr
71 void
72 operator()(_Tp* __ptr) const
73 {
74 static_assert(!is_void<_Tp>::value,
75 "can't delete pointer to incomplete type");
76 static_assert(sizeof(_Tp)>0,
77 "can't delete pointer to incomplete type");
78 delete __ptr;
79 }
80 };
81
82 // _GLIBCXX_RESOLVE_LIB_DEFECTS
83 // DR 740 - omit specialization for array objects with a compile time length
84 /// Specialization for arrays, default_delete.
85 template<typename _Tp>
86 struct default_delete<_Tp[]>
87 {
88 public:
89 /// Default constructor
90 constexpr default_delete() noexcept = default;
91
92 /** @brief Converting constructor.
93 *
94 * Allows conversion from a deleter for arrays of another type, such as
95 * a const-qualified version of @p _Tp.
96 *
97 * Conversions from types derived from @c _Tp are not allowed because
98 * it is unsafe to @c delete[] an array of derived types through a
99 * pointer to the base type.
100 */
101 template<typename _Up, typename = typename
102 enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type>
103 default_delete(const default_delete<_Up[]>&) noexcept { }
104
105 /// Calls @c delete[] @p __ptr
106 template<typename _Up>
107 typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type
108 operator()(_Up* __ptr) const
109 {
110 static_assert(sizeof(_Tp)>0,
111 "can't delete pointer to incomplete type");
112 delete [] __ptr;
113 }
114 };
115
116 template <typename _Tp, typename _Dp>
117 class __uniq_ptr_impl
118 {
119 template <typename _Up, typename _Ep, typename = void>
120 struct _Ptr
121 {
122 using type = _Up*;
123 };
124
125 template <typename _Up, typename _Ep>
126 struct
127 _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>>
128 {
129 using type = typename remove_reference<_Ep>::type::pointer;
130 };
131
132 public:
133 using _DeleterConstraint = enable_if<
134 __and_<__not_<is_pointer<_Dp>>,
135 is_default_constructible<_Dp>>::value>;
136
137 using pointer = typename _Ptr<_Tp, _Dp>::type;
138
139 __uniq_ptr_impl() = default;
140 __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
141
142 template<typename _Del>
143 __uniq_ptr_impl(pointer __p, _Del&& __d)
144 : _M_t(__p, std::forward<_Del>(__d)) { }
114
Calling 'forward'
115
Returning from 'forward'
116
Calling constructor for 'tuple'
139
Returning from constructor for 'tuple'
145
146 pointer& _M_ptr() { return std::get<0>(_M_t); }
89
Calling 'get'
96
Returning from 'get'
147 pointer _M_ptr() const { return std::get<0>(_M_t); }
78
Calling 'get'
85
Returning from 'get'
148 _Dp& _M_deleter() { return std::get<1>(_M_t); }
101
Calling 'get'
108
Returning from 'get'
149 const _Dp& _M_deleter() const { return std::get<1>(_M_t); }
150
151 private:
152 tuple<pointer, _Dp> _M_t;
153 };
154
155 /// 20.7.1.2 unique_ptr for single objects.
156 template <typename _Tp, typename _Dp = default_delete<_Tp>>
157 class unique_ptr
158 {
159 template <class _Up>
160 using _DeleterConstraint =
161 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
162
163 __uniq_ptr_impl<_Tp, _Dp> _M_t;
164
165 public:
166 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
167 using element_type = _Tp;
168 using deleter_type = _Dp;
169
170 // helper template for detecting a safe conversion from another
171 // unique_ptr
172 template<typename _Up, typename _Ep>
173 using __safe_conversion_up = __and_<
174 is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
175 __not_<is_array<_Up>>,
176 __or_<__and_<is_reference<deleter_type>,
177 is_same<deleter_type, _Ep>>,
178 __and_<__not_<is_reference<deleter_type>>,
179 is_convertible<_Ep, deleter_type>>
180 >
181 >;
182
183 // Constructors.
184
185 /// Default constructor, creates a unique_ptr that owns nothing.
186 template <typename _Up = _Dp,
187 typename = _DeleterConstraint<_Up>>
188 constexpr unique_ptr() noexcept
189 : _M_t()
190 { }
191
192 /** Takes ownership of a pointer.
193 *
194 * @param __p A pointer to an object of @c element_type
195 *
196 * The deleter will be value-initialized.
197 */
198 template <typename _Up = _Dp,
199 typename = _DeleterConstraint<_Up>>
200 explicit
201 unique_ptr(pointer __p) noexcept
202 : _M_t(__p)
203 { }
204
205 /** Takes ownership of a pointer.
206 *
207 * @param __p A pointer to an object of @c element_type
208 * @param __d A reference to a deleter.
209 *
210 * The deleter will be initialized with @p __d
211 */
212 unique_ptr(pointer __p,
213 typename conditional<is_reference<deleter_type>::value,
214 deleter_type, const deleter_type&>::type __d) noexcept
215 : _M_t(__p, __d) { }
216
217 /** Takes ownership of a pointer.
218 *
219 * @param __p A pointer to an object of @c element_type
220 * @param __d An rvalue reference to a deleter.
221 *
222 * The deleter will be initialized with @p std::move(__d)
223 */
224 unique_ptr(pointer __p,
225 typename remove_reference<deleter_type>::type&& __d) noexcept
226 : _M_t(std::move(__p), std::move(__d))
227 { static_assert(!std::is_reference<deleter_type>::value,
228 "rvalue deleter bound to reference"); }
229
230 /// Creates a unique_ptr that owns nothing.
231 template <typename _Up = _Dp,
232 typename = _DeleterConstraint<_Up>>
233 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
234
235 // Move constructors.
236
237 /// Move constructor.
238 unique_ptr(unique_ptr&& __u) noexcept
239 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
75
Calling 'unique_ptr::release'
98
Returning from 'unique_ptr::release'
99
Calling 'unique_ptr::get_deleter'
110
Returning from 'unique_ptr::get_deleter'
111
Calling 'forward'
112
Returning from 'forward'
113
Calling constructor for '__uniq_ptr_impl'
140
Returning from constructor for '__uniq_ptr_impl'
240
241 /** @brief Converting constructor from another type
242 *
243 * Requires that the pointer owned by @p __u is convertible to the
244 * type of pointer owned by this object, @p __u does not own an array,
245 * and @p __u has a compatible deleter type.
246 */
247 template<typename _Up, typename _Ep, typename = _Require<
248 __safe_conversion_up<_Up, _Ep>,
249 typename conditional<is_reference<_Dp>::value,
250 is_same<_Ep, _Dp>,
251 is_convertible<_Ep, _Dp>>::type>>
252 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
253 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
254 { }
255
256#if _GLIBCXX_USE_DEPRECATED1
257 /// Converting constructor from @c auto_ptr
258 template<typename _Up, typename = _Require<
259 is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
260 unique_ptr(auto_ptr<_Up>&& __u) noexcept;
261#endif
262
263 /// Destructor, invokes the deleter if the stored pointer is not null.
264 ~unique_ptr() noexcept
265 {
266 auto& __ptr = _M_t._M_ptr();
267 if (__ptr != nullptr)
268 get_deleter()(__ptr);
269 __ptr = pointer();
270 }
271
272 // Assignment.
273
274 /** @brief Move assignment operator.
275 *
276 * @param __u The object to transfer ownership from.
277 *
278 * Invokes the deleter first if this object owns a pointer.
279 */
280 unique_ptr&
281 operator=(unique_ptr&& __u) noexcept
282 {
283 reset(__u.release());
284 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
285 return *this;
286 }
287
288 /** @brief Assignment from another type.
289 *
290 * @param __u The object to transfer ownership from, which owns a
291 * convertible pointer to a non-array object.
292 *
293 * Invokes the deleter first if this object owns a pointer.
294 */
295 template<typename _Up, typename _Ep>
296 typename enable_if< __and_<
297 __safe_conversion_up<_Up, _Ep>,
298 is_assignable<deleter_type&, _Ep&&>
299 >::value,
300 unique_ptr&>::type
301 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
302 {
303 reset(__u.release());
304 get_deleter() = std::forward<_Ep>(__u.get_deleter());
305 return *this;
306 }
307
308 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
309 unique_ptr&
310 operator=(nullptr_t) noexcept
311 {
312 reset();
313 return *this;
314 }
315
316 // Observers.
317
318 /// Dereference the stored pointer.
319 typename add_lvalue_reference<element_type>::type
320 operator*() const
321 {
322 __glibcxx_assert(get() != pointer());
323 return *get();
324 }
325
326 /// Return the stored pointer.
327 pointer
328 operator->() const noexcept
329 {
330 _GLIBCXX_DEBUG_PEDASSERT(get() != pointer());
331 return get();
332 }
333
334 /// Return the stored pointer.
335 pointer
336 get() const noexcept
337 { return _M_t._M_ptr(); }
77
Calling '__uniq_ptr_impl::_M_ptr'
86
Returning from '__uniq_ptr_impl::_M_ptr'
338
339 /// Return a reference to the stored deleter.
340 deleter_type&
341 get_deleter() noexcept
342 { return _M_t._M_deleter(); }
100
Calling '__uniq_ptr_impl::_M_deleter'
109
Returning from '__uniq_ptr_impl::_M_deleter'
343
344 /// Return a reference to the stored deleter.
345 const deleter_type&
346 get_deleter() const noexcept
347 { return _M_t._M_deleter(); }
348
349 /// Return @c true if the stored pointer is not null.
350 explicit operator bool() const noexcept
351 { return get() == pointer() ? false : true; }
352
353 // Modifiers.
354
355 /// Release ownership of any stored pointer.
356 pointer
357 release() noexcept
358 {
359 pointer __p = get();
76
Calling 'unique_ptr::get'
87
Returning from 'unique_ptr::get'
360 _M_t._M_ptr() = pointer();
88
Calling '__uniq_ptr_impl::_M_ptr'
97
Returning from '__uniq_ptr_impl::_M_ptr'
361 return __p;
362 }
363
364 /** @brief Replace the stored pointer.
365 *
366 * @param __p The new pointer to store.
367 *
368 * The deleter will be invoked if a pointer is already owned.
369 */
370 void
371 reset(pointer __p = pointer()) noexcept
372 {
373 using std::swap;
374 swap(_M_t._M_ptr(), __p);
375 if (__p != pointer())
376 get_deleter()(__p);
377 }
378
379 /// Exchange the pointer and deleter with another object.
380 void
381 swap(unique_ptr& __u) noexcept
382 {
383 using std::swap;
384 swap(_M_t, __u._M_t);
385 }
386
387 // Disable copy from lvalue.
388 unique_ptr(const unique_ptr&) = delete;
389 unique_ptr& operator=(const unique_ptr&) = delete;
390 };
391
392 /// 20.7.1.3 unique_ptr for array objects with a runtime length
393 // [unique.ptr.runtime]
394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
395 // DR 740 - omit specialization for array objects with a compile time length
396 template<typename _Tp, typename _Dp>
397 class unique_ptr<_Tp[], _Dp>
398 {
399 template <typename _Up>
400 using _DeleterConstraint =
401 typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type;
402
403 __uniq_ptr_impl<_Tp, _Dp> _M_t;
404
405 template<typename _Up>
406 using __remove_cv = typename remove_cv<_Up>::type;
407
408 // like is_base_of<_Tp, _Up> but false if unqualified types are the same
409 template<typename _Up>
410 using __is_derived_Tp
411 = __and_< is_base_of<_Tp, _Up>,
412 __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >;
413
414 public:
415 using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer;
416 using element_type = _Tp;
417 using deleter_type = _Dp;
418
419 // helper template for detecting a safe conversion from another
420 // unique_ptr
421 template<typename _Up, typename _Ep,
422 typename _Up_up = unique_ptr<_Up, _Ep>,
423 typename _Up_element_type = typename _Up_up::element_type>
424 using __safe_conversion_up = __and_<
425 is_array<_Up>,
426 is_same<pointer, element_type*>,
427 is_same<typename _Up_up::pointer, _Up_element_type*>,
428 is_convertible<_Up_element_type(*)[], element_type(*)[]>,
429 __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
430 __and_<__not_<is_reference<deleter_type>>,
431 is_convertible<_Ep, deleter_type>>>
432 >;
433
434 // helper template for detecting a safe conversion from a raw pointer
435 template<typename _Up>
436 using __safe_conversion_raw = __and_<
437 __or_<__or_<is_same<_Up, pointer>,
438 is_same<_Up, nullptr_t>>,
439 __and_<is_pointer<_Up>,
440 is_same<pointer, element_type*>,
441 is_convertible<
442 typename remove_pointer<_Up>::type(*)[],
443 element_type(*)[]>
444 >
445 >
446 >;
447
448 // Constructors.
449
450 /// Default constructor, creates a unique_ptr that owns nothing.
451 template <typename _Up = _Dp,
452 typename = _DeleterConstraint<_Up>>
453 constexpr unique_ptr() noexcept
454 : _M_t()
455 { }
456
457 /** Takes ownership of a pointer.
458 *
459 * @param __p A pointer to an array of a type safely convertible
460 * to an array of @c element_type
461 *
462 * The deleter will be value-initialized.
463 */
464 template<typename _Up,
465 typename _Vp = _Dp,
466 typename = _DeleterConstraint<_Vp>,
467 typename = typename enable_if<
468 __safe_conversion_raw<_Up>::value, bool>::type>
469 explicit
470 unique_ptr(_Up __p) noexcept
471 : _M_t(__p)
472 { }
473
474 /** Takes ownership of a pointer.
475 *
476 * @param __p A pointer to an array of a type safely convertible
477 * to an array of @c element_type
478 * @param __d A reference to a deleter.
479 *
480 * The deleter will be initialized with @p __d
481 */
482 template<typename _Up,
483 typename = typename enable_if<
484 __safe_conversion_raw<_Up>::value, bool>::type>
485 unique_ptr(_Up __p,
486 typename conditional<is_reference<deleter_type>::value,
487 deleter_type, const deleter_type&>::type __d) noexcept
488 : _M_t(__p, __d) { }
489
490 /** Takes ownership of a pointer.
491 *
492 * @param __p A pointer to an array of a type safely convertible
493 * to an array of @c element_type
494 * @param __d A reference to a deleter.
495 *
496 * The deleter will be initialized with @p std::move(__d)
497 */
498 template<typename _Up,
499 typename = typename enable_if<
500 __safe_conversion_raw<_Up>::value, bool>::type>
501 unique_ptr(_Up __p, typename
502 remove_reference<deleter_type>::type&& __d) noexcept
503 : _M_t(std::move(__p), std::move(__d))
504 { static_assert(!is_reference<deleter_type>::value,
505 "rvalue deleter bound to reference"); }
506
507 /// Move constructor.
508 unique_ptr(unique_ptr&& __u) noexcept
509 : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { }
510
511 /// Creates a unique_ptr that owns nothing.
512 template <typename _Up = _Dp,
513 typename = _DeleterConstraint<_Up>>
514 constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
515
516 template<typename _Up, typename _Ep,
517 typename = _Require<__safe_conversion_up<_Up, _Ep>>>
518 unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
519 : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
520 { }
521
522 /// Destructor, invokes the deleter if the stored pointer is not null.
523 ~unique_ptr()
524 {
525 auto& __ptr = _M_t._M_ptr();
526 if (__ptr != nullptr)
527 get_deleter()(__ptr);
528 __ptr = pointer();
529 }
530
531 // Assignment.
532
533 /** @brief Move assignment operator.
534 *
535 * @param __u The object to transfer ownership from.
536 *
537 * Invokes the deleter first if this object owns a pointer.
538 */
539 unique_ptr&
540 operator=(unique_ptr&& __u) noexcept
541 {
542 reset(__u.release());
543 get_deleter() = std::forward<deleter_type>(__u.get_deleter());
544 return *this;
545 }
546
547 /** @brief Assignment from another type.
548 *
549 * @param __u The object to transfer ownership from, which owns a
550 * convertible pointer to an array object.
551 *
552 * Invokes the deleter first if this object owns a pointer.
553 */
554 template<typename _Up, typename _Ep>
555 typename
556 enable_if<__and_<__safe_conversion_up<_Up, _Ep>,
557 is_assignable<deleter_type&, _Ep&&>
558 >::value,
559 unique_ptr&>::type
560 operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
561 {
562 reset(__u.release());
563 get_deleter() = std::forward<_Ep>(__u.get_deleter());
564 return *this;
565 }
566
567 /// Reset the %unique_ptr to empty, invoking the deleter if necessary.
568 unique_ptr&
569 operator=(nullptr_t) noexcept
570 {
571 reset();
572 return *this;
573 }
574
575 // Observers.
576
577 /// Access an element of owned array.
578 typename std::add_lvalue_reference<element_type>::type
579 operator[](size_t __i) const
580 {
581 __glibcxx_assert(get() != pointer());
582 return get()[__i];
583 }
584
585 /// Return the stored pointer.
586 pointer
587 get() const noexcept
588 { return _M_t._M_ptr(); }
589
590 /// Return a reference to the stored deleter.
591 deleter_type&
592 get_deleter() noexcept
593 { return _M_t._M_deleter(); }
594
595 /// Return a reference to the stored deleter.
596 const deleter_type&
597 get_deleter() const noexcept
598 { return _M_t._M_deleter(); }
599
600 /// Return @c true if the stored pointer is not null.
601 explicit operator bool() const noexcept
602 { return get() == pointer() ? false : true; }
603
604 // Modifiers.
605
606 /// Release ownership of any stored pointer.
607 pointer
608 release() noexcept
609 {
610 pointer __p = get();
611 _M_t._M_ptr() = pointer();
612 return __p;
613 }
614
615 /** @brief Replace the stored pointer.
616 *
617 * @param __p The new pointer to store.
618 *
619 * The deleter will be invoked if a pointer is already owned.
620 */
621 template <typename _Up,
622 typename = _Require<
623 __or_<is_same<_Up, pointer>,
624 __and_<is_same<pointer, element_type*>,
625 is_pointer<_Up>,
626 is_convertible<
627 typename remove_pointer<_Up>::type(*)[],
628 element_type(*)[]
629 >
630 >
631 >
632 >>
633 void
634 reset(_Up __p) noexcept
635 {
636 pointer __ptr = __p;
637 using std::swap;
638 swap(_M_t._M_ptr(), __ptr);
639 if (__ptr != nullptr)
640 get_deleter()(__ptr);
641 }
642
643 void reset(nullptr_t = nullptr) noexcept
644 {
645 reset(pointer());
646 }
647
648 /// Exchange the pointer and deleter with another object.
649 void
650 swap(unique_ptr& __u) noexcept
651 {
652 using std::swap;
653 swap(_M_t, __u._M_t);
654 }
655
656 // Disable copy from lvalue.
657 unique_ptr(const unique_ptr&) = delete;
658 unique_ptr& operator=(const unique_ptr&) = delete;
659 };
660
661 template<typename _Tp, typename _Dp>
662 inline
663#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
664 // Constrained free swap overload, see p0185r1
665 typename enable_if<__is_swappable<_Dp>::value>::type
666#else
667 void
668#endif
669 swap(unique_ptr<_Tp, _Dp>& __x,
670 unique_ptr<_Tp, _Dp>& __y) noexcept
671 { __x.swap(__y); }
672
673#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
674 template<typename _Tp, typename _Dp>
675 typename enable_if<!__is_swappable<_Dp>::value>::type
676 swap(unique_ptr<_Tp, _Dp>&,
677 unique_ptr<_Tp, _Dp>&) = delete;
678#endif
679
680 template<typename _Tp, typename _Dp,
681 typename _Up, typename _Ep>
682 inline bool
683 operator==(const unique_ptr<_Tp, _Dp>& __x,
684 const unique_ptr<_Up, _Ep>& __y)
685 { return __x.get() == __y.get(); }
686
687 template<typename _Tp, typename _Dp>
688 inline bool
689 operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
690 { return !__x; }
691
692 template<typename _Tp, typename _Dp>
693 inline bool
694 operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
695 { return !__x; }
696
697 template<typename _Tp, typename _Dp,
698 typename _Up, typename _Ep>
699 inline bool
700 operator!=(const unique_ptr<_Tp, _Dp>& __x,
701 const unique_ptr<_Up, _Ep>& __y)
702 { return __x.get() != __y.get(); }
703
704 template<typename _Tp, typename _Dp>
705 inline bool
706 operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept
707 { return (bool)__x; }
708
709 template<typename _Tp, typename _Dp>
710 inline bool
711 operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept
712 { return (bool)__x; }
713
714 template<typename _Tp, typename _Dp,
715 typename _Up, typename _Ep>
716 inline bool
717 operator<(const unique_ptr<_Tp, _Dp>& __x,
718 const unique_ptr<_Up, _Ep>& __y)
719 {
720 typedef typename
721 std::common_type<typename unique_ptr<_Tp, _Dp>::pointer,
722 typename unique_ptr<_Up, _Ep>::pointer>::type _CT;
723 return std::less<_CT>()(__x.get(), __y.get());
724 }
725
726 template<typename _Tp, typename _Dp>
727 inline bool
728 operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
729 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
730 nullptr); }
731
732 template<typename _Tp, typename _Dp>
733 inline bool
734 operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
735 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
736 __x.get()); }
737
738 template<typename _Tp, typename _Dp,
739 typename _Up, typename _Ep>
740 inline bool
741 operator<=(const unique_ptr<_Tp, _Dp>& __x,
742 const unique_ptr<_Up, _Ep>& __y)
743 { return !(__y < __x); }
744
745 template<typename _Tp, typename _Dp>
746 inline bool
747 operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
748 { return !(nullptr < __x); }
749
750 template<typename _Tp, typename _Dp>
751 inline bool
752 operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
753 { return !(__x < nullptr); }
754
755 template<typename _Tp, typename _Dp,
756 typename _Up, typename _Ep>
757 inline bool
758 operator>(const unique_ptr<_Tp, _Dp>& __x,
759 const unique_ptr<_Up, _Ep>& __y)
760 { return (__y < __x); }
761
762 template<typename _Tp, typename _Dp>
763 inline bool
764 operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
765 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr,
766 __x.get()); }
767
768 template<typename _Tp, typename _Dp>
769 inline bool
770 operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
771 { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(),
772 nullptr); }
773
774 template<typename _Tp, typename _Dp,
775 typename _Up, typename _Ep>
776 inline bool
777 operator>=(const unique_ptr<_Tp, _Dp>& __x,
778 const unique_ptr<_Up, _Ep>& __y)
779 { return !(__x < __y); }
780
781 template<typename _Tp, typename _Dp>
782 inline bool
783 operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t)
784 { return !(__x < nullptr); }
785
786 template<typename _Tp, typename _Dp>
787 inline bool
788 operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x)
789 { return !(nullptr < __x); }
790
791 /// std::hash specialization for unique_ptr.
792 template<typename _Tp, typename _Dp>
793 struct hash<unique_ptr<_Tp, _Dp>>
794 : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>,
795 private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer>
796 {
797 size_t
798 operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept
799 {
800 typedef unique_ptr<_Tp, _Dp> _UP;
801 return std::hash<typename _UP::pointer>()(__u.get());
802 }
803 };
804
805#if __cplusplus201103L > 201103L
806
807#define __cpp_lib_make_unique 201304
808
809 template<typename _Tp>
810 struct _MakeUniq
811 { typedef unique_ptr<_Tp> __single_object; };
812
813 template<typename _Tp>
814 struct _MakeUniq<_Tp[]>
815 { typedef unique_ptr<_Tp[]> __array; };
816
817 template<typename _Tp, size_t _Bound>
818 struct _MakeUniq<_Tp[_Bound]>
819 { struct __invalid_type { }; };
820
821 /// std::make_unique for single objects
822 template<typename _Tp, typename... _Args>
823 inline typename _MakeUniq<_Tp>::__single_object
824 make_unique(_Args&&... __args)
825 { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
826
827 /// std::make_unique for arrays of unknown bound
828 template<typename _Tp>
829 inline typename _MakeUniq<_Tp>::__array
830 make_unique(size_t __num)
831 { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); }
832
833 /// Disable std::make_unique for arrays of known bound
834 template<typename _Tp, typename... _Args>
835 inline typename _MakeUniq<_Tp>::__invalid_type
836 make_unique(_Args&&...) = delete;
837#endif
838
839 // @} group pointer_abstractions
840
841_GLIBCXX_END_NAMESPACE_VERSION
842} // namespace
843
844#endif /* _UNIQUE_PTR_H */

/usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/tuple

1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-2017 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/tuple
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE1
30#define _GLIBCXX_TUPLE1 1
31
32#pragma GCC system_header
33
34#if __cplusplus201103L < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <utility>
39#include <array>
40#include <bits/uses_allocator.h>
41#include <bits/invoke.h>
42
43namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
44{
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
46
47 /**
48 * @addtogroup utilities
49 * @{
50 */
51
52 template<typename... _Elements>
53 class tuple;
54
55 template<typename _Tp>
56 struct __is_empty_non_tuple : is_empty<_Tp> { };
57
58 // Using EBO for elements that are tuples causes ambiguous base errors.
59 template<typename _El0, typename... _El>
60 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
61
62 // Use the Empty Base-class Optimization for empty, non-final types.
63 template<typename _Tp>
64 using __empty_not_final
65 = typename conditional<__is_final(_Tp), false_type,
66 __is_empty_non_tuple<_Tp>>::type;
67
68 template<std::size_t _Idx, typename _Head,
69 bool = __empty_not_final<_Head>::value>
70 struct _Head_base;
71
72 template<std::size_t _Idx, typename _Head>
73 struct _Head_base<_Idx, _Head, true>
74 : public _Head
75 {
76 constexpr _Head_base()
77 : _Head() { }
78
79 constexpr _Head_base(const _Head& __h)
80 : _Head(__h) { }
81
82 constexpr _Head_base(const _Head_base&) = default;
83 constexpr _Head_base(_Head_base&&) = default;
84
85 template<typename _UHead>
86 constexpr _Head_base(_UHead&& __h)
87 : _Head(std::forward<_UHead>(__h)) { }
128
Calling 'forward'
129
Returning from 'forward'
88
89 _Head_base(allocator_arg_t, __uses_alloc0)
90 : _Head() { }
91
92 template<typename _Alloc>
93 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
94 : _Head(allocator_arg, *__a._M_a) { }
95
96 template<typename _Alloc>
97 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
98 : _Head(*__a._M_a) { }
99
100 template<typename _UHead>
101 _Head_base(__uses_alloc0, _UHead&& __uhead)
102 : _Head(std::forward<_UHead>(__uhead)) { }
103
104 template<typename _Alloc, typename _UHead>
105 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
106 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
107
108 template<typename _Alloc, typename _UHead>
109 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
110 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
111
112 static constexpr _Head&
113 _M_head(_Head_base& __b) noexcept { return __b; }
114
115 static constexpr const _Head&
116 _M_head(const _Head_base& __b) noexcept { return __b; }
117 };
118
119 template<std::size_t _Idx, typename _Head>
120 struct _Head_base<_Idx, _Head, false>
121 {
122 constexpr _Head_base()
123 : _M_head_impl() { }
124
125 constexpr _Head_base(const _Head& __h)
126 : _M_head_impl(__h) { }
127
128 constexpr _Head_base(const _Head_base&) = default;
129 constexpr _Head_base(_Head_base&&) = default;
130
131 template<typename _UHead>
132 constexpr _Head_base(_UHead&& __h)
133 : _M_head_impl(std::forward<_UHead>(__h)) { }
135
Calling 'forward'
136
Returning from 'forward'
134
135 _Head_base(allocator_arg_t, __uses_alloc0)
136 : _M_head_impl() { }
137
138 template<typename _Alloc>
139 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
140 : _M_head_impl(allocator_arg, *__a._M_a) { }
141
142 template<typename _Alloc>
143 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
144 : _M_head_impl(*__a._M_a) { }
145
146 template<typename _UHead>
147 _Head_base(__uses_alloc0, _UHead&& __uhead)
148 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
149
150 template<typename _Alloc, typename _UHead>
151 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
152 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
153 { }
154
155 template<typename _Alloc, typename _UHead>
156 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
157 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
158
159 static constexpr _Head&
160 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
161
162 static constexpr const _Head&
163 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
164
165 _Head _M_head_impl;
166 };
167
168 /**
169 * Contains the actual implementation of the @c tuple template, stored
170 * as a recursive inheritance hierarchy from the first element (most
171 * derived class) to the last (least derived class). The @c Idx
172 * parameter gives the 0-based index of the element stored at this
173 * point in the hierarchy; we use it to implement a constant-time
174 * get() operation.
175 */
176 template<std::size_t _Idx, typename... _Elements>
177 struct _Tuple_impl;
178
179 /**
180 * Recursive tuple implementation. Here we store the @c Head element
181 * and derive from a @c Tuple_impl containing the remaining elements
182 * (which contains the @c Tail).
183 */
184 template<std::size_t _Idx, typename _Head, typename... _Tail>
185 struct _Tuple_impl<_Idx, _Head, _Tail...>
186 : public _Tuple_impl<_Idx + 1, _Tail...>,
187 private _Head_base<_Idx, _Head>
188 {
189 template<std::size_t, typename...> friend class _Tuple_impl;
190
191 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
192 typedef _Head_base<_Idx, _Head> _Base;
193
194 static constexpr _Head&
195 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
92
Calling '_Head_base::_M_head'
93
Returning from '_Head_base::_M_head'
196
197 static constexpr const _Head&
198 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
81
Calling '_Head_base::_M_head'
82
Returning from '_Head_base::_M_head'
199
200 static constexpr _Inherited&
201 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
202
203 static constexpr const _Inherited&
204 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
205
206 constexpr _Tuple_impl()
207 : _Inherited(), _Base() { }
208
209 explicit
210 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
211 : _Inherited(__tail...), _Base(__head) { }
212
213 template<typename _UHead, typename... _UTail, typename = typename
214 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
215 explicit
216 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
217 : _Inherited(std::forward<_UTail>(__tail)...),
122
Calling 'forward'
123
Returning from 'forward'
124
Calling constructor for '_Tuple_impl'
131
Returning from constructor for '_Tuple_impl'
218 _Base(std::forward<_UHead>(__head)) { }
132
Calling 'forward'
133
Returning from 'forward'
134
Calling constructor for '_Head_base'
137
Returning from constructor for '_Head_base'
219
220 constexpr _Tuple_impl(const _Tuple_impl&) = default;
221
222 constexpr
223 _Tuple_impl(_Tuple_impl&& __in)
224 noexcept(__and_<is_nothrow_move_constructible<_Head>,
225 is_nothrow_move_constructible<_Inherited>>::value)
226 : _Inherited(std::move(_M_tail(__in))),
227 _Base(std::forward<_Head>(_M_head(__in))) { }
228
229 template<typename... _UElements>
230 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
231 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
232 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
233
234 template<typename _UHead, typename... _UTails>
235 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
236 : _Inherited(std::move
237 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
238 _Base(std::forward<_UHead>
239 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
240
241 template<typename _Alloc>
242 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
243 : _Inherited(__tag, __a),
244 _Base(__tag, __use_alloc<_Head>(__a)) { }
245
246 template<typename _Alloc>
247 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
248 const _Head& __head, const _Tail&... __tail)
249 : _Inherited(__tag, __a, __tail...),
250 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
251
252 template<typename _Alloc, typename _UHead, typename... _UTail,
253 typename = typename enable_if<sizeof...(_Tail)
254 == sizeof...(_UTail)>::type>
255 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
256 _UHead&& __head, _UTail&&... __tail)
257 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
258 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
259 std::forward<_UHead>(__head)) { }
260
261 template<typename _Alloc>
262 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
263 const _Tuple_impl& __in)
264 : _Inherited(__tag, __a, _M_tail(__in)),
265 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
266
267 template<typename _Alloc>
268 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
269 _Tuple_impl&& __in)
270 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
271 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
272 std::forward<_Head>(_M_head(__in))) { }
273
274 template<typename _Alloc, typename... _UElements>
275 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
276 const _Tuple_impl<_Idx, _UElements...>& __in)
277 : _Inherited(__tag, __a,
278 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
279 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
280 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
281
282 template<typename _Alloc, typename _UHead, typename... _UTails>
283 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
284 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
285 : _Inherited(__tag, __a, std::move
286 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
287 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
288 std::forward<_UHead>
289 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
290
291 _Tuple_impl&
292 operator=(const _Tuple_impl& __in)
293 {
294 _M_head(*this) = _M_head(__in);
295 _M_tail(*this) = _M_tail(__in);
296 return *this;
297 }
298
299 _Tuple_impl&
300 operator=(_Tuple_impl&& __in)
301 noexcept(__and_<is_nothrow_move_assignable<_Head>,
302 is_nothrow_move_assignable<_Inherited>>::value)
303 {
304 _M_head(*this) = std::forward<_Head>(_M_head(__in));
305 _M_tail(*this) = std::move(_M_tail(__in));
306 return *this;
307 }
308
309 template<typename... _UElements>
310 _Tuple_impl&
311 operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
312 {
313 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
314 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
315 return *this;
316 }
317
318 template<typename _UHead, typename... _UTails>
319 _Tuple_impl&
320 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321 {
322 _M_head(*this) = std::forward<_UHead>
323 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
324 _M_tail(*this) = std::move
325 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
326 return *this;
327 }
328
329 protected:
330 void
331 _M_swap(_Tuple_impl& __in)
332 noexcept(__is_nothrow_swappable<_Head>::value
333 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
334 {
335 using std::swap;
336 swap(_M_head(*this), _M_head(__in));
337 _Inherited::_M_swap(_M_tail(__in));
338 }
339 };
340
341 // Basis case of inheritance recursion.
342 template<std::size_t _Idx, typename _Head>
343 struct _Tuple_impl<_Idx, _Head>
344 : private _Head_base<_Idx, _Head>
345 {
346 template<std::size_t, typename...> friend class _Tuple_impl;
347
348 typedef _Head_base<_Idx, _Head> _Base;
349
350 static constexpr _Head&
351 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
104
Calling '_Head_base::_M_head'
105
Returning from '_Head_base::_M_head'
352
353 static constexpr const _Head&
354 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
355
356 constexpr _Tuple_impl()
357 : _Base() { }
358
359 explicit
360 constexpr _Tuple_impl(const _Head& __head)
361 : _Base(__head) { }
362
363 template<typename _UHead>
364 explicit
365 constexpr _Tuple_impl(_UHead&& __head)
366 : _Base(std::forward<_UHead>(__head)) { }
125
Calling 'forward'
126
Returning from 'forward'
127
Calling constructor for '_Head_base'
130
Returning from constructor for '_Head_base'
367
368 constexpr _Tuple_impl(const _Tuple_impl&) = default;
369
370 constexpr
371 _Tuple_impl(_Tuple_impl&& __in)
372 noexcept(is_nothrow_move_constructible<_Head>::value)
373 : _Base(std::forward<_Head>(_M_head(__in))) { }
374
375 template<typename _UHead>
376 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
377 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
378
379 template<typename _UHead>
380 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
381 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
382 { }
383
384 template<typename _Alloc>
385 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
386 : _Base(__tag, __use_alloc<_Head>(__a)) { }
387
388 template<typename _Alloc>
389 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
390 const _Head& __head)
391 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
392
393 template<typename _Alloc, typename _UHead>
394 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
395 _UHead&& __head)
396 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
397 std::forward<_UHead>(__head)) { }
398
399 template<typename _Alloc>
400 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
401 const _Tuple_impl& __in)
402 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
403
404 template<typename _Alloc>
405 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
406 _Tuple_impl&& __in)
407 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
408 std::forward<_Head>(_M_head(__in))) { }
409
410 template<typename _Alloc, typename _UHead>
411 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412 const _Tuple_impl<_Idx, _UHead>& __in)
413 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
414 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
415
416 template<typename _Alloc, typename _UHead>
417 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
418 _Tuple_impl<_Idx, _UHead>&& __in)
419 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
420 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
421 { }
422
423 _Tuple_impl&
424 operator=(const _Tuple_impl& __in)
425 {
426 _M_head(*this) = _M_head(__in);
427 return *this;
428 }
429
430 _Tuple_impl&
431 operator=(_Tuple_impl&& __in)
432 noexcept(is_nothrow_move_assignable<_Head>::value)
433 {
434 _M_head(*this) = std::forward<_Head>(_M_head(__in));
435 return *this;
436 }
437
438 template<typename _UHead>
439 _Tuple_impl&
440 operator=(const _Tuple_impl<_Idx, _UHead>& __in)
441 {
442 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
443 return *this;
444 }
445
446 template<typename _UHead>
447 _Tuple_impl&
448 operator=(_Tuple_impl<_Idx, _UHead>&& __in)
449 {
450 _M_head(*this)
451 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
452 return *this;
453 }
454
455 protected:
456 void
457 _M_swap(_Tuple_impl& __in)
458 noexcept(__is_nothrow_swappable<_Head>::value)
459 {
460 using std::swap;
461 swap(_M_head(*this), _M_head(__in));
462 }
463 };
464
465 // Concept utility functions, reused in conditionally-explicit
466 // constructors.
467 template<bool, typename... _Elements>
468 struct _TC
469 {
470 template<typename... _UElements>
471 static constexpr bool _ConstructibleTuple()
472 {
473 return __and_<is_constructible<_Elements, const _UElements&>...>::value;
474 }
475
476 template<typename... _UElements>
477 static constexpr bool _ImplicitlyConvertibleTuple()
478 {
479 return __and_<is_convertible<const _UElements&, _Elements>...>::value;
480 }
481
482 template<typename... _UElements>
483 static constexpr bool _MoveConstructibleTuple()
484 {
485 return __and_<is_constructible<_Elements, _UElements&&>...>::value;
486 }
487
488 template<typename... _UElements>
489 static constexpr bool _ImplicitlyMoveConvertibleTuple()
490 {
491 return __and_<is_convertible<_UElements&&, _Elements>...>::value;
492 }
493
494 template<typename _SrcTuple>
495 static constexpr bool _NonNestedTuple()
496 {
497 return __and_<__not_<is_same<tuple<_Elements...>,
498 typename remove_cv<
499 typename remove_reference<_SrcTuple>::type
500 >::type>>,
501 __not_<is_convertible<_SrcTuple, _Elements...>>,
502 __not_<is_constructible<_Elements..., _SrcTuple>>
503 >::value;
504 }
505 template<typename... _UElements>
506 static constexpr bool _NotSameTuple()
507 {
508 return __not_<is_same<tuple<_Elements...>,
509 typename remove_const<
510 typename remove_reference<_UElements...>::type
511 >::type>>::value;
512 }
513 };
514
515 template<typename... _Elements>
516 struct _TC<false, _Elements...>
517 {
518 template<typename... _UElements>
519 static constexpr bool _ConstructibleTuple()
520 {
521 return false;
522 }
523
524 template<typename... _UElements>
525 static constexpr bool _ImplicitlyConvertibleTuple()
526 {
527 return false;
528 }
529
530 template<typename... _UElements>
531 static constexpr bool _MoveConstructibleTuple()
532 {
533 return false;
534 }
535
536 template<typename... _UElements>
537 static constexpr bool _ImplicitlyMoveConvertibleTuple()
538 {
539 return false;
540 }
541
542 template<typename... _UElements>
543 static constexpr bool _NonNestedTuple()
544 {
545 return true;
546 }
547 template<typename... _UElements>
548 static constexpr bool _NotSameTuple()
549 {
550 return true;
551 }
552 };
553
554 /// Primary class template, tuple
555 template<typename... _Elements>
556 class tuple : public _Tuple_impl<0, _Elements...>
557 {
558 typedef _Tuple_impl<0, _Elements...> _Inherited;
559
560 // Used for constraining the default constructor so
561 // that it becomes dependent on the constraints.
562 template<typename _Dummy>
563 struct _TC2
564 {
565 static constexpr bool _DefaultConstructibleTuple()
566 {
567 return __and_<is_default_constructible<_Elements>...>::value;
568 }
569 static constexpr bool _ImplicitlyDefaultConstructibleTuple()
570 {
571 return __and_<__is_implicitly_default_constructible<_Elements>...>
572 ::value;
573 }
574 };
575
576 public:
577 template<typename _Dummy = void,
578 typename enable_if<_TC2<_Dummy>::
579 _ImplicitlyDefaultConstructibleTuple(),
580 bool>::type = true>
581 constexpr tuple()
582 : _Inherited() { }
583
584 template<typename _Dummy = void,
585 typename enable_if<_TC2<_Dummy>::
586 _DefaultConstructibleTuple()
587 &&
588 !_TC2<_Dummy>::
589 _ImplicitlyDefaultConstructibleTuple(),
590 bool>::type = false>
591 explicit constexpr tuple()
592 : _Inherited() { }
593
594 // Shortcut for the cases where constructors taking _Elements...
595 // need to be constrained.
596 template<typename _Dummy> using _TCC =
597 _TC<is_same<_Dummy, void>::value,
598 _Elements...>;
599
600 template<typename _Dummy = void,
601 typename enable_if<
602 _TCC<_Dummy>::template
603 _ConstructibleTuple<_Elements...>()
604 && _TCC<_Dummy>::template
605 _ImplicitlyConvertibleTuple<_Elements...>()
606 && (sizeof...(_Elements) >= 1),
607 bool>::type=true>
608 constexpr tuple(const _Elements&... __elements)
609 : _Inherited(__elements...) { }
610
611 template<typename _Dummy = void,
612 typename enable_if<
613 _TCC<_Dummy>::template
614 _ConstructibleTuple<_Elements...>()
615 && !_TCC<_Dummy>::template
616 _ImplicitlyConvertibleTuple<_Elements...>()
617 && (sizeof...(_Elements) >= 1),
618 bool>::type=false>
619 explicit constexpr tuple(const _Elements&... __elements)
620 : _Inherited(__elements...) { }
621
622 // Shortcut for the cases where constructors taking _UElements...
623 // need to be constrained.
624 template<typename... _UElements> using _TMC =
625 _TC<(sizeof...(_Elements) == sizeof...(_UElements))
626 && (_TC<(sizeof...(_UElements)==1), _Elements...>::
627 template _NotSameTuple<_UElements...>()),
628 _Elements...>;
629
630 // Shortcut for the cases where constructors taking tuple<_UElements...>
631 // need to be constrained.
632 template<typename... _UElements> using _TMCT =
633 _TC<(sizeof...(_Elements) == sizeof...(_UElements))
634 && !is_same<tuple<_Elements...>,
635 tuple<_UElements...>>::value,
636 _Elements...>;
637
638 template<typename... _UElements, typename
639 enable_if<
640 _TMC<_UElements...>::template
641 _MoveConstructibleTuple<_UElements...>()
642 && _TMC<_UElements...>::template
643 _ImplicitlyMoveConvertibleTuple<_UElements...>()
644 && (sizeof...(_Elements) >= 1),
645 bool>::type=true>
646 constexpr tuple(_UElements&&... __elements)
647 : _Inherited(std::forward<_UElements>(__elements)...) { }
648
649 template<typename... _UElements, typename
650 enable_if<
651 _TMC<_UElements...>::template
652 _MoveConstructibleTuple<_UElements...>()
653 && !_TMC<_UElements...>::template
654 _ImplicitlyMoveConvertibleTuple<_UElements...>()
655 && (sizeof...(_Elements) >= 1),
656 bool>::type=false>
657 explicit constexpr tuple(_UElements&&... __elements)
658 : _Inherited(std::forward<_UElements>(__elements)...) { }
659
660 constexpr tuple(const tuple&) = default;
661
662 constexpr tuple(tuple&&) = default;
663
664 // Shortcut for the cases where constructors taking tuples
665 // must avoid creating temporaries.
666 template<typename _Dummy> using _TNTC =
667 _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
668 _Elements...>;
669
670 template<typename... _UElements, typename _Dummy = void, typename
671 enable_if<_TMCT<_UElements...>::template
672 _ConstructibleTuple<_UElements...>()
673 && _TMCT<_UElements...>::template
674 _ImplicitlyConvertibleTuple<_UElements...>()
675 && _TNTC<_Dummy>::template
676 _NonNestedTuple<const tuple<_UElements...>&>(),
677 bool>::type=true>
678 constexpr tuple(const tuple<_UElements...>& __in)
679 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
680 { }
681
682 template<typename... _UElements, typename _Dummy = void, typename
683 enable_if<_TMCT<_UElements...>::template
684 _ConstructibleTuple<_UElements...>()
685 && !_TMCT<_UElements...>::template
686 _ImplicitlyConvertibleTuple<_UElements...>()
687 && _TNTC<_Dummy>::template
688 _NonNestedTuple<const tuple<_UElements...>&>(),
689 bool>::type=false>
690 explicit constexpr tuple(const tuple<_UElements...>& __in)
691 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
692 { }
693
694 template<typename... _UElements, typename _Dummy = void, typename
695 enable_if<_TMCT<_UElements...>::template
696 _MoveConstructibleTuple<_UElements...>()
697 && _TMCT<_UElements...>::template
698 _ImplicitlyMoveConvertibleTuple<_UElements...>()
699 && _TNTC<_Dummy>::template
700 _NonNestedTuple<tuple<_UElements...>&&>(),
701 bool>::type=true>
702 constexpr tuple(tuple<_UElements...>&& __in)
703 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
704
705 template<typename... _UElements, typename _Dummy = void, typename
706 enable_if<_TMCT<_UElements...>::template
707 _MoveConstructibleTuple<_UElements...>()
708 && !_TMCT<_UElements...>::template
709 _ImplicitlyMoveConvertibleTuple<_UElements...>()
710 && _TNTC<_Dummy>::template
711 _NonNestedTuple<tuple<_UElements...>&&>(),
712 bool>::type=false>
713 explicit constexpr tuple(tuple<_UElements...>&& __in)
714 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
715
716 // Allocator-extended constructors.
717
718 template<typename _Alloc>
719 tuple(allocator_arg_t __tag, const _Alloc& __a)
720 : _Inherited(__tag, __a) { }
721
722 template<typename _Alloc, typename _Dummy = void,
723 typename enable_if<
724 _TCC<_Dummy>::template
725 _ConstructibleTuple<_Elements...>()
726 && _TCC<_Dummy>::template
727 _ImplicitlyConvertibleTuple<_Elements...>(),
728 bool>::type=true>
729 tuple(allocator_arg_t __tag, const _Alloc& __a,
730 const _Elements&... __elements)
731 : _Inherited(__tag, __a, __elements...) { }
732
733 template<typename _Alloc, typename _Dummy = void,
734 typename enable_if<
735 _TCC<_Dummy>::template
736 _ConstructibleTuple<_Elements...>()
737 && !_TCC<_Dummy>::template
738 _ImplicitlyConvertibleTuple<_Elements...>(),
739 bool>::type=false>
740 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
741 const _Elements&... __elements)
742 : _Inherited(__tag, __a, __elements...) { }
743
744 template<typename _Alloc, typename... _UElements, typename
745 enable_if<_TMC<_UElements...>::template
746 _MoveConstructibleTuple<_UElements...>()
747 && _TMC<_UElements...>::template
748 _ImplicitlyMoveConvertibleTuple<_UElements...>(),
749 bool>::type=true>
750 tuple(allocator_arg_t __tag, const _Alloc& __a,
751 _UElements&&... __elements)
752 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
753 { }
754
755 template<typename _Alloc, typename... _UElements, typename
756 enable_if<_TMC<_UElements...>::template
757 _MoveConstructibleTuple<_UElements...>()
758 && !_TMC<_UElements...>::template
759 _ImplicitlyMoveConvertibleTuple<_UElements...>(),
760 bool>::type=false>
761 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
762 _UElements&&... __elements)
763 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
764 { }
765
766 template<typename _Alloc>
767 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
768 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
769
770 template<typename _Alloc>
771 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
772 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
773
774 template<typename _Alloc, typename _Dummy = void,
775 typename... _UElements, typename
776 enable_if<_TMCT<_UElements...>::template
777 _ConstructibleTuple<_UElements...>()
778 && _TMCT<_UElements...>::template
779 _ImplicitlyConvertibleTuple<_UElements...>()
780 && _TNTC<_Dummy>::template
781 _NonNestedTuple<tuple<_UElements...>&&>(),
782 bool>::type=true>
783 tuple(allocator_arg_t __tag, const _Alloc& __a,
784 const tuple<_UElements...>& __in)
785 : _Inherited(__tag, __a,
786 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
787 { }
788
789 template<typename _Alloc, typename _Dummy = void,
790 typename... _UElements, typename
791 enable_if<_TMCT<_UElements...>::template
792 _ConstructibleTuple<_UElements...>()
793 && !_TMCT<_UElements...>::template
794 _ImplicitlyConvertibleTuple<_UElements...>()
795 && _TNTC<_Dummy>::template
796 _NonNestedTuple<tuple<_UElements...>&&>(),
797 bool>::type=false>
798 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
799 const tuple<_UElements...>& __in)
800 : _Inherited(__tag, __a,
801 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
802 { }
803
804 template<typename _Alloc, typename _Dummy = void,
805 typename... _UElements, typename
806 enable_if<_TMCT<_UElements...>::template
807 _MoveConstructibleTuple<_UElements...>()
808 && _TMCT<_UElements...>::template
809 _ImplicitlyMoveConvertibleTuple<_UElements...>()
810 && _TNTC<_Dummy>::template
811 _NonNestedTuple<tuple<_UElements...>&&>(),
812 bool>::type=true>
813 tuple(allocator_arg_t __tag, const _Alloc& __a,
814 tuple<_UElements...>&& __in)
815 : _Inherited(__tag, __a,
816 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
817 { }
818
819 template<typename _Alloc, typename _Dummy = void,
820 typename... _UElements, typename
821 enable_if<_TMCT<_UElements...>::template
822 _MoveConstructibleTuple<_UElements...>()
823 && !_TMCT<_UElements...>::template
824 _ImplicitlyMoveConvertibleTuple<_UElements...>()
825 && _TNTC<_Dummy>::template
826 _NonNestedTuple<tuple<_UElements...>&&>(),
827 bool>::type=false>
828 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
829 tuple<_UElements...>&& __in)
830 : _Inherited(__tag, __a,
831 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
832 { }
833
834 tuple&
835 operator=(const tuple& __in)
836 {
837 static_cast<_Inherited&>(*this) = __in;
838 return *this;
839 }
840
841 tuple&
842 operator=(tuple&& __in)
843 noexcept(is_nothrow_move_assignable<_Inherited>::value)
844 {
845 static_cast<_Inherited&>(*this) = std::move(__in);
846 return *this;
847 }
848
849 template<typename... _UElements>
850 typename
851 enable_if<sizeof...(_UElements)
852 == sizeof...(_Elements), tuple&>::type
853 operator=(const tuple<_UElements...>& __in)
854 {
855 static_cast<_Inherited&>(*this) = __in;
856 return *this;
857 }
858
859 template<typename... _UElements>
860 typename
861 enable_if<sizeof...(_UElements)
862 == sizeof...(_Elements), tuple&>::type
863 operator=(tuple<_UElements...>&& __in)
864 {
865 static_cast<_Inherited&>(*this) = std::move(__in);
866 return *this;
867 }
868
869 void
870 swap(tuple& __in)
871 noexcept(noexcept(__in._M_swap(__in)))
872 { _Inherited::_M_swap(__in); }
873 };
874
875#if __cpp_deduction_guides >= 201606
876 template<typename... _UTypes>
877 tuple(_UTypes...) -> tuple<_UTypes...>;
878 template<typename _T1, typename _T2>
879 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
880 template<typename _Alloc, typename... _UTypes>
881 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
882 template<typename _Alloc, typename _T1, typename _T2>
883 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
884 template<typename _Alloc, typename... _UTypes>
885 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
886#endif
887
888 // Explicit specialization, zero-element tuple.
889 template<>
890 class tuple<>
891 {
892 public:
893 void swap(tuple&) noexcept { /* no-op */ }
894 // We need the default since we're going to define no-op
895 // allocator constructors.
896 tuple() = default;
897 // No-op allocator constructors.
898 template<typename _Alloc>
899 tuple(allocator_arg_t, const _Alloc&) { }
900 template<typename _Alloc>
901 tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
902 };
903
904 /// Partial specialization, 2-element tuple.
905 /// Includes construction and assignment from a pair.
906 template<typename _T1, typename _T2>
907 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
908 {
909 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
910
911 public:
912 template <typename _U1 = _T1,
913 typename _U2 = _T2,
914 typename enable_if<__and_<
915 __is_implicitly_default_constructible<_U1>,
916 __is_implicitly_default_constructible<_U2>>
917 ::value, bool>::type = true>
918
919 constexpr tuple()
920 : _Inherited() { }
921
922 template <typename _U1 = _T1,
923 typename _U2 = _T2,
924 typename enable_if<
925 __and_<
926 is_default_constructible<_U1>,
927 is_default_constructible<_U2>,
928 __not_<
929 __and_<__is_implicitly_default_constructible<_U1>,
930 __is_implicitly_default_constructible<_U2>>>>
931 ::value, bool>::type = false>
932
933 explicit constexpr tuple()
934 : _Inherited() { }
935
936 // Shortcut for the cases where constructors taking _T1, _T2
937 // need to be constrained.
938 template<typename _Dummy> using _TCC =
939 _TC<is_same<_Dummy, void>::value, _T1, _T2>;
940
941 template<typename _Dummy = void, typename
942 enable_if<_TCC<_Dummy>::template
943 _ConstructibleTuple<_T1, _T2>()
944 && _TCC<_Dummy>::template
945 _ImplicitlyConvertibleTuple<_T1, _T2>(),
946 bool>::type = true>
947 constexpr tuple(const _T1& __a1, const _T2& __a2)
948 : _Inherited(__a1, __a2) { }
949
950 template<typename _Dummy = void, typename
951 enable_if<_TCC<_Dummy>::template
952 _ConstructibleTuple<_T1, _T2>()
953 && !_TCC<_Dummy>::template
954 _ImplicitlyConvertibleTuple<_T1, _T2>(),
955 bool>::type = false>
956 explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
957 : _Inherited(__a1, __a2) { }
958
959 // Shortcut for the cases where constructors taking _U1, _U2
960 // need to be constrained.
961 using _TMC = _TC<true, _T1, _T2>;
962
963 template<typename _U1, typename _U2, typename
964 enable_if<_TMC::template
965 _MoveConstructibleTuple<_U1, _U2>()
966 && _TMC::template
967 _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
968 && !is_same<typename decay<_U1>::type,
969 allocator_arg_t>::value,
970 bool>::type = true>
971 constexpr tuple(_U1&& __a1, _U2&& __a2)
972 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
117
Calling 'forward'
118
Returning from 'forward'
119
Calling 'forward'
120
Returning from 'forward'
121
Calling constructor for '_Tuple_impl'
138
Returning from constructor for '_Tuple_impl'
973
974 template<typename _U1, typename _U2, typename
975 enable_if<_TMC::template
976 _MoveConstructibleTuple<_U1, _U2>()
977 && !_TMC::template
978 _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
979 && !is_same<typename decay<_U1>::type,
980 allocator_arg_t>::value,
981 bool>::type = false>
982 explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
983 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
984
985 constexpr tuple(const tuple&) = default;
986
987 constexpr tuple(tuple&&) = default;
988
989 template<typename _U1, typename _U2, typename
990 enable_if<_TMC::template
991 _ConstructibleTuple<_U1, _U2>()
992 && _TMC::template
993 _ImplicitlyConvertibleTuple<_U1, _U2>(),
994 bool>::type = true>
995 constexpr tuple(const tuple<_U1, _U2>& __in)
996 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
997
998 template<typename _U1, typename _U2, typename
999 enable_if<_TMC::template
1000 _ConstructibleTuple<_U1, _U2>()
1001 && !_TMC::template
1002 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1003 bool>::type = false>
1004 explicit constexpr tuple(const tuple<_U1, _U2>& __in)
1005 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1006
1007 template<typename _U1, typename _U2, typename
1008 enable_if<_TMC::template
1009 _MoveConstructibleTuple<_U1, _U2>()
1010 && _TMC::template
1011 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1012 bool>::type = true>
1013 constexpr tuple(tuple<_U1, _U2>&& __in)
1014 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1015
1016 template<typename _U1, typename _U2, typename
1017 enable_if<_TMC::template
1018 _MoveConstructibleTuple<_U1, _U2>()
1019 && !_TMC::template
1020 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1021 bool>::type = false>
1022 explicit constexpr tuple(tuple<_U1, _U2>&& __in)
1023 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1024
1025 template<typename _U1, typename _U2, typename
1026 enable_if<_TMC::template
1027 _ConstructibleTuple<_U1, _U2>()
1028 && _TMC::template
1029 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1030 bool>::type = true>
1031 constexpr tuple(const pair<_U1, _U2>& __in)
1032 : _Inherited(__in.first, __in.second) { }
1033
1034 template<typename _U1, typename _U2, typename
1035 enable_if<_TMC::template
1036 _ConstructibleTuple<_U1, _U2>()
1037 && !_TMC::template
1038 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1039 bool>::type = false>
1040 explicit constexpr tuple(const pair<_U1, _U2>& __in)
1041 : _Inherited(__in.first, __in.second) { }
1042
1043 template<typename _U1, typename _U2, typename
1044 enable_if<_TMC::template
1045 _MoveConstructibleTuple<_U1, _U2>()
1046 && _TMC::template
1047 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1048 bool>::type = true>
1049 constexpr tuple(pair<_U1, _U2>&& __in)
1050 : _Inherited(std::forward<_U1>(__in.first),
1051 std::forward<_U2>(__in.second)) { }
1052
1053 template<typename _U1, typename _U2, typename
1054 enable_if<_TMC::template
1055 _MoveConstructibleTuple<_U1, _U2>()
1056 && !_TMC::template
1057 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1058 bool>::type = false>
1059 explicit constexpr tuple(pair<_U1, _U2>&& __in)
1060 : _Inherited(std::forward<_U1>(__in.first),
1061 std::forward<_U2>(__in.second)) { }
1062
1063 // Allocator-extended constructors.
1064
1065 template<typename _Alloc>
1066 tuple(allocator_arg_t __tag, const _Alloc& __a)
1067 : _Inherited(__tag, __a) { }
1068
1069 template<typename _Alloc, typename _Dummy = void,
1070 typename enable_if<
1071 _TCC<_Dummy>::template
1072 _ConstructibleTuple<_T1, _T2>()
1073 && _TCC<_Dummy>::template
1074 _ImplicitlyConvertibleTuple<_T1, _T2>(),
1075 bool>::type=true>
1076
1077 tuple(allocator_arg_t __tag, const _Alloc& __a,
1078 const _T1& __a1, const _T2& __a2)
1079 : _Inherited(__tag, __a, __a1, __a2) { }
1080
1081 template<typename _Alloc, typename _Dummy = void,
1082 typename enable_if<
1083 _TCC<_Dummy>::template
1084 _ConstructibleTuple<_T1, _T2>()
1085 && !_TCC<_Dummy>::template
1086 _ImplicitlyConvertibleTuple<_T1, _T2>(),
1087 bool>::type=false>
1088
1089 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1090 const _T1& __a1, const _T2& __a2)
1091 : _Inherited(__tag, __a, __a1, __a2) { }
1092
1093 template<typename _Alloc, typename _U1, typename _U2, typename
1094 enable_if<_TMC::template
1095 _MoveConstructibleTuple<_U1, _U2>()
1096 && _TMC::template
1097 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1098 bool>::type = true>
1099 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1100 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1101 std::forward<_U2>(__a2)) { }
1102
1103 template<typename _Alloc, typename _U1, typename _U2, typename
1104 enable_if<_TMC::template
1105 _MoveConstructibleTuple<_U1, _U2>()
1106 && !_TMC::template
1107 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1108 bool>::type = false>
1109 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1110 _U1&& __a1, _U2&& __a2)
1111 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1112 std::forward<_U2>(__a2)) { }
1113
1114 template<typename _Alloc>
1115 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1116 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1117
1118 template<typename _Alloc>
1119 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1120 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1121
1122 template<typename _Alloc, typename _U1, typename _U2, typename
1123 enable_if<_TMC::template
1124 _ConstructibleTuple<_U1, _U2>()
1125 && _TMC::template
1126 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1127 bool>::type = true>
1128 tuple(allocator_arg_t __tag, const _Alloc& __a,
1129 const tuple<_U1, _U2>& __in)
1130 : _Inherited(__tag, __a,
1131 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1132 { }
1133
1134 template<typename _Alloc, typename _U1, typename _U2, typename
1135 enable_if<_TMC::template
1136 _ConstructibleTuple<_U1, _U2>()
1137 && !_TMC::template
1138 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1139 bool>::type = false>
1140 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1141 const tuple<_U1, _U2>& __in)
1142 : _Inherited(__tag, __a,
1143 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1144 { }
1145
1146 template<typename _Alloc, typename _U1, typename _U2, typename
1147 enable_if<_TMC::template
1148 _MoveConstructibleTuple<_U1, _U2>()
1149 && _TMC::template
1150 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1151 bool>::type = true>
1152 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1153 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1154 { }
1155
1156 template<typename _Alloc, typename _U1, typename _U2, typename
1157 enable_if<_TMC::template
1158 _MoveConstructibleTuple<_U1, _U2>()
1159 && !_TMC::template
1160 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1161 bool>::type = false>
1162 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1163 tuple<_U1, _U2>&& __in)
1164 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1165 { }
1166
1167 template<typename _Alloc, typename _U1, typename _U2, typename
1168 enable_if<_TMC::template
1169 _ConstructibleTuple<_U1, _U2>()
1170 && _TMC::template
1171 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1172 bool>::type = true>
1173 tuple(allocator_arg_t __tag, const _Alloc& __a,
1174 const pair<_U1, _U2>& __in)
1175 : _Inherited(__tag, __a, __in.first, __in.second) { }
1176
1177 template<typename _Alloc, typename _U1, typename _U2, typename
1178 enable_if<_TMC::template
1179 _ConstructibleTuple<_U1, _U2>()
1180 && !_TMC::template
1181 _ImplicitlyConvertibleTuple<_U1, _U2>(),
1182 bool>::type = false>
1183 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1184 const pair<_U1, _U2>& __in)
1185 : _Inherited(__tag, __a, __in.first, __in.second) { }
1186
1187 template<typename _Alloc, typename _U1, typename _U2, typename
1188 enable_if<_TMC::template
1189 _MoveConstructibleTuple<_U1, _U2>()
1190 && _TMC::template
1191 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1192 bool>::type = true>
1193 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1194 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1195 std::forward<_U2>(__in.second)) { }
1196
1197 template<typename _Alloc, typename _U1, typename _U2, typename
1198 enable_if<_TMC::template
1199 _MoveConstructibleTuple<_U1, _U2>()
1200 && !_TMC::template
1201 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1202 bool>::type = false>
1203 explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1204 pair<_U1, _U2>&& __in)
1205 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1206 std::forward<_U2>(__in.second)) { }
1207
1208 tuple&
1209 operator=(const tuple& __in)
1210 {
1211 static_cast<_Inherited&>(*this) = __in;
1212 return *this;
1213 }
1214
1215 tuple&
1216 operator=(tuple&& __in)
1217 noexcept(is_nothrow_move_assignable<_Inherited>::value)
1218 {
1219 static_cast<_Inherited&>(*this) = std::move(__in);
1220 return *this;
1221 }
1222
1223 template<typename _U1, typename _U2>
1224 tuple&
1225 operator=(const tuple<_U1, _U2>& __in)
1226 {
1227 static_cast<_Inherited&>(*this) = __in;
1228 return *this;
1229 }
1230
1231 template<typename _U1, typename _U2>
1232 tuple&
1233 operator=(tuple<_U1, _U2>&& __in)
1234 {
1235 static_cast<_Inherited&>(*this) = std::move(__in);
1236 return *this;
1237 }
1238
1239 template<typename _U1, typename _U2>
1240 tuple&
1241 operator=(const pair<_U1, _U2>& __in)
1242 {
1243 this->_M_head(*this) = __in.first;
1244 this->_M_tail(*this)._M_head(*this) = __in.second;
1245 return *this;
1246 }
1247
1248 template<typename _U1, typename _U2>
1249 tuple&
1250 operator=(pair<_U1, _U2>&& __in)
1251 {
1252 this->_M_head(*this) = std::forward<_U1>(__in.first);
1253 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1254 return *this;
1255 }
1256
1257 void
1258 swap(tuple& __in)
1259 noexcept(noexcept(__in._M_swap(__in)))
1260 { _Inherited::_M_swap(__in); }
1261 };
1262
1263
1264 /// class tuple_size
1265 template<typename... _Elements>
1266 struct tuple_size<tuple<_Elements...>>
1267 : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1268
1269#if __cplusplus201103L > 201402L
1270 template <typename _Tp>
1271 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1272#endif
1273
1274 /**
1275 * Recursive case for tuple_element: strip off the first element in
1276 * the tuple and retrieve the (i-1)th element of the remaining tuple.
1277 */
1278 template<std::size_t __i, typename _Head, typename... _Tail>
1279 struct tuple_element<__i, tuple<_Head, _Tail...> >
1280 : tuple_element<__i - 1, tuple<_Tail...> > { };
1281
1282 /**
1283 * Basis case for tuple_element: The first element is the one we're seeking.
1284 */
1285 template<typename _Head, typename... _Tail>
1286 struct tuple_element<0, tuple<_Head, _Tail...> >
1287 {
1288 typedef _Head type;
1289 };
1290
1291 /**
1292 * Error case for tuple_element: invalid index.
1293 */
1294 template<size_t __i>
1295 struct tuple_element<__i, tuple<>>
1296 {
1297 static_assert(__i < tuple_size<tuple<>>::value,
1298 "tuple index is in range");
1299 };
1300
1301 template<std::size_t __i, typename _Head, typename... _Tail>
1302 constexpr _Head&
1303 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1304 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
91
Calling '_Tuple_impl::_M_head'
94
Returning from '_Tuple_impl::_M_head'
103
Calling '_Tuple_impl::_M_head'
106
Returning from '_Tuple_impl::_M_head'
1305
1306 template<std::size_t __i, typename _Head, typename... _Tail>
1307 constexpr const _Head&
1308 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1309 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
80
Calling '_Tuple_impl::_M_head'
83
Returning from '_Tuple_impl::_M_head'
1310
1311 /// Return a reference to the ith element of a tuple.
1312 template<std::size_t __i, typename... _Elements>
1313 constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1314 get(tuple<_Elements...>& __t) noexcept
1315 { return std::__get_helper<__i>(__t); }
90
Calling '__get_helper'
95
Returning from '__get_helper'
102
Calling '__get_helper'
107
Returning from '__get_helper'
1316
1317 /// Return a const reference to the ith element of a const tuple.
1318 template<std::size_t __i, typename... _Elements>
1319 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1320 get(const tuple<_Elements...>& __t) noexcept
1321 { return std::__get_helper<__i>(__t); }
79
Calling '__get_helper'
84
Returning from '__get_helper'
1322
1323 /// Return an rvalue reference to the ith element of a tuple rvalue.
1324 template<std::size_t __i, typename... _Elements>
1325 constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1326 get(tuple<_Elements...>&& __t) noexcept
1327 {
1328 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1329 return std::forward<__element_type&&>(std::get<__i>(__t));
1330 }
1331
1332#if __cplusplus201103L > 201103L
1333
1334#define __cpp_lib_tuples_by_type 201304
1335
1336 template<typename _Head, size_t __i, typename... _Tail>
1337 constexpr _Head&
1338 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1339 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1340
1341 template<typename _Head, size_t __i, typename... _Tail>
1342 constexpr const _Head&
1343 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1344 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1345
1346 /// Return a reference to the unique element of type _Tp of a tuple.
1347 template <typename _Tp, typename... _Types>
1348 constexpr _Tp&
1349 get(tuple<_Types...>& __t) noexcept
1350 { return std::__get_helper2<_Tp>(__t); }
1351
1352 /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1353 template <typename _Tp, typename... _Types>
1354 constexpr _Tp&&
1355 get(tuple<_Types...>&& __t) noexcept
1356 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1357
1358 /// Return a const reference to the unique element of type _Tp of a tuple.
1359 template <typename _Tp, typename... _Types>
1360 constexpr const _Tp&
1361 get(const tuple<_Types...>& __t) noexcept
1362 { return std::__get_helper2<_Tp>(__t); }
1363#endif
1364
1365 // This class performs the comparison operations on tuples
1366 template<typename _Tp, typename _Up, size_t __i, size_t __size>
1367 struct __tuple_compare
1368 {
1369 static constexpr bool
1370 __eq(const _Tp& __t, const _Up& __u)
1371 {
1372 return bool(std::get<__i>(__t) == std::get<__i>(__u))
1373 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1374 }
1375
1376 static constexpr bool
1377 __less(const _Tp& __t, const _Up& __u)
1378 {
1379 return bool(std::get<__i>(__t) < std::get<__i>(__u))
1380 || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1381 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1382 }
1383 };
1384
1385 template<typename _Tp, typename _Up, size_t __size>
1386 struct __tuple_compare<_Tp, _Up, __size, __size>
1387 {
1388 static constexpr bool
1389 __eq(const _Tp&, const _Up&) { return true; }
1390
1391 static constexpr bool
1392 __less(const _Tp&, const _Up&) { return false; }
1393 };
1394
1395 template<typename... _TElements, typename... _UElements>
1396 constexpr bool
1397 operator==(const tuple<_TElements...>& __t,
1398 const tuple<_UElements...>& __u)
1399 {
1400 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1401 "tuple objects can only be compared if they have equal sizes.");
1402 using __compare = __tuple_compare<tuple<_TElements...>,
1403 tuple<_UElements...>,
1404 0, sizeof...(_TElements)>;
1405 return __compare::__eq(__t, __u);
1406 }
1407
1408 template<typename... _TElements, typename... _UElements>
1409 constexpr bool
1410 operator<(const tuple<_TElements...>& __t,
1411 const tuple<_UElements...>& __u)
1412 {
1413 static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1414 "tuple objects can only be compared if they have equal sizes.");
1415 using __compare = __tuple_compare<tuple<_TElements...>,
1416 tuple<_UElements...>,
1417 0, sizeof...(_TElements)>;
1418 return __compare::__less(__t, __u);
1419 }
1420
1421 template<typename... _TElements, typename... _UElements>
1422 constexpr bool
1423 operator!=(const tuple<_TElements...>& __t,
1424 const tuple<_UElements...>& __u)
1425 { return !(__t == __u); }
1426
1427 template<typename... _TElements, typename... _UElements>
1428 constexpr bool
1429 operator>(const tuple<_TElements...>& __t,
1430 const tuple<_UElements...>& __u)
1431 { return __u < __t; }
1432
1433 template<typename... _TElements, typename... _UElements>
1434 constexpr bool
1435 operator<=(const tuple<_TElements...>& __t,
1436 const tuple<_UElements...>& __u)
1437 { return !(__u < __t); }
1438
1439 template<typename... _TElements, typename... _UElements>
1440 constexpr bool
1441 operator>=(const tuple<_TElements...>& __t,
1442 const tuple<_UElements...>& __u)
1443 { return !(__t < __u); }
1444
1445 // NB: DR 705.
1446 template<typename... _Elements>
1447 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1448 make_tuple(_Elements&&... __args)
1449 {
1450 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1451 __result_type;
1452 return __result_type(std::forward<_Elements>(__args)...);
1453 }
1454
1455 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1456 // 2275. Why is forward_as_tuple not constexpr?
1457 template<typename... _Elements>
1458 constexpr tuple<_Elements&&...>
1459 forward_as_tuple(_Elements&&... __args) noexcept
1460 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1461
1462 template<size_t, typename, typename, size_t>
1463 struct __make_tuple_impl;
1464
1465 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1466 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1467 : __make_tuple_impl<_Idx + 1,
1468 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1469 _Tuple, _Nm>
1470 { };
1471
1472 template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1473 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1474 {
1475 typedef tuple<_Tp...> __type;
1476 };
1477
1478 template<typename _Tuple>
1479 struct __do_make_tuple
1480 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1481 { };
1482
1483 // Returns the std::tuple equivalent of a tuple-like type.
1484 template<typename _Tuple>
1485 struct __make_tuple
1486 : public __do_make_tuple<typename std::remove_cv
1487 <typename std::remove_reference<_Tuple>::type>::type>
1488 { };
1489
1490 // Combines several std::tuple's into a single one.
1491 template<typename...>
1492 struct __combine_tuples;
1493
1494 template<>
1495 struct __combine_tuples<>
1496 {
1497 typedef tuple<> __type;
1498 };
1499
1500 template<typename... _Ts>
1501 struct __combine_tuples<tuple<_Ts...>>
1502 {
1503 typedef tuple<_Ts...> __type;
1504 };
1505
1506 template<typename... _T1s, typename... _T2s, typename... _Rem>
1507 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1508 {
1509 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1510 _Rem...>::__type __type;
1511 };
1512
1513 // Computes the result type of tuple_cat given a set of tuple-like types.
1514 template<typename... _Tpls>
1515 struct __tuple_cat_result
1516 {
1517 typedef typename __combine_tuples
1518 <typename __make_tuple<_Tpls>::__type...>::__type __type;
1519 };
1520
1521 // Helper to determine the index set for the first tuple-like
1522 // type of a given set.
1523 template<typename...>
1524 struct __make_1st_indices;
1525
1526 template<>
1527 struct __make_1st_indices<>
1528 {
1529 typedef std::_Index_tuple<> __type;
1530 };
1531
1532 template<typename _Tp, typename... _Tpls>
1533 struct __make_1st_indices<_Tp, _Tpls...>
1534 {
1535 typedef typename std::_Build_index_tuple<std::tuple_size<
1536 typename std::remove_reference<_Tp>::type>::value>::__type __type;
1537 };
1538
1539 // Performs the actual concatenation by step-wise expanding tuple-like
1540 // objects into the elements, which are finally forwarded into the
1541 // result tuple.
1542 template<typename _Ret, typename _Indices, typename... _Tpls>
1543 struct __tuple_concater;
1544
1545 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1546 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1547 {
1548 template<typename... _Us>
1549 static constexpr _Ret
1550 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1551 {
1552 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1553 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1554 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1555 std::forward<_Us>(__us)...,
1556 std::get<_Is>(std::forward<_Tp>(__tp))...);
1557 }
1558 };
1559
1560 template<typename _Ret>
1561 struct __tuple_concater<_Ret, std::_Index_tuple<>>
1562 {
1563 template<typename... _Us>
1564 static constexpr _Ret
1565 _S_do(_Us&&... __us)
1566 {
1567 return _Ret(std::forward<_Us>(__us)...);
1568 }
1569 };
1570
1571 /// tuple_cat
1572 template<typename... _Tpls, typename = typename
1573 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1574 constexpr auto
1575 tuple_cat(_Tpls&&... __tpls)
1576 -> typename __tuple_cat_result<_Tpls...>::__type
1577 {
1578 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1579 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1580 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1581 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1582 }
1583
1584 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1585 // 2301. Why is tie not constexpr?
1586 /// tie
1587 template<typename... _Elements>
1588 constexpr tuple<_Elements&...>
1589 tie(_Elements&... __args) noexcept
1590 { return tuple<_Elements&...>(__args...); }
1591
1592 /// swap
1593 template<typename... _Elements>
1594 inline
1595#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1596 // Constrained free swap overload, see p0185r1
1597 typename enable_if<__and_<__is_swappable<_Elements>...>::value
1598 >::type
1599#else
1600 void
1601#endif
1602 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1603 noexcept(noexcept(__x.swap(__y)))
1604 { __x.swap(__y); }
1605
1606#if __cplusplus201103L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11
1607 template<typename... _Elements>
1608 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1609 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1610#endif
1611
1612 // A class (and instance) which can be used in 'tie' when an element
1613 // of a tuple is not required.
1614 // _GLIBCXX14_CONSTEXPR
1615 // 2933. PR for LWG 2773 could be clearer
1616 struct _Swallow_assign
1617 {
1618 template<class _Tp>
1619 _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1620 operator=(const _Tp&) const
1621 { return *this; }
1622 };
1623
1624 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1625 // 2773. Making std::ignore constexpr
1626 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1627
1628 /// Partial specialization for tuples
1629 template<typename... _Types, typename _Alloc>
1630 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1631
1632 // See stl_pair.h...
1633 template<class _T1, class _T2>
1634 template<typename... _Args1, typename... _Args2>
1635 inline
1636 pair<_T1, _T2>::
1637 pair(piecewise_construct_t,
1638 tuple<_Args1...> __first, tuple<_Args2...> __second)
1639 : pair(__first, __second,
1640 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),