Bug Summary

File:rootdir/src/amuleDlg.cpp
Warning:line 323, column 3
Access of the field 'm_networkpages' at index 2, while it holds only 2 'struct PageType' elements

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name amuleDlg.cpp -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 -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -D USE_WX_EXTENSIONS -I /usr/include/upnp -D ENABLE_UPNP=1 -I /usr/lib/x86_64-linux-gnu/wx/include/gtk3-unicode-3.2 -I /usr/include/wx-3.2 -D _FILE_OFFSET_BITS=64 -D WXUSINGDLL -D __WXGTK__ -D ENABLE_IP2COUNTRY=1 -I ./libs -I libs -I ./include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-register -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-01-17-083350-60053-1 -x c++ amuleDlg.cpp

amuleDlg.cpp

1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6//
7// Any parts of this program derived from the xMule, lMule or eMule project,
8// or contributed by third-party developers are copyrighted by their
9// respective authors.
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24//
25
26#include <wx/app.h>
27
28#include <wx/archive.h>
29#include <wx/config.h> // Do_not_auto_remove (MacOS 10.3, wx 2.7)
30#include <wx/confbase.h> // Do_not_auto_remove (MacOS 10.3, wx 2.7)
31#include <wx/html/htmlwin.h>
32#include <wx/mimetype.h> // Do_not_auto_remove (win32)
33#include <wx/stattext.h>
34#include <wx/stdpaths.h>
35#include <wx/textfile.h> // Do_not_auto_remove (win32)
36#include <wx/tokenzr.h>
37#include <wx/wfstream.h>
38#include <wx/zipstrm.h>
39#include <wx/sysopt.h>
40#include <wx/wupdlock.h> // Needed for wxWindowUpdateLocker
41#include <wx/utils.h> // Needed for wxFindWindowAtPoint
42
43#include <common/EventIDs.h>
44
45#include "config.h" // Needed for SVNDATE, PACKAGE, VERSION
46#include "amuleDlg.h" // Interface declarations.
47
48#include <common/Format.h> // Needed for CFormat
49#include "amule.h" // Needed for theApp
50#include "ChatWnd.h" // Needed for CChatWnd
51#include "SourceListCtrl.h" // Needed for CSourceListCtrl
52#include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
53#include "DownloadQueue.h" // Needed for CDownloadQueue
54#include "KadDlg.h" // Needed for CKadDlg
55#include "Logger.h"
56#include "MuleTrayIcon.h"
57#include "muuli_wdr.h" // Needed for ID_BUTTON*
58#include "Preferences.h" // Needed for CPreferences
59#include "PrefsUnifiedDlg.h"
60#include "SearchDlg.h" // Needed for CSearchDlg
61#include "Server.h" // Needed for CServer
62#include "ServerConnect.h" // Needed for CServerConnect
63#include "ServerWnd.h" // Needed for CServerWnd
64#include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
65#include "SharedFilePeersListCtrl.h" // Needed for CSharedFilePeersListCtrl
66#include "Statistics.h" // Needed for theStats
67#include "StatisticsDlg.h" // Needed for CStatisticsDlg
68#include "TerminationProcess.h" // Needed for CTerminationProcess
69#include "TransferWnd.h" // Needed for CTransferWnd
70#ifndef CLIENT_GUI
71#include "PartFileConvertDlg.h"
72#endif
73#include "IPFilter.h"
74
75#ifndef __WINDOWS__
76#include "aMule.xpm"
77#endif
78
79#include "kademlia/kademlia/Kademlia.h"
80#include "MuleVersion.h" // Needed for GetMuleVersion()
81
82#ifdef ENABLE_IP2COUNTRY1
83#include "IP2Country.h" // Needed for IP2Country
84#endif
85
86#ifdef ENABLE_IP2COUNTRY1 // That's no bug. MSVC has ENABLE_IP2COUNTRY always on,
87 // but dummy GeoIP.h turns ENABLE_IP2COUNTRY off again.
88void CamuleDlg::IP2CountryDownloadFinished(uint32 result)
89{
90 m_IP2Country->DownloadFinished(result);
91}
92
93void CamuleDlg::EnableIP2Country()
94{
95 if (thePrefs::IsGeoIPEnabled()) {
96 m_IP2Country->Enable();
97 }
98}
99
100#else
101
102void CamuleDlg::IP2CountryDownloadFinished(uint32){}
103void CamuleDlg::EnableIP2Country(){}
104
105#endif
106
107BEGIN_EVENT_TABLE(CamuleDlg, wxFrame)const wxEventTable CamuleDlg::sm_eventTable = { &wxFrame::
sm_eventTable, &CamuleDlg::sm_eventTableEntries[0] }; const
wxEventTable *CamuleDlg::GetEventTable() const { return &
CamuleDlg::sm_eventTable; } wxEventHashTable CamuleDlg::sm_eventHashTable
(CamuleDlg::sm_eventTable); wxEventHashTable &CamuleDlg::
GetEventHashTable() const { return CamuleDlg::sm_eventHashTable
; } const wxEventTableEntry CamuleDlg::sm_eventTableEntries[]
= {
108
109 EVT_TOOL(ID_BUTTONNETWORKS, CamuleDlg::OnToolBarButton)wxEventTableEntry(wxEVT_MENU, 10334, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnToolBarButton))), __null),
110 EVT_TOOL(ID_BUTTONSEARCH, CamuleDlg::OnToolBarButton)wxEventTableEntry(wxEVT_MENU, 10335, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnToolBarButton))), __null),
111 EVT_TOOL(ID_BUTTONDOWNLOADS, CamuleDlg::OnToolBarButton)wxEventTableEntry(wxEVT_MENU, 10336, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnToolBarButton))), __null),
112 EVT_TOOL(ID_BUTTONSHARED, CamuleDlg::OnToolBarButton)wxEventTableEntry(wxEVT_MENU, 10337, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnToolBarButton))), __null),
113 EVT_TOOL(ID_BUTTONMESSAGES, CamuleDlg::OnToolBarButton)wxEventTableEntry(wxEVT_MENU, 10338, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnToolBarButton))), __null),
114 EVT_TOOL(ID_BUTTONSTATISTICS, CamuleDlg::OnToolBarButton)wxEventTableEntry(wxEVT_MENU, 10339, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnToolBarButton))), __null),
115 EVT_TOOL(ID_ABOUT, CamuleDlg::OnAboutButton)wxEventTableEntry(wxEVT_MENU, 10342, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnAboutButton))), __null),
116
117 EVT_TOOL(ID_BUTTONNEWPREFERENCES, CamuleDlg::OnPrefButton)wxEventTableEntry(wxEVT_MENU, 10340, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnPrefButton))), __null),
118 EVT_TOOL(ID_BUTTONIMPORT, CamuleDlg::OnImportButton)wxEventTableEntry(wxEVT_MENU, 10341, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnImportButton))), __null),
119
120 EVT_TOOL(ID_BUTTONCONNECT, CamuleDlg::OnBnConnect)wxEventTableEntry(wxEVT_MENU, 10333, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnBnConnect))), __null),
121
122 EVT_CLOSE(CamuleDlg::OnClose)wxEventTableEntry(wxEVT_CLOSE_WINDOW, wxID_ANY, wxID_ANY, wxNewEventTableFunctor
(wxEVT_CLOSE_WINDOW, wxEventFunctionCast(wxPrivate::DoCast<
wxPrivate::EventArgOf<wxCloseEventFunction>::type>(&
CamuleDlg::OnClose))), __null),
123 EVT_ICONIZE(CamuleDlg::OnMinimize)wxEventTableEntry(wxEVT_ICONIZE, wxID_ANY, wxID_ANY, wxNewEventTableFunctor
(wxEVT_ICONIZE, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxIconizeEventFunction>::type>(&CamuleDlg
::OnMinimize))), __null),
124
125 EVT_BUTTON(ID_BUTTON_FAST, CamuleDlg::OnBnClickedFast)wxEventTableEntry(wxEVT_BUTTON, 10000, wxID_ANY, wxNewEventTableFunctor
(wxEVT_BUTTON, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnBnClickedFast))), __null),
126
127 EVT_TIMER(ID_GUI_TIMER_EVENT, CamuleDlg::OnGUITimer)wxEventTableEntry(wxEVT_TIMER, ID_GUI_TIMER_EVENT, wxID_ANY, wxNewEventTableFunctor
(wxEVT_TIMER, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxTimerEventFunction>::type>(&CamuleDlg
::OnGUITimer))), __null),
128
129 EVT_SIZE(CamuleDlg::OnMainGUISizeChange)wxEventTableEntry(wxEVT_SIZE, wxID_ANY, wxID_ANY, wxNewEventTableFunctor
(wxEVT_SIZE, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxSizeEventFunction>::type>(&CamuleDlg
::OnMainGUISizeChange))), __null),
130
131 EVT_KEY_UP(CamuleDlg::OnKeyPressed)wxEventTableEntry(wxEVT_KEY_UP, wxID_ANY, wxID_ANY, wxNewEventTableFunctor
(wxEVT_KEY_UP, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCharEventFunction>::type>(&CamuleDlg
::OnKeyPressed))), __null),
132
133 EVT_MENU(wxID_EXIT, CamuleDlg::OnExit)wxEventTableEntry(wxEVT_MENU, wxID_EXIT, wxID_ANY, wxNewEventTableFunctor
(wxEVT_MENU, wxEventFunctionCast(wxPrivate::DoCast<wxPrivate
::EventArgOf<wxCommandEventFunction>::type>(&CamuleDlg
::OnExit))), __null),
134
135END_EVENT_TABLE()wxEventTableEntry(wxEVT_NULL, 0, 0, __null, __null) };
136
137#ifndef wxCLOSE_BOX0x1000
138 #define wxCLOSE_BOX0x1000 0
139#endif
140
141CamuleDlg::CamuleDlg(
142 wxWindow* pParent,
143 const wxString &title,
144 wxPoint where,
145 wxSize dlg_size)
146:
147wxFrame(
148 pParent, -1, title, where, dlg_size,
149 wxCAPTION0x20000000|wxRESIZE_BORDER0x0040|wxSYSTEM_MENU0x0800|wxDIALOG_NO_PARENT0x00000020|
150 wxRESIZE_BORDER0x0040|wxMINIMIZE_BOX0x0400|wxMAXIMIZE_BOX0x0200|wxCLOSE_BOX0x1000,
151 wxT("aMule")L"aMule"),
152m_activewnd(NULL__null),
153m_transferwnd(NULL__null),
154m_serverwnd(NULL__null),
155m_sharedfileswnd(NULL__null),
156m_searchwnd(NULL__null),
157m_chatwnd(NULL__null),
158m_statisticswnd(NULL__null),
159m_kademliawnd(NULL__null),
160m_prefsDialog(NULL__null),
161m_srv_split_pos(0),
162m_imagelist(16,16),
163m_tblist(32,32),
164m_prefsVisible(false),
165m_wndToolbar(NULL__null),
166m_wndTaskbarNotifier(NULL__null),
167m_nActiveDialog(DT_NETWORKS_WND),
168m_is_safe_state(false),
169m_BlinkMessages(false),
170m_CurrentBlinkBitmap(24),
171m_last_iconizing(0),
172m_skinFileName(),
173m_clientSkinNames(CLIENT_SKIN_SIZE)
174{
175 // Initialize skin names
176 m_clientSkinNames[Client_Green_Smiley] = wxT("Transfer")L"Transfer";
177 m_clientSkinNames[Client_Red_Smiley] = wxT("Connecting")L"Connecting";
178 m_clientSkinNames[Client_Yellow_Smiley] = wxT("OnQueue")L"OnQueue";
179 m_clientSkinNames[Client_Grey_Smiley] = wxT("A4AFNoNeededPartsQueueFull")L"A4AFNoNeededPartsQueueFull";
180 m_clientSkinNames[Client_White_Smiley] = wxT("StatusUnknown")L"StatusUnknown";
181 m_clientSkinNames[Client_ExtendedProtocol_Smiley] = wxT("ExtendedProtocol")L"ExtendedProtocol";
182 m_clientSkinNames[Client_SecIdent_Smiley] = wxT("SecIdent")L"SecIdent";
183 m_clientSkinNames[Client_BadGuy_Smiley] = wxT("BadGuy")L"BadGuy";
184 m_clientSkinNames[Client_CreditsGrey_Smiley] = wxT("CreditsGrey")L"CreditsGrey";
185 m_clientSkinNames[Client_CreditsYellow_Smiley] = wxT("CreditsYellow")L"CreditsYellow";
186 m_clientSkinNames[Client_Upload_Smiley] = wxT("Upload")L"Upload";
187 m_clientSkinNames[Client_Friend_Smiley] = wxT("Friend")L"Friend";
188 m_clientSkinNames[Client_eMule_Smiley] = wxT("eMule")L"eMule";
189 m_clientSkinNames[Client_mlDonkey_Smiley] = wxT("mlDonkey")L"mlDonkey";
190 m_clientSkinNames[Client_eDonkeyHybrid_Smiley] = wxT("eDonkeyHybrid")L"eDonkeyHybrid";
191 m_clientSkinNames[Client_aMule_Smiley] = wxT("aMule")L"aMule";
192 m_clientSkinNames[Client_lphant_Smiley] = wxT("lphant")L"lphant";
193 m_clientSkinNames[Client_Shareaza_Smiley] = wxT("Shareaza")L"Shareaza";
194 m_clientSkinNames[Client_xMule_Smiley] = wxT("xMule")L"xMule";
195 m_clientSkinNames[Client_Unknown] = wxT("Unknown")L"Unknown";
196 m_clientSkinNames[Client_InvalidRating_Smiley] = wxT("InvalidRatingOnFile")L"InvalidRatingOnFile";
197 m_clientSkinNames[Client_PoorRating_Smiley] = wxT("PoorRatingOnFile")L"PoorRatingOnFile";
198 m_clientSkinNames[Client_GoodRating_Smiley] = wxT("GoodRatingOnFile")L"GoodRatingOnFile";
199 m_clientSkinNames[Client_FairRating_Smiley] = wxT("FairRatingOnFile")L"FairRatingOnFile";
200 m_clientSkinNames[Client_ExcellentRating_Smiley] = wxT("ExcellentRatingOnFile")L"ExcellentRatingOnFile";
201 m_clientSkinNames[Client_CommentOnly_Smiley] = wxT("CommentOnly")L"CommentOnly";
202 m_clientSkinNames[Client_Encryption_Smiley] = wxT("Encrypted")L"Encrypted";
203
204 // wxWidgets send idle events to ALL WINDOWS by default... *SIGH*
205 wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED);
206 wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED);
207 wxInitAllImageHandlers();
208 Apply_Clients_Skin();
209
210#ifdef __WINDOWS__
211 wxSystemOptions::SetOption(wxT("msw.remap")L"msw.remap", 0);
212#endif
213
214#if !defined(__WXMAC__)
215 // this crashes on Mac with wx 2.9
216 SetIcon(wxICON(aMule)wxIcon( aMule_xpm ));
217#endif
218
219 srand(time(NULL__null));
220
221 // Create new sizer and stuff a wxPanel in there.
222 wxFlexGridSizer *s_main = new wxFlexGridSizer(1);
223 s_main->AddGrowableCol(0);
224 s_main->AddGrowableRow(0);
225
226 wxPanel* p_cnt = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize);
227 s_main->Add(p_cnt, 0, wxGROW|wxEXPAND, 0);
228 muleDlg(p_cnt, false, true);
229 SetSizer(s_main, true);
230
231 m_serverwnd = new CServerWnd(p_cnt, m_srv_split_pos);
232 AddLogLineN(wxEmptyString)theLogger.AddLogLine(L"amuleDlg.cpp", 232, false, logStandard
, wxEmptyString)
;
233 AddLogLineN(wxT(" - ") +theLogger.AddLogLine(L"amuleDlg.cpp", 234, false, logStandard
, L" - " + CFormat(wxGetTranslation(("This is aMule %s based on eMule."
))) % GetMuleVersion())
234 CFormat(_("This is aMule %s based on eMule.")) % GetMuleVersion())theLogger.AddLogLine(L"amuleDlg.cpp", 234, false, logStandard
, L" - " + CFormat(wxGetTranslation(("This is aMule %s based on eMule."
))) % GetMuleVersion())
;
235 AddLogLineN(wxT(" ") +theLogger.AddLogLine(L"amuleDlg.cpp", 236, false, logStandard
, L" " + CFormat(wxGetTranslation(("Running on %s"))) % wxGetOsDescription
())
236 CFormat(_("Running on %s")) % wxGetOsDescription())theLogger.AddLogLine(L"amuleDlg.cpp", 236, false, logStandard
, L" " + CFormat(wxGetTranslation(("Running on %s"))) % wxGetOsDescription
())
;
237 AddLogLineN(wxT(" - ") +theLogger.AddLogLine(L"amuleDlg.cpp", 238, false, logStandard
, L" - " + wxString(wxGetTranslation(("Visit http://www.amule.org to check if a new version is available."
))))
238 wxString(_("Visit http://www.amule.org to check if a new version is available.")))theLogger.AddLogLine(L"amuleDlg.cpp", 238, false, logStandard
, L" - " + wxString(wxGetTranslation(("Visit http://www.amule.org to check if a new version is available."
))))
;
239 AddLogLineN(wxEmptyString)theLogger.AddLogLine(L"amuleDlg.cpp", 239, false, logStandard
, wxEmptyString)
;
240
241#ifdef ENABLE_IP2COUNTRY1
242 m_GeoIPavailable = true;
243 m_IP2Country = new CIP2Country(thePrefs::GetConfigDir());
244#else
245 m_GeoIPavailable = false;
246#endif
247 m_searchwnd = new CSearchDlg(p_cnt);
248 m_transferwnd = new CTransferWnd(p_cnt);
249 m_sharedfileswnd = new CSharedFilesWnd(p_cnt);
250 m_statisticswnd = new CStatisticsDlg(p_cnt, theApp->m_statistics);
251 m_chatwnd = new CChatWnd(p_cnt);
252 m_kademliawnd = CastChild(wxT("kadWnd"), CKadDlg)dynamic_cast<CKadDlg*>( FindWindow( L"kadWnd" ) );
253
254 m_serverwnd->Show(false);
255 m_searchwnd->Show(false);
256 m_transferwnd->Show(false);
257 m_sharedfileswnd->Show(false);
258 m_statisticswnd->Show(false);
259 m_chatwnd->Show(false);
260
261 // Create the GUI timer
262 gui_timer=new wxTimer(this,ID_GUI_TIMER_EVENT);
263 if (!gui_timer
0.1
Field 'gui_timer' is non-null
0.1
Field 'gui_timer' is non-null
0.1
Field 'gui_timer' is non-null
0.1
Field 'gui_timer' is non-null
) {
1
Taking false branch
264 AddLogLineN(_("FATAL ERROR: Failed to create Timer"))theLogger.AddLogLine(L"amuleDlg.cpp", 264, false, logStandard
, wxGetTranslation(("FATAL ERROR: Failed to create Timer")))
;
265 exit(1);
266 }
267
268 // Set transfers as active window
269 Create_Toolbar(thePrefs::VerticalToolbar());
270 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd);
271 m_wndToolbar->ToggleTool(ID_BUTTONDOWNLOADS10336, true );
272
273 bool override_where = (where != wxDefaultPosition);
274 bool override_size = (
275 (dlg_size.x != DEFAULT_SIZE_X800) ||
2
Assuming field 'x' is not equal to DEFAULT_SIZE_X
276 (dlg_size.y != DEFAULT_SIZE_Y600) );
277 if (!LoadGUIPrefs(override_where, override_size)) {
3
Taking false branch
278 // Prefs not loaded for some reason, exit
279 AddLogLineC(wxT("Error! Unable to load Preferences") )theLogger.AddLogLine(L"amuleDlg.cpp", 279, true, logStandard,
L"Error! Unable to load Preferences")
;
280 return;
281 }
282
283 // Prepare the dialog, sets the splitter-position (AFTER window size is set)
284 m_transferwnd->Prepare();
285
286 m_is_safe_state = true;
287
288 // Init statistics stuff, better do it asap
289 m_statisticswnd->Init();
290 m_kademliawnd->Init();
291 m_searchwnd->UpdateCatChoice();
292
293 if (thePrefs::UseTrayIcon()) {
4
Assuming the condition is false
5
Taking false branch
294 CreateSystray();
295 }
296
297 Show(true);
298 // Must we start minimized?
299 if (thePrefs::GetStartMinimized()) {
6
Assuming the condition is false
7
Taking false branch
300 Iconize(true);
301 }
302
303 // Set shortcut keys
304 wxAcceleratorEntry entries[] = {
305 wxAcceleratorEntry(wxACCEL_CTRL, wxT('Q')L'Q', wxID_EXIT)
306 };
307
308 SetAcceleratorTable(wxAcceleratorTable(itemsof(entries)(sizeof(entries) / sizeof(entries[0])), entries));
309 ShowED2KLinksHandler( thePrefs::GetFED2KLH() );
310
311 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook)dynamic_cast<wxNotebook*>( FindWindow( 10252 ) );
312 wxNotebook* networks_notebook = CastChild( ID_NETNOTEBOOK, wxNotebook)dynamic_cast<wxNotebook*>( FindWindow( 10317 ) );
313
314 wxASSERT(logs_notebook->GetPageCount() == 4)do { if ( logs_notebook->GetPageCount() == 4 ) { } else if
( wxTheAssertHandler && (wxOnAssert("amuleDlg.cpp", 314
, __FUNCTION__, "logs_notebook->GetPageCount() == 4", (const
char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false; asm
volatile ("int $3"); } } while ( (void)0, 0 )
;
8
Assuming the condition is true
9
Taking true branch
10
Loop condition is false. Exiting loop
315 wxASSERT(networks_notebook->GetPageCount() == 2)do { if ( networks_notebook->GetPageCount() == 2 ) { } else
if ( wxTheAssertHandler && (wxOnAssert("amuleDlg.cpp"
, 315, __FUNCTION__, "networks_notebook->GetPageCount() == 2"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
11
Assuming the condition is true
12
Taking true branch
13
Loop condition is false. Exiting loop
316
317 for (uint32 i = 0; i < logs_notebook->GetPageCount(); ++i) {
14
Assuming the condition is false
15
Loop condition is false. Execution continues on line 322
318 m_logpages[i].page = logs_notebook->GetPage(i);
319 m_logpages[i].name = logs_notebook->GetPageText(i);
320 }
321
322 for (uint32 i = 0; i < networks_notebook->GetPageCount(); ++i) {
16
Assuming the condition is true
17
Loop condition is true. Entering loop body
18
Assuming the condition is true
19
Loop condition is true. Entering loop body
20
Assuming the condition is true
21
Loop condition is true. Entering loop body
323 m_networkpages[i].page = networks_notebook->GetPage(i);
22
Access of the field 'm_networkpages' at index 2, while it holds only 2 'struct PageType' elements
324 m_networkpages[i].name = networks_notebook->GetPageText(i);
325 }
326
327 DoNetworkRearrange();
328}
329
330
331// Madcat - Sets Fast ED2K Links Handler on/off.
332void CamuleDlg::ShowED2KLinksHandler( bool show )
333{
334 // Errorchecking in case the pointer becomes invalid ...
335 if (s_fed2klh == NULL__null) {
336 wxLogWarningfor ( bool wxdoif336 = false; !wxdoif336 && wxLog::IsLevelEnabled
(wxLOG_Warning, wxString::FromAscii(wxLOG_COMPONENT)); wxdoif336
= true ) wxLogger(wxLOG_Warning, "amuleDlg.cpp", 336, __FUNCTION__
, wxLOG_COMPONENT).Log
(wxT("Unable to find Fast ED2K Links handler sizer! Hiding FED2KLH aborted.")L"Unable to find Fast ED2K Links handler sizer! Hiding FED2KLH aborted.");
337 return;
338 }
339
340 s_dlgcnt->Show( s_fed2klh, show );
341 s_dlgcnt->Layout();
342}
343
344// Toogles ed2k link handler.
345void CamuleDlg::ToogleED2KLinksHandler()
346{
347 // Errorchecking in case the pointer becomes invalid ...
348 if (s_fed2klh == NULL__null) {
349 wxLogWarningfor ( bool wxdoif349 = false; !wxdoif349 && wxLog::IsLevelEnabled
(wxLOG_Warning, wxString::FromAscii(wxLOG_COMPONENT)); wxdoif349
= true ) wxLogger(wxLOG_Warning, "amuleDlg.cpp", 349, __FUNCTION__
, wxLOG_COMPONENT).Log
(wxT("Unable to find Fast ED2K Links handler sizer! Toogling FED2KLH aborted.")L"Unable to find Fast ED2K Links handler sizer! Toogling FED2KLH aborted.");
350 return;
351 }
352 ShowED2KLinksHandler(!s_dlgcnt->IsShown(s_fed2klh));
353}
354
355void CamuleDlg::SetActiveDialog(DialogType type, wxWindow* dlg)
356{
357 m_nActiveDialog = type;
358
359 if ( type == DT_TRANSFER_WND ) {
360 if (thePrefs::ShowCatTabInfos()) {
361 m_transferwnd->UpdateCatTabTitles();
362 }
363 }
364
365 if ( m_activewnd ) {
366 m_activewnd->Show(false);
367 contentSizer->Detach(m_activewnd);
368 }
369
370 contentSizer->Add(dlg, 1, wxALIGN_LEFT|wxEXPAND);
371 dlg->Show(true);
372 m_activewnd=dlg;
373 s_dlgcnt->Layout();
374
375 // Since we might be suspending redrawing while hiding the dialog
376 // we have to refresh it once it is visible again
377 dlg->Refresh( true );
378 dlg->SetFocus();
379
380 if ( type == DT_SHARED_WND ) {
381 // set up splitter now that window sizes are defined
382 m_sharedfileswnd->Prepare();
383 }
384}
385
386
387void CamuleDlg::UpdateTrayIcon(int percent)
388{
389 // set trayicon-icon
390 if(!theApp->IsConnected()) {
391 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_DISCONNECTED, percent);
392 } else {
393 if(theApp->IsConnectedED2K() && theApp->serverconnect->IsLowID()) {
394 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_LOWID, percent);
395 } else {
396 m_wndTaskbarNotifier->SetTrayIcon(TRAY_ICON_HIGHID, percent);
397 }
398 }
399}
400
401
402void CamuleDlg::CreateSystray()
403{
404 wxCHECK_RET(m_wndTaskbarNotifier == NULL,if ( m_wndTaskbarNotifier == __null ) {} else { do { if ( wxTheAssertHandler
&& (wxOnAssert("amuleDlg.cpp", 405, __FUNCTION__, "\"m_wndTaskbarNotifier == __null\""
, L"Systray already created"), wxTrapInAssert) ) { wxTrapInAssert
= false; asm volatile ("int $3"); } } while ( (void)0, 0 ); return
; } struct wxDummyCheckStruct405
405 wxT("Systray already created"))if ( m_wndTaskbarNotifier == __null ) {} else { do { if ( wxTheAssertHandler
&& (wxOnAssert("amuleDlg.cpp", 405, __FUNCTION__, "\"m_wndTaskbarNotifier == __null\""
, L"Systray already created"), wxTrapInAssert) ) { wxTrapInAssert
= false; asm volatile ("int $3"); } } while ( (void)0, 0 ); return
; } struct wxDummyCheckStruct405
;
406
407 m_wndTaskbarNotifier = new CMuleTrayIcon();
408 // This will effectively show the Tray Icon.
409 UpdateTrayIcon(0);
410}
411
412
413void CamuleDlg::RemoveSystray()
414{
415 delete m_wndTaskbarNotifier;
416 m_wndTaskbarNotifier = NULL__null;
417}
418
419
420void CamuleDlg::OnToolBarButton(wxCommandEvent& ev)
421{
422 static int lastbutton = ID_BUTTONDOWNLOADS10336;
423
424 // Kry - just if the GUI is ready for it
425 if ( m_is_safe_state ) {
426
427 // Rehide the handler if needed
428 if ( lastbutton == ID_BUTTONSEARCH10335 && !thePrefs::GetFED2KLH() ) {
429 if (ev.GetId() != ID_BUTTONSEARCH10335) {
430 ShowED2KLinksHandler( false );
431 } else {
432 // Toogle ED2K handler.
433 ToogleED2KLinksHandler();
434 }
435 }
436
437 if ( lastbutton != ev.GetId() ) {
438 switch ( ev.GetId() ) {
439 case ID_BUTTONNETWORKS10334:
440 SetActiveDialog(DT_NETWORKS_WND, m_serverwnd);
441 // Set serverlist splitter position
442 CastChild( wxT("SrvSplitterWnd"), wxSplitterWindow )dynamic_cast<wxSplitterWindow*>( FindWindow( L"SrvSplitterWnd"
) )
->SetSashPosition(m_srv_split_pos, true);
443 break;
444
445 case ID_BUTTONSEARCH10335:
446 // The search dialog should always display the handler
447 if ( !thePrefs::GetFED2KLH() )
448 ShowED2KLinksHandler( true );
449
450 SetActiveDialog(DT_SEARCH_WND, m_searchwnd);
451 break;
452
453 case ID_BUTTONDOWNLOADS10336:
454 SetActiveDialog(DT_TRANSFER_WND, m_transferwnd);
455 // Prepare the dialog, sets the splitter-position
456 m_transferwnd->Prepare();
457 break;
458
459 case ID_BUTTONSHARED10337:
460 SetActiveDialog(DT_SHARED_WND, m_sharedfileswnd);
461 break;
462
463 case ID_BUTTONMESSAGES10338:
464 m_BlinkMessages = false;
465 SetActiveDialog(DT_CHAT_WND, m_chatwnd);
466 break;
467
468 case ID_BUTTONSTATISTICS10339:
469 SetActiveDialog(DT_STATS_WND, m_statisticswnd);
470 break;
471
472 // This shouldn't happen, but just in case
473 default:
474 AddLogLineC(wxT("Unknown button triggered CamuleApp::OnToolBarButton().") )theLogger.AddLogLine(L"amuleDlg.cpp", 474, true, logStandard,
L"Unknown button triggered CamuleApp::OnToolBarButton().")
;
475 break;
476 }
477 }
478
479 m_wndToolbar->ToggleTool(lastbutton, lastbutton == ev.GetId() );
480 lastbutton = ev.GetId();
481 }
482}
483
484
485void CamuleDlg::OnAboutButton(wxCommandEvent& WXUNUSED(ev))
486{
487 wxString msg = wxT(" ")L" ";
488#ifdef CLIENT_GUI
489 msg << _("aMule remote control ")wxGetTranslation(("aMule remote control ")) << wxT(VERSION)L"SVN";
490#else
491 msg << wxT("aMule ")L"aMule " << wxT(VERSION)L"SVN";
492#endif
493 msg << wxT(" ")L" ";
494#ifdef SVNDATE"rev. gd198cb8"
495 msg << _("Snapshot:")wxGetTranslation(("Snapshot:")) << wxT("\n ")L"\n " << wxT(SVNDATE)L"rev. gd198cb8";
496#endif
497 msg << wxT("\n\n")L"\n\n" << _("'All-Platform' p2p client based on eMule \n\n")wxGetTranslation(("'All-Platform' p2p client based on eMule \n\n"
))
<<
498 _("Website: http://www.amule.org \n")wxGetTranslation(("Website: http://www.amule.org \n")) <<
499 _("Forum: http://forum.amule.org \n")wxGetTranslation(("Forum: http://forum.amule.org \n")) <<
500 _("FAQ: http://wiki.amule.org \n\n")wxGetTranslation(("FAQ: http://wiki.amule.org \n\n")) <<
501 _("Contact: admin@amule.org (administrative issues) \n")wxGetTranslation(("Contact: admin@amule.org (administrative issues) \n"
))
<<
502 _("Copyright (c) 2003-2019 aMule Team \n\n")wxGetTranslation(("Copyright (c) 2003-2019 aMule Team \n\n")) <<
503 _("Part of aMule is based on \n")wxGetTranslation(("Part of aMule is based on \n")) <<
504 _("Kademlia: Peer-to-peer routing based on the XOR metric.\n")wxGetTranslation(("Kademlia: Peer-to-peer routing based on the XOR metric.\n"
))
<<
505 _(" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n")wxGetTranslation((" Copyright (c) 2002-2011 Petar Maymounkov ( petar@post.harvard.edu )\n"
))
<<
506 _("http://kademlia.scs.cs.nyu.edu\n")wxGetTranslation(("http://kademlia.scs.cs.nyu.edu\n"));
507
508 if (m_is_safe_state) {
509 wxMessageBox(msg, _("Message")wxGetTranslation(("Message")), wxOK0x00000004 | wxICON_INFORMATION0x00000800, this);
510 }
511}
512
513
514void CamuleDlg::OnPrefButton(wxCommandEvent& WXUNUSED(ev))
515{
516 if (m_is_safe_state) {
517 if (m_prefsDialog == NULL__null) {
518 m_prefsDialog = new PrefsUnifiedDlg(this);
519 }
520
521 m_prefsDialog->TransferToWindow();
522 m_prefsDialog->Show(true);
523 m_prefsDialog->Raise();
524 }
525}
526
527
528void CamuleDlg::OnImportButton(wxCommandEvent& WXUNUSED(ev))
529{
530#ifndef CLIENT_GUI
531 if (m_is_safe_state) {
532 CPartFileConvertDlg::ShowGUI(NULL__null);
533 }
534#endif
535}
536
537
538CamuleDlg::~CamuleDlg()
539{
540 theApp->amuledlg = NULL__null;
541
542#ifdef ENABLE_IP2COUNTRY1
543 delete m_IP2Country;
544#endif
545
546 AddLogLineN(_("aMule dialog destroyed"))theLogger.AddLogLine(L"amuleDlg.cpp", 546, false, logStandard
, wxGetTranslation(("aMule dialog destroyed")))
;
547}
548
549
550void CamuleDlg::OnBnConnect(wxCommandEvent& WXUNUSED(evt))
551{
552
553 bool disconnect = (theApp->IsConnectedED2K() || theApp->serverconnect->IsConnecting())
554 #ifdef CLIENT_GUI
555 || theApp->IsConnectedKad() // there's no Kad running state atm
556 #else
557 || (Kademlia::CKademlia::IsRunning())
558 #endif
559 ;
560 if (thePrefs::GetNetworkED2K()) {
561 if (disconnect) {
562 //disconnect if currently connected
563 if (theApp->serverconnect->IsConnecting()) {
564 theApp->serverconnect->StopConnectionTry();
565 } else {
566 theApp->serverconnect->Disconnect();
567 }
568 } else {
569 //connect if not currently connected
570 AddLogLineC(_("Connecting"))theLogger.AddLogLine(L"amuleDlg.cpp", 570, true, logStandard,
wxGetTranslation(("Connecting")))
;
571 theApp->serverconnect->ConnectToAnyServer();
572 }
573 } else {
574 wxASSERT(!theApp->IsConnectedED2K())do { if ( !theApp->IsConnectedED2K() ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("amuleDlg.cpp", 574, __FUNCTION__, "!theApp->IsConnectedED2K()"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
575 }
576
577 // Connect Kad also
578 if (thePrefs::GetNetworkKademlia()) {
579 if( disconnect ) {
580 theApp->StopKad();
581 } else {
582 theApp->StartKad();
583 }
584 } else {
585 #ifndef CLIENT_GUI
586 wxASSERT(!Kademlia::CKademlia::IsRunning())do { if ( !Kademlia::CKademlia::IsRunning() ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("amuleDlg.cpp", 586, __FUNCTION__, "!Kademlia::CKademlia::IsRunning()"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
587 #endif
588 }
589
590 ShowConnectionState();
591}
592
593
594void CamuleDlg::ResetLog(int id)
595{
596 wxTextCtrl* ct = CastByID(id, m_serverwnd, wxTextCtrl)dynamic_cast<wxTextCtrl*>( wxWindow::FindWindowById( (id
), (m_serverwnd) ) )
;
597 wxCHECK_RET(ct, wxT("Resetting unknown log"))if ( ct ) {} else { do { if ( wxTheAssertHandler && (
wxOnAssert("amuleDlg.cpp", 597, __FUNCTION__, "\"ct\"", L"Resetting unknown log"
), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile (
"int $3"); } } while ( (void)0, 0 ); return; } struct wxDummyCheckStruct597
;
598
599 ct->Clear();
600
601 if (id == ID_LOGVIEW10242) {
602 // Also clear the log line
603 wxStaticText* text = CastChild(wxT("infoLabel"), wxStaticText)dynamic_cast<wxStaticText*>( FindWindow( L"infoLabel" )
)
;
604 text->SetLabel(wxEmptyString);
605 text->GetParent()->Layout();
606 }
607}
608
609
610void CamuleDlg::AddLogLine(const wxString& line)
611{
612 bool addtostatusbar = line[0] == '!';
613 wxString bufferline = line.Mid(1);
614
615 // Add the message to the log-view
616 wxTextCtrl* ct = CastByID( ID_LOGVIEW, m_serverwnd, wxTextCtrl )dynamic_cast<wxTextCtrl*>( wxWindow::FindWindowById( (10242
), (m_serverwnd) ) )
;
617 if ( ct ) {
618 // Bold critical log-lines
619 // Works in Windows too thanks to wxTE_RICH2 style in muuli
620 wxTextAttr style = ct->GetDefaultStyle();
621 wxFont font = style.GetFont();
622 font.SetWeight(addtostatusbar ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
623 style.SetFont(font);
624 style.SetFontSize(8);
625 ct->SetDefaultStyle(style);
626 ct->AppendText(bufferline);
627 ct->ShowPosition( ct->GetLastPosition() - 1 );
628 }
629
630
631 // Set the status-bar if the event warrents it
632 if ( addtostatusbar ) {
633 // Escape "&"s, which would otherwise not show up
634 bufferline.Replace( wxT("&")L"&", wxT("&&")L"&&" );
635 wxStaticText* text = CastChild( wxT("infoLabel"), wxStaticText )dynamic_cast<wxStaticText*>( FindWindow( L"infoLabel" )
)
;
636 // Only show the first line if multiple lines
637 text->SetLabel( bufferline.BeforeFirst( wxT('\n')L'\n' ) );
638 text->SetToolTip( bufferline );
639 text->GetParent()->Layout();
640 }
641
642}
643
644
645void CamuleDlg::AddServerMessageLine(wxString& message)
646{
647 wxTextCtrl* cv= CastByID( ID_SERVERINFO, m_serverwnd, wxTextCtrl )dynamic_cast<wxTextCtrl*>( wxWindow::FindWindowById( (10240
), (m_serverwnd) ) )
;
648 if(cv) {
649 if (message.Length() > 500) {
650 cv->AppendText(message.Left(500) + wxT("\n")L"\n");
651 } else {
652 cv->AppendText(message + wxT("\n")L"\n");
653 }
654 cv->ShowPosition(cv->GetLastPosition()-1);
655 }
656}
657
658
659void CamuleDlg::ShowConnectionState(bool skinChanged)
660{
661 static wxImageList status_arrows(16,16,true,0);
662 if (!status_arrows.GetImageCount()) {
663 // Generate the image list (This is only done once)
664 for (int t = 0; t < 7; ++t) {
665 status_arrows.Add(connImages(t));
666 }
667 }
668
669 m_serverwnd->UpdateED2KInfo();
670 m_serverwnd->UpdateKadInfo();
671
672
673 ////////////////////////////////////////////////////////////
674 // Determine the status of the networks
675 //
676 enum ED2KState { ED2KOff = 0, ED2KLowID = 1, ED2KConnecting = 2, ED2KHighID = 3, ED2KUndef = -1 };
677 enum EKadState { EKadOff = 4, EKadFW = 5, EKadConnecting = 5, EKadOK = 6, EKadUndef = -1 };
678
679 ED2KState ed2kState = ED2KOff;
680 EKadState kadState = EKadOff;
681
682 ////////////////////////////////////////////////////////////
683 // Update the label on the status-bar and determine
684 // the states of the two networks.
685 //
686 wxString msgED2K;
687 if (theApp->IsConnectedED2K()) {
688 CServer* server = theApp->serverconnect->GetCurrentServer();
689 if (server) {
690 msgED2K = CFormat(wxT("eD2k: %s")L"eD2k: %s") % server->GetListName();
691 }
692
693 if (theApp->serverconnect->IsLowID()) {
694 ed2kState = ED2KLowID;
695 } else {
696 ed2kState = ED2KHighID;
697 }
698 } else if (theApp->serverconnect->IsConnecting()) {
699 msgED2K = _("eD2k: Connecting")wxGetTranslation(("eD2k: Connecting"));
700
701 ed2kState = ED2KConnecting;
702 } else if (thePrefs::GetNetworkED2K()) {
703 msgED2K = _("eD2k: Disconnected")wxGetTranslation(("eD2k: Disconnected"));
704 }
705
706 wxString msgKad;
707 if (theApp->IsConnectedKad()) {
708 if (theApp->IsFirewalledKad()) {
709 msgKad = _("Kad: Firewalled")wxGetTranslation(("Kad: Firewalled"));
710
711 kadState = EKadFW;
712 } else {
713 msgKad = _("Kad: Connected")wxGetTranslation(("Kad: Connected"));
714
715 kadState = EKadOK;
716 }
717 } else if (theApp->IsKadRunning()) {
718 msgKad = _("Kad: Connecting")wxGetTranslation(("Kad: Connecting"));
719
720 kadState = EKadConnecting;
721 } else if (thePrefs::GetNetworkKademlia()) {
722 msgKad = _("Kad: Off")wxGetTranslation(("Kad: Off"));
723 }
724
725 wxStaticText* connLabel = CastChild( wxT("connLabel"), wxStaticText )dynamic_cast<wxStaticText*>( FindWindow( L"connLabel" )
)
;
726 { wxCHECK_RET(connLabel, wxT("'connLabel' widget not found"))if ( connLabel ) {} else { do { if ( wxTheAssertHandler &&
(wxOnAssert("amuleDlg.cpp", 726, __FUNCTION__, "\"connLabel\""
, L"'connLabel' widget not found"), wxTrapInAssert) ) { wxTrapInAssert
= false; asm volatile ("int $3"); } } while ( (void)0, 0 ); return
; } struct wxDummyCheckStruct726
; }
727
728 wxString labelMsg;
729 if (msgED2K.Length() && msgKad.Length()) {
730 labelMsg = msgED2K + wxT(" | ")L" | " + msgKad;
731 } else {
732 labelMsg = msgED2K + msgKad;
733 }
734
735 connLabel->SetLabel(labelMsg);
736 connLabel->GetParent()->Layout();
737
738
739 ////////////////////////////////////////////////////////////
740 // Update the connect/disconnect/cancel button.
741 //
742 enum EConnState {
743 ECS_Unknown,
744 ECS_Connected,
745 ECS_Connecting,
746 ECS_Disconnected
747 };
748
749 static EConnState s_oldState = ECS_Unknown;
750 EConnState currentState = ECS_Disconnected;
751
752 if (theApp->serverconnect->IsConnecting() ||
753 (theApp->IsKadRunning() && !theApp->IsConnectedKad())) {
754 currentState = ECS_Connecting;
755 } else if (theApp->IsConnected()) {
756 currentState = ECS_Connected;
757 } else {
758 currentState = ECS_Disconnected;
759 }
760
761 if ( (true == skinChanged) || (currentState != s_oldState) ) {
762 wxWindowUpdateLocker freezer(m_wndToolbar);
763
764 wxToolBarToolBase* toolbarTool = m_wndToolbar->FindById(ID_BUTTONCONNECT10333);
765
766 switch (currentState) {
767 case ECS_Connecting:
768 toolbarTool->SetLabel(_("Cancel")wxGetTranslation(("Cancel")));
769 toolbarTool->SetShortHelp(_("Stop the current connection attempts")wxGetTranslation(("Stop the current connection attempts")));
770 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(2));
771 break;
772
773 case ECS_Connected:
774 toolbarTool->SetLabel(_("Disconnect")wxGetTranslation(("Disconnect")));
775 toolbarTool->SetShortHelp(_("Disconnect from the currently connected networks")wxGetTranslation(("Disconnect from the currently connected networks"
))
);
776 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(1));
777 break;
778
779 default:
780 toolbarTool->SetLabel(_("Connect")wxGetTranslation(("Connect")));
781 toolbarTool->SetShortHelp(_("Connect to the currently enabled networks")wxGetTranslation(("Connect to the currently enabled networks"
))
);
782 toolbarTool->SetNormalBitmap(m_tblist.GetBitmap(0));
783 }
784
785 m_wndToolbar->EnableTool(ID_BUTTONCONNECT10333, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()) && theApp->ipfilter->IsReady());
786
787 s_oldState = currentState;
788 }
789
790
791 ////////////////////////////////////////////////////////////
792 // Update the globe-icon in the lower-right corner.
793 // (only if connection state has changed)
794 //
795 static ED2KState s_ED2KOldState = ED2KUndef;
796 static EKadState s_EKadOldState = EKadUndef;
797 if (ed2kState != s_ED2KOldState || kadState != s_EKadOldState) {
798 s_ED2KOldState = ed2kState;
799 s_EKadOldState = kadState;
800 wxStaticBitmap* connBitmap = CastChild( wxT("connImage"), wxStaticBitmap )dynamic_cast<wxStaticBitmap*>( FindWindow( L"connImage"
) )
;
801 wxCHECK_RET(connBitmap, wxT("'connImage' widget not found"))if ( connBitmap ) {} else { do { if ( wxTheAssertHandler &&
(wxOnAssert("amuleDlg.cpp", 801, __FUNCTION__, "\"connBitmap\""
, L"'connImage' widget not found"), wxTrapInAssert) ) { wxTrapInAssert
= false; asm volatile ("int $3"); } } while ( (void)0, 0 ); return
; } struct wxDummyCheckStruct801
;
802
803 wxBitmap statusIcon = connBitmap->GetBitmap();
804 // Sanity check - otherwise there's a crash here if aMule runs out of resources
805 if (statusIcon.GetRefData() == NULL__null) {
806 return;
807 }
808
809 wxMemoryDC bitmapDC(statusIcon);
810
811 status_arrows.Draw(kadState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT0x0002);
812 status_arrows.Draw(ed2kState, bitmapDC, 0, 0, wxIMAGELIST_DRAW_TRANSPARENT0x0002);
813
814 connBitmap->SetBitmap(statusIcon);
815 }
816}
817
818
819void CamuleDlg::ShowUserCount(const wxString& info)
820{
821 wxStaticText* label = CastChild( wxT("userLabel"), wxStaticText )dynamic_cast<wxStaticText*>( FindWindow( L"userLabel" )
)
;
822
823 // Update Kad tab
824 m_serverwnd->UpdateKadInfo();
825
826 label->SetLabel(info);
827 label->GetParent()->Layout();
828}
829
830
831void CamuleDlg::ShowTransferRate()
832{
833 float kBpsUp = theStats::GetUploadRate() / 1024.0;
834 float kBpsDown = theStats::GetDownloadRate() / 1024.0;
835 float MBpsUp = kBpsUp / 1024.0;
836 float MBpsDown = kBpsDown / 1024.0;
837 bool showMBpsUp = (MBpsUp >= 1);
838 bool showMBpsDown = (MBpsDown >= 1);
839 wxString buffer;
840 if( thePrefs::ShowOverhead() )
841 {
842 buffer = CFormat(_("Up: %.1f%s (%.1f) | Down: %.1f%s (%.1f)")wxGetTranslation(("Up: %.1f%s (%.1f) | Down: %.1f%s (%.1f)")))
843 % (showMBpsUp ? MBpsUp : kBpsUp) % (showMBpsUp ? _(" MB/s")wxGetTranslation((" MB/s")) : ((kBpsUp > 0) ? _(" kB/s")wxGetTranslation((" kB/s")) : wxT("")L"")) % (theStats::GetUpOverheadRate() / 1024.0)
844 % (showMBpsDown ? MBpsDown : kBpsDown) % (showMBpsDown ? _(" MB/s")wxGetTranslation((" MB/s")) : ((kBpsDown > 0) ? _(" kB/s")wxGetTranslation((" kB/s")) : wxT("")L"")) % (theStats::GetDownOverheadRate() / 1024.0);
845 } else {
846 buffer = CFormat(_("Up: %.1f%s | Down: %.1f%s")wxGetTranslation(("Up: %.1f%s | Down: %.1f%s")))
847 % (showMBpsUp ? MBpsUp : kBpsUp) % (showMBpsUp ? _(" MB/s")wxGetTranslation((" MB/s")) : ((kBpsUp > 0) ? _(" kB/s")wxGetTranslation((" kB/s")) : wxT("")L""))
848 % (showMBpsDown ? MBpsDown : kBpsDown) % (showMBpsDown ? _(" MB/s")wxGetTranslation((" MB/s")) : ((kBpsDown > 0) ? _(" kB/s")wxGetTranslation((" kB/s")) : wxT("")L""));
849 }
850 buffer.Truncate(50); // Max size 50
851
852 wxStaticText* label = CastChild( wxT("speedLabel"), wxStaticText )dynamic_cast<wxStaticText*>( FindWindow( L"speedLabel" )
)
;
853 label->SetLabel(buffer);
854 label->GetParent()->Layout();
855
856 // Show upload/download speed in title
857 if (thePrefs::GetShowRatesOnTitle()) {
858 wxString UpDownSpeed = CFormat(wxT("Up: %.1f%s | Down: %.1f%s")L"Up: %.1f%s | Down: %.1f%s")
859 % (showMBpsUp ? MBpsUp : kBpsUp) % (showMBpsUp ? _(" MB/s")wxGetTranslation((" MB/s")) : ((kBpsUp > 0) ? _(" kB/s")wxGetTranslation((" kB/s")) : wxT("")L""))
860 % (showMBpsDown ? MBpsDown : kBpsDown) % (showMBpsDown ? _(" MB/s")wxGetTranslation((" MB/s")) : ((kBpsDown > 0) ? _(" kB/s")wxGetTranslation((" kB/s")) : wxT("")L""));
861 if (thePrefs::GetShowRatesOnTitle() == 1) {
862 SetTitle(theApp->m_FrameTitle + wxT(" -- ")L" -- " + UpDownSpeed);
863 } else {
864 SetTitle(UpDownSpeed + wxT(" -- ")L" -- " + theApp->m_FrameTitle);
865 }
866 }
867
868 wxASSERT((m_wndTaskbarNotifier != NULL) == thePrefs::UseTrayIcon())do { if ( (m_wndTaskbarNotifier != __null) == thePrefs::UseTrayIcon
() ) { } else if ( wxTheAssertHandler && (wxOnAssert(
"amuleDlg.cpp", 868, __FUNCTION__, "(m_wndTaskbarNotifier != __null) == thePrefs::UseTrayIcon()"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
869 if (m_wndTaskbarNotifier) {
870 // set trayicon-icon
871 int percentDown = (int)ceil((kBpsDown*100) / thePrefs::GetMaxGraphDownloadRate());
872 UpdateTrayIcon( ( percentDown > 100 ) ? 100 : percentDown);
873
874 wxString buffer2;
875 if ( theApp->IsConnected() ) {
876 buffer2 = CFormat(_("aMule (%s | Connected)")wxGetTranslation(("aMule (%s | Connected)"))) % buffer;
877 } else {
878 buffer2 = CFormat(_("aMule (%s | Disconnected)")wxGetTranslation(("aMule (%s | Disconnected)"))) % buffer;
879 }
880 m_wndTaskbarNotifier->SetTrayToolTip(buffer2);
881 }
882
883 wxStaticBitmap* bmp = CastChild( wxT("transferImg"), wxStaticBitmap )dynamic_cast<wxStaticBitmap*>( FindWindow( L"transferImg"
) )
;
884 bmp->SetBitmap(dlStatusImages((kBpsUp>0.01 ? 2 : 0) + (kBpsDown>0.01 ? 1 : 0)));
885}
886
887void CamuleDlg::DlgShutDown()
888{
889 // Are we already shutting down or still on init?
890 if ( m_is_safe_state == false ) {
891 return;
892 }
893
894 // we are going DOWN
895 m_is_safe_state = false;
896
897 // Stop the GUI Timer
898 delete gui_timer;
899 m_transferwnd->downloadlistctrl->DeleteAllItems();
900
901 // We want to delete the systray too!
902 RemoveSystray();
903}
904
905void CamuleDlg::OnClose(wxCloseEvent& evt)
906{
907 if (thePrefs::HideOnClose() && evt.CanVeto()) {
908 Show(false);
909 evt.Veto();
910 return;
911 }
912
913 // This will be here till the core close is != app close
914 if (evt.CanVeto() && thePrefs::IsConfirmExitEnabled() ) {
915 if (wxNO0x00000008 == wxMessageBox(wxString(CFormat(_("Do you really want to exit %s?")wxGetTranslation(("Do you really want to exit %s?"))) % theApp->GetMuleAppName()),
916 wxString(_("Exit confirmation")wxGetTranslation(("Exit confirmation"))), wxYES_NO(0x00000002 | 0x00000008), this)) {
917 evt.Veto();
918 return;
919 }
920 }
921
922 SaveGUIPrefs();
923
924 Enable(false);
925 Show(false);
926
927 theApp->ShutDown(evt);
928}
929
930
931void CamuleDlg::OnBnClickedFast(wxCommandEvent& WXUNUSED(evt))
932{
933 wxTextCtrl* ctl = CastChild( wxT("FastEd2kLinks"), wxTextCtrl )dynamic_cast<wxTextCtrl*>( FindWindow( L"FastEd2kLinks"
) )
;
934
935 for ( int i = 0; i < ctl->GetNumberOfLines(); i++ ) {
936 wxString strlink = ctl->GetLineText(i);
937 strlink.Trim(true);
938 strlink.Trim(false);
939 if ( !strlink.IsEmpty() ) {
940 theApp->downloadqueue->AddLink( strlink, m_transferwnd->downloadlistctrl->GetCategory() );
941 }
942 }
943
944 ctl->SetValue(wxEmptyString);
945}
946
947
948// Formerly known as LoadRazorPrefs()
949bool CamuleDlg::LoadGUIPrefs(bool override_pos, bool override_size)
950{
951 // Create a config base for loading razor preferences
952 wxConfigBase *config = wxConfigBase::Get();
953 // If config haven't been created exit without loading
954 if (config == NULL__null) {
955 return false;
956 }
957
958 // The section where to save in in file
959 wxString section = wxT("/Razor_Preferences/")L"/Razor_Preferences/";
960
961 // Get window size and position
962 int x1 = config->Read(section + wxT("MAIN_X_POS")L"MAIN_X_POS", -1);
963 int y1 = config->Read(section + wxT("MAIN_Y_POS")L"MAIN_Y_POS", -1);
964 int x2 = config->Read(section + wxT("MAIN_X_SIZE")L"MAIN_X_SIZE", -1);
965 int y2 = config->Read(section + wxT("MAIN_Y_SIZE")L"MAIN_Y_SIZE", -1);
966
967 int maximized = config->Read(section + wxT("Maximized")L"Maximized", 01);
968
969 // Kry - Random usable pos for m_srv_split_pos
970 m_srv_split_pos = config->Read(section + wxT("SRV_SPLITTER_POS")L"SRV_SPLITTER_POS", 463l);
971 if (!override_size) {
972 if (x2 > 0 && y2 > 0) {
973 SetSize(x2, y2);
974 } else {
975#ifndef __WXGTK__1
976 // Probably first run.
977 Maximize();
978#endif
979 }
980 }
981
982 if (!override_pos) {
983 // If x1 and y1 != -1 Redefine location
984 if(x1 != -1 && y1 != -1) {
985 wxRect display = wxGetClientDisplayRect();
986 if (x1 <= display.GetRightTop().x && y1 <= display.GetRightBottom().y) {
987 Move(x1, y1);
988 } else {
989 // It's offscreen... so let's not.
990 }
991 }
992 }
993
994 if (!override_size && !override_pos && maximized) {
995 Maximize();
996 }
997
998 return true;
999}
1000
1001
1002bool CamuleDlg::SaveGUIPrefs()
1003{
1004 /* Razor 1a - Modif by MikaelB
1005 Save client size and position */
1006
1007 // Create a config base for saving razor preferences
1008 wxConfigBase *config = wxConfigBase::Get();
1009 // If config haven't been created exit without saving
1010 if (config == NULL__null) {
1011 return false;
1012 }
1013 // The section where to save in in file
1014 wxString section = wxT("/Razor_Preferences/")L"/Razor_Preferences/";
1015
1016 if (!IsIconized()) {
1017 // Main window location and size
1018 int x1, y1, x2, y2;
1019 GetPosition(&x1, &y1);
1020 GetSize(&x2, &y2);
1021
1022 // Saving window size and position
1023 config->Write(section+wxT("MAIN_X_POS")L"MAIN_X_POS", (long) x1);
1024 config->Write(section+wxT("MAIN_Y_POS")L"MAIN_Y_POS", (long) y1);
1025
1026 config->Write(section+wxT("MAIN_X_SIZE")L"MAIN_X_SIZE", (long) x2);
1027 config->Write(section+wxT("MAIN_Y_SIZE")L"MAIN_Y_SIZE", (long) y2);
1028
1029 config->Write(section+wxT("Maximized")L"Maximized", (long) (IsMaximized() ? 1 : 0));
1030 }
1031
1032 // Saving sash position of splitter in server window
1033 config->Write(section+wxT("SRV_SPLITTER_POS")L"SRV_SPLITTER_POS", (long) m_srv_split_pos);
1034
1035 config->Flush(true);
1036
1037 /* End modif */
1038
1039 return true;
1040}
1041
1042
1043void CamuleDlg::OnMinimize(wxIconizeEvent& evt)
1044{
1045// Evil Hack: check if the mouse is inside the window
1046#ifndef __WINDOWS__
1047 if (wxFindWindowAtPoint(wxGetMousePosition()))
1048#endif
1049 {
1050 if (m_prefsDialog && m_prefsDialog->IsShown()) {
1051 // Veto.
1052 } else {
1053 if (m_wndTaskbarNotifier && thePrefs::DoMinToTray()) {
1054 Show(!evt.IsIconized());
1055 }
1056 else {
1057 evt.Skip();
1058 }
1059 }
1060 }
1061}
1062
1063void CamuleDlg::OnGUITimer(wxTimerEvent& WXUNUSED(evt))
1064{
1065 // Former TimerProc section
1066
1067 static uint32 msPrev1, msPrev5;
1068
1069 uint32 msCur = theStats::GetUptimeMillis();
1070
1071 // can this actually happen under wxwin ?
1072 if (!SafeState()) {
1073 return;
1074 }
1075
1076#ifndef CLIENT_GUI
1077 static uint32 msPrevGraph, msPrevStats;
1078 int msGraphUpdate = thePrefs::GetTrafficOMeterInterval() * 1000;
1079 if ((msGraphUpdate > 0) && ((msCur / msGraphUpdate) > (msPrevGraph / msGraphUpdate))) {
1080 // trying to get the graph shifts evenly spaced after a change in the update period
1081 msPrevGraph = msCur;
1082
1083 GraphUpdateInfo update = theApp->m_statistics->GetPointsForUpdate();
1084
1085 m_statisticswnd->UpdateStatGraphs(theStats::GetPeakConnections(), update);
1086 m_kademliawnd->UpdateGraph(update);
1087 }
1088
1089 int sStatsUpdate = thePrefs::GetStatsInterval();
1090 if ((sStatsUpdate > 0) && ((int)(msCur - msPrevStats) > sStatsUpdate*1000)) {
1091 if (m_statisticswnd->IsShownOnScreen()) {
1092 msPrevStats = msCur;
1093 m_statisticswnd->ShowStatistics();
1094 }
1095 }
1096#endif
1097
1098 if (msCur-msPrev5 > 5000) { // every 5 seconds
1099 msPrev5 = msCur;
1100 ShowTransferRate();
1101 if (thePrefs::ShowCatTabInfos() && theApp->amuledlg->m_activewnd == theApp->amuledlg->m_transferwnd) {
1102 m_transferwnd->UpdateCatTabTitles();
1103 }
1104 if (thePrefs::AutoSortDownload()) {
1105 m_transferwnd->downloadlistctrl->SortList();
1106 m_transferwnd->clientlistctrl->SortList();
1107 m_sharedfileswnd->peerslistctrl->SortList();
1108 }
1109 m_kademliawnd->UpdateNodeCount(CStatistics::GetKadNodes());
1110 }
1111
1112 if (msCur-msPrev1 > 1000) { // every second
1113 msPrev1 = msCur;
1114 if (m_CurrentBlinkBitmap == 12) {
1115 m_CurrentBlinkBitmap = 7;
1116 SetMessagesTool();
1117 } else {
1118 if (m_BlinkMessages) {
1119 m_CurrentBlinkBitmap = 12;
1120 SetMessagesTool();
1121 }
1122 }
1123
1124 }
1125}
1126
1127
1128void CamuleDlg::SetMessagesTool()
1129{
1130 wxWindowUpdateLocker freezer(m_wndToolbar);
1131#ifdef __WXCOCOA__
1132 m_wndToolbar->FindById(ID_BUTTONMESSAGES10338)->SetNormalBitmap(m_tblist.GetBitmap(m_CurrentBlinkBitmap));
1133#else
1134 m_wndToolbar->SetToolNormalBitmap(ID_BUTTONMESSAGES10338, m_tblist.GetBitmap(m_CurrentBlinkBitmap));
1135#endif
1136}
1137
1138void CamuleDlg::LaunchUrl( const wxString& url )
1139{
1140 wxString cmd;
1141
1142 cmd = thePrefs::GetBrowser();
1143 wxString tmp = url;
1144 // Pipes cause problems, so escape them
1145 tmp.Replace( wxT("|")L"|", wxT("%7C")L"%7C" );
1146
1147 if ( !cmd.IsEmpty() ) {
1148 if (!cmd.Replace(wxT("%s")L"%s", tmp)) {
1149 // No %s found, just append the url
1150 cmd += wxT(" ")L" " + tmp;
1151 }
1152
1153 CTerminationProcess *p = new CTerminationProcess(cmd);
1154 if (wxExecute(cmd, wxEXEC_ASYNC, p)) {
1155 AddLogLineN(_("Launch Command: ") + cmd)theLogger.AddLogLine(L"amuleDlg.cpp", 1155, false, logStandard
, wxGetTranslation(("Launch Command: ")) + cmd)
;
1156 return;
1157 } else {
1158 delete p;
1159 }
1160 } else {
1161 wxLaunchDefaultBrowser(tmp);
1162 return;
1163 }
1164 // Unable to execute browser. But this error message doesn't make sense,
1165 // cosidering that you _can't_ set the browser executable path... =/
1166 wxLogErrorfor ( bool wxdoif1166 = false; !wxdoif1166 && wxLog::
IsLevelEnabled(wxLOG_Error, wxString::FromAscii(wxLOG_COMPONENT
)); wxdoif1166 = true ) wxLogger(wxLOG_Error, "amuleDlg.cpp",
1166, __FUNCTION__, wxLOG_COMPONENT).Log
(wxT("Unable to launch browser. Please set correct browser executable path in Preferences.")L"Unable to launch browser. Please set correct browser executable path in Preferences.");
1167}
1168
1169
1170bool CamuleDlg::Check_and_Init_Skin()
1171{
1172 bool ret = true;
1173 wxString skinFileName(thePrefs::GetSkin());
1174
1175 if (skinFileName.IsEmpty() || skinFileName.IsSameAs(_("- default -")wxGetTranslation(("- default -")))) {
1176 return false;
1177 }
1178
1179 wxString userDir(JoinPaths(thePrefs::GetConfigDir(), wxT("skins")L"skins") + wxFileName::GetPathSeparator());
1180
1181 wxStandardPathsBase &spb(wxStandardPaths::Get());
1182#ifdef __WINDOWS__
1183 wxString dataDir(spb.GetPluginsDir());
1184#elif defined(__WXMAC__)
1185 wxString dataDir(spb.GetDataDir());
1186#else
1187 wxString dataDir(spb.GetDataDir().BeforeLast(wxT('/')L'/') + wxT("/amule")L"/amule");
1188#endif
1189 wxString systemDir(JoinPaths(dataDir,wxT("skins")L"skins") + wxFileName::GetPathSeparator());
1190
1191
1192 skinFileName.Replace(wxT("User:")L"User:", userDir );
1193 skinFileName.Replace(wxT("System:")L"System:", systemDir );
1194
1195 m_skinFileName.Assign(skinFileName);
1196 if (!m_skinFileName.FileExists()) {
1197 AddLogLineC(CFormat(theLogger.AddLogLine(L"amuleDlg.cpp", 1199, true, logStandard
, CFormat( wxGetTranslation(("Skin directory '%s' does not exist"
))) % skinFileName)
1198 _("Skin directory '%s' does not exist")) %theLogger.AddLogLine(L"amuleDlg.cpp", 1199, true, logStandard
, CFormat( wxGetTranslation(("Skin directory '%s' does not exist"
))) % skinFileName)
1199 skinFileName )theLogger.AddLogLine(L"amuleDlg.cpp", 1199, true, logStandard
, CFormat( wxGetTranslation(("Skin directory '%s' does not exist"
))) % skinFileName)
;
1200 ret = false;
1201 } else if (!m_skinFileName.IsFileReadable()) {
1202 AddLogLineC(CFormat(theLogger.AddLogLine(L"amuleDlg.cpp", 1204, true, logStandard
, CFormat( wxGetTranslation(("WARNING: Unable to open skin file '%s' for read"
))) % skinFileName)
1203 _("WARNING: Unable to open skin file '%s' for read")) %theLogger.AddLogLine(L"amuleDlg.cpp", 1204, true, logStandard
, CFormat( wxGetTranslation(("WARNING: Unable to open skin file '%s' for read"
))) % skinFileName)
1204 skinFileName)theLogger.AddLogLine(L"amuleDlg.cpp", 1204, true, logStandard
, CFormat( wxGetTranslation(("WARNING: Unable to open skin file '%s' for read"
))) % skinFileName)
;
1205 ret = false;
1206 }
1207
1208 wxFFileInputStream in(m_skinFileName.GetFullPath());
1209 wxZipInputStream zip(in);
1210 wxZipEntry *entry;
1211
1212 while ((entry = zip.GetNextEntry()) != NULL__null) {
1213 wxZipEntry*& current = cat[entry->GetInternalName()];
1214 delete current;
1215 current = entry;
1216 }
1217
1218 return ret;
1219}
1220
1221
1222void CamuleDlg::Add_Skin_Icon(
1223 const wxString &iconName,
1224 const wxBitmap &stdIcon,
1225 bool useSkins)
1226{
1227 wxImage new_image;
1228 if (useSkins) {
1229 wxFFileInputStream in(m_skinFileName.GetFullPath());
1230 wxZipInputStream zip(in);
1231
1232 ZipCatalog::iterator it = cat.find(wxZipEntry::GetInternalName(iconName + wxT(".png")L".png"));
1233 if ( it != cat.end() ) {
1234 zip.OpenEntry(*it->second);
1235 if ( !new_image.LoadFile(zip,wxBITMAP_TYPE_PNG) ) {
1236 AddLogLineN(wxT("Warning: Error loading icon for ") +theLogger.AddLogLine(L"amuleDlg.cpp", 1237, false, logStandard
, L"Warning: Error loading icon for " + iconName)
1237 iconName)theLogger.AddLogLine(L"amuleDlg.cpp", 1237, false, logStandard
, L"Warning: Error loading icon for " + iconName)
;
1238 useSkins = false;
1239 }
1240 }else {
1241 AddLogLineN(wxT("Warning: Can't load icon for ") +theLogger.AddLogLine(L"amuleDlg.cpp", 1242, false, logStandard
, L"Warning: Can't load icon for " + iconName)
1242 iconName)theLogger.AddLogLine(L"amuleDlg.cpp", 1242, false, logStandard
, L"Warning: Can't load icon for " + iconName)
;
1243 useSkins = false;
1244 }
1245
1246 }
1247
1248 wxBitmap bmp(useSkins ? new_image : stdIcon);
1249 if (iconName.StartsWith(wxT("Client_")L"Client_")) {
1250 m_imagelist.Add(bmp);
1251 } else if (iconName.StartsWith(wxT("Toolbar_")L"Toolbar_")) {
1252 m_tblist.Add(bmp);
1253 }
1254}
1255
1256
1257void CamuleDlg::Apply_Clients_Skin()
1258{
1259 bool useSkins = Check_and_Init_Skin();
1260
1261 // Clear the client image list
1262 m_imagelist.RemoveAll();
1263
1264 // Add the images to the image list
1265 for (int i = 0; i < CLIENT_SKIN_SIZE; ++i) {
1266 Add_Skin_Icon(wxT("Client_")L"Client_" + m_clientSkinNames[i],
1267 clientImages(i), useSkins);
1268 }
1269}
1270
1271
1272void CamuleDlg::Apply_Toolbar_Skin(wxToolBar *wndToolbar)
1273{
1274 bool useSkins = Check_and_Init_Skin();
1275
1276
1277 // Clear the toolbar image list
1278 m_tblist.RemoveAll();
1279
1280 // Add the images to the image list
1281 Add_Skin_Icon(wxT("Toolbar_Connect")L"Toolbar_Connect", connButImg(0), useSkins);
1282 Add_Skin_Icon(wxT("Toolbar_Disconnect")L"Toolbar_Disconnect", connButImg(1), useSkins);
1283 Add_Skin_Icon(wxT("Toolbar_Connecting")L"Toolbar_Connecting", connButImg(2), useSkins);
1284 Add_Skin_Icon(wxT("Toolbar_Network")L"Toolbar_Network", amuleDlgImages(20), useSkins);
1285 Add_Skin_Icon(wxT("Toolbar_Transfers")L"Toolbar_Transfers", amuleDlgImages(21), useSkins);
1286 Add_Skin_Icon(wxT("Toolbar_Search")L"Toolbar_Search", amuleDlgImages(22), useSkins);
1287 Add_Skin_Icon(wxT("Toolbar_Shared")L"Toolbar_Shared", amuleDlgImages(23), useSkins);
1288 Add_Skin_Icon(wxT("Toolbar_Messages")L"Toolbar_Messages", amuleDlgImages(24), useSkins);
1289 Add_Skin_Icon(wxT("Toolbar_Stats")L"Toolbar_Stats", amuleDlgImages(25), useSkins);
1290 Add_Skin_Icon(wxT("Toolbar_Prefs")L"Toolbar_Prefs", amuleDlgImages(26), useSkins);
1291 Add_Skin_Icon(wxT("Toolbar_Import")L"Toolbar_Import", amuleDlgImages(32), useSkins);
1292 Add_Skin_Icon(wxT("Toolbar_About")L"Toolbar_About", amuleDlgImages(29), useSkins);
1293 Add_Skin_Icon(wxT("Toolbar_Blink")L"Toolbar_Blink", amuleDlgImages(33), useSkins);
1294
1295 // Build aMule toolbar
1296 wndToolbar->SetMargins(0, 0);
1297
1298 // Placeholder. Gets updated by ShowConnectionState
1299 wndToolbar->AddTool(ID_BUTTONCONNECT10333, wxT("...")L"...", m_tblist.GetBitmap(0));
1300
1301 wndToolbar->AddSeparator();
1302 wndToolbar->AddTool(ID_BUTTONNETWORKS10334, _("Networks")wxGetTranslation(("Networks")), m_tblist.GetBitmap(3), wxNullBitmap, wxITEM_CHECK, _("Networks Window")wxGetTranslation(("Networks Window")));
1303 wndToolbar->AddTool(ID_BUTTONSEARCH10335, _("Searches")wxGetTranslation(("Searches")), m_tblist.GetBitmap(5), wxNullBitmap, wxITEM_CHECK, _("Searches Window")wxGetTranslation(("Searches Window")));
1304 wndToolbar->AddTool(ID_BUTTONDOWNLOADS10336, _("Downloads")wxGetTranslation(("Downloads")), m_tblist.GetBitmap(4), wxNullBitmap, wxITEM_CHECK, _("Downloads Window")wxGetTranslation(("Downloads Window")));
1305 wndToolbar->AddTool(ID_BUTTONSHARED10337, _("Shared files")wxGetTranslation(("Shared files")), m_tblist.GetBitmap(6), wxNullBitmap, wxITEM_CHECK, _("Shared Files Window")wxGetTranslation(("Shared Files Window")));
1306 wndToolbar->AddTool(ID_BUTTONMESSAGES10338, _("Messages")wxGetTranslation(("Messages")), m_tblist.GetBitmap(7), wxNullBitmap, wxITEM_CHECK, _("Messages Window")wxGetTranslation(("Messages Window")));
1307 wndToolbar->AddTool(ID_BUTTONSTATISTICS10339, _("Statistics")wxGetTranslation(("Statistics")), m_tblist.GetBitmap(8), wxNullBitmap, wxITEM_CHECK, _("Statistics Graph Window")wxGetTranslation(("Statistics Graph Window")));
1308 wndToolbar->AddSeparator();
1309 wndToolbar->AddTool(ID_BUTTONNEWPREFERENCES10340, _("Preferences")wxGetTranslation(("Preferences")), m_tblist.GetBitmap(9), wxNullBitmap, wxITEM_NORMAL, _("Preferences Settings Window")wxGetTranslation(("Preferences Settings Window")));
1310#ifndef CLIENT_GUI
1311 wndToolbar->AddTool(ID_BUTTONIMPORT10341, _("Import")wxGetTranslation(("Import")), m_tblist.GetBitmap(10), wxNullBitmap, wxITEM_NORMAL, _("The partfile importer tool")wxGetTranslation(("The partfile importer tool")));
1312#endif
1313 wndToolbar->AddTool(ID_ABOUT10342, _("About")wxGetTranslation(("About")), m_tblist.GetBitmap(11), wxNullBitmap, wxITEM_NORMAL, _("About/Help")wxGetTranslation(("About/Help")));
1314
1315 wndToolbar->ToggleTool(ID_BUTTONDOWNLOADS10336, true);
1316
1317 // Needed for non-GTK platforms, where the
1318 // items don't get added immediately.
1319 wndToolbar->Realize();
1320
1321 // Updates the "Connect" button, and so on.
1322 ShowConnectionState(true);
1323}
1324
1325
1326void CamuleDlg::Create_Toolbar(bool orientation)
1327{
1328 Freeze();
1329 // Create ToolBar from the one designed by wxDesigner (BigBob)
1330 wxToolBar *current = GetToolBar();
1331
1332 wxASSERT(current == m_wndToolbar)do { if ( current == m_wndToolbar ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("amuleDlg.cpp", 1332, __FUNCTION__, "current == m_wndToolbar"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
1333
1334 if (current) {
1335 bool oldorientation = ((current->GetWindowStyle() & wxTB_VERTICAL) == wxTB_VERTICAL);
1336 if (oldorientation != orientation) {
1337 current->Destroy();
1338 SetToolBar(NULL__null); // Remove old one if present
1339 m_wndToolbar = NULL__null;
1340 } else {
1341 current->ClearTools();
1342 }
1343 }
1344
1345 if (!m_wndToolbar) {
1346 m_wndToolbar = CreateToolBar((orientation ? wxTB_VERTICAL : wxTB_HORIZONTAL) |
1347 wxNO_BORDERwxBORDER_NONE | wxTB_TEXT | wxTB_FLAT |
1348 wxCLIP_CHILDREN0x00400000 | wxTB_NODIVIDER);
1349
1350 m_wndToolbar->SetToolBitmapSize(wxSize(32, 32));
1351 }
1352
1353 Apply_Toolbar_Skin(m_wndToolbar);
1354
1355 Thaw();
1356}
1357
1358
1359void CamuleDlg::OnMainGUISizeChange(wxSizeEvent& evt)
1360{
1361 wxFrame::OnSize(evt);
1362 if (m_transferwnd && m_transferwnd->clientlistctrl) {
1363 // Transfer window's splitter set again if it's hidden.
1364 if (!m_transferwnd->clientlistctrl->GetShowing()) {
1365 int height = m_transferwnd->clientlistctrl->GetSize().GetHeight();
1366 wxSplitterWindow* splitter =
1367 CastChild(wxT("splitterWnd"), wxSplitterWindow)dynamic_cast<wxSplitterWindow*>( FindWindow( L"splitterWnd"
) )
;
1368 height += splitter->GetWindow1()->GetSize().GetHeight();
1369 splitter->SetSashPosition( height );
1370 }
1371 }
1372}
1373
1374
1375void CamuleDlg::OnKeyPressed(wxKeyEvent& event)
1376{
1377 if (event.GetKeyCode() == WXK_F1) {
1378 // Ctrl/Alt/Shift must not be pressed, to avoid
1379 // conflicts with other (global) shortcuts.
1380 if (!event.HasModifiers() && !event.ShiftDown()) {
1381 LaunchUrl(wxT("http://wiki.amule.org")L"http://wiki.amule.org");
1382 return;
1383 }
1384 }
1385
1386 event.Skip();
1387}
1388
1389
1390void CamuleDlg::OnExit(wxCommandEvent& WXUNUSED(evt))
1391{
1392 Close(true);
1393}
1394
1395void CamuleDlg::DoNetworkRearrange()
1396{
1397#if !defined(__WXOSX_COCOA__)
1398 // in Mac OS with wxWidgets >= 3.0 and COCOA the following seems to cause problems
1399 // (window is not refreshed after changes in network settings)
1400 wxWindowUpdateLocker freezer(this);
1401#endif
1402
1403 wxToolBarToolBase* toolbarTool = m_wndToolbar->FindById(ID_BUTTONNETWORKS10334);
1404
1405 // set the log windows
1406 wxNotebook* logs_notebook = CastChild( ID_SRVLOG_NOTEBOOK, wxNotebook)dynamic_cast<wxNotebook*>( FindWindow( 10252 ) );
1407
1408 while (logs_notebook->GetPageCount() > 1) {
1409 logs_notebook->RemovePage(logs_notebook->GetPageCount() - 1);
1410 }
1411
1412 if (thePrefs::GetNetworkED2K()) {
1413#ifndef CLIENT_GUI
1414 logs_notebook->AddPage(m_logpages[1].page, m_logpages[1].name);
1415#endif
1416 logs_notebook->AddPage(m_logpages[2].page, m_logpages[2].name);
1417 }
1418
1419 if (thePrefs::GetNetworkKademlia()) {
1420 logs_notebook->AddPage(m_logpages[3].page, m_logpages[3].name);
1421 }
1422
1423 // Set the main window.
1424 // If we have both networks active, activate a notebook to select between them.
1425 // If only one is active, show the window directly without a surrounding one tab notebook.
1426
1427 // States:
1428 // 1: ED2K only
1429 // 2: Kad only
1430 // 3: both (in Notebook)
1431
1432 static uint8 currentState = 3; // on startup we have both enabled
1433 uint8 newState;
1434 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
1435 newState = 3;
1436 toolbarTool->SetLabel(_("Networks")wxGetTranslation(("Networks")));
1437 }
1438 else if (thePrefs::GetNetworkED2K()) {
1439 newState = 1;
1440 toolbarTool->SetLabel(_("eD2k network")wxGetTranslation(("eD2k network")));
1441 }
1442 else { // Kad only or no network
1443 newState = 2; // no network makes no sense anyway, so just show Kad there
1444 toolbarTool->SetLabel(thePrefs::GetNetworkKademlia() ? _("Kad network")wxGetTranslation(("Kad network")) : _("No network")wxGetTranslation(("No network")));
1445 }
1446
1447 if (newState != currentState) {
1448 wxNotebook* networks_notebook = CastChild(ID_NETNOTEBOOK, wxNotebook)dynamic_cast<wxNotebook*>( FindWindow( 10317 ) );
1449 // First hide all windows
1450 networks_notebook->Show(false);
1451 m_networkpages[0].page->Show(false);
1452 m_networkpages[1].page->Show(false);
1453 m_networknotebooksizer->Clear();
1454
1455 wxWindow* replacement = NULL__null;
1456
1457 // Move both pages into the notebook if they aren't already there.
1458 if (currentState == 1) { // ED2K
1459 m_networkpages[0].page->Reparent(networks_notebook);
1460 networks_notebook->InsertPage(0, m_networkpages[0].page, m_networkpages[0].name);
1461 } else if (currentState == 2) { // Kad
1462 m_networkpages[1].page->Reparent(networks_notebook);
1463 networks_notebook->AddPage(m_networkpages[1].page, m_networkpages[1].name);
1464 }
1465
1466 // Now both pages are in the notebook. If we want to show one of them outside, move it back out again.
1467 // Windows that are part of a notebook can't be reparented.
1468 if (newState == 3) {
1469 // Since we messed with the notebook, we now have to show both pages, one after the other.
1470 // Otherwise GTK gets confused and shows the first tab only.
1471 // (So much for "platform independent".)
1472 networks_notebook->SetSelection(1);
1473 m_networkpages[1].page->Show();
1474 networks_notebook->SetSelection(0);
1475 m_networkpages[0].page->Show();
1476 replacement = networks_notebook;
1477 } else if (newState == 1) {
1478 replacement = m_networkpages[0].page;
1479 networks_notebook->RemovePage(0);
1480 } else {
1481 replacement = m_networkpages[1].page;
1482 networks_notebook->RemovePage(1);
1483 }
1484
1485 replacement->Reparent(m_networknotebooksizer->GetContainingWindow());
1486 replacement->Show();
1487 m_networknotebooksizer->Add(replacement, 1, wxGROW | wxALIGN_CENTER_VERTICAL | wxTOP, 5);
1488 m_networknotebooksizer->Layout();
1489 currentState = newState;
1490 }
1491
1492 // Tool bar
1493
1494 m_wndToolbar->EnableTool(ID_BUTTONNETWORKS10334, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()));
1495 m_wndToolbar->EnableTool(ID_BUTTONCONNECT10333, (thePrefs::GetNetworkED2K() || thePrefs::GetNetworkKademlia()) && theApp->ipfilter->IsReady());
1496
1497 ShowConnectionState(); // status in the bottom right
1498 m_searchwnd->FixSearchTypes();
1499}
1500
1501// File_checked_for_headers

/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/stl_vector.h

1// Vector implementation -*- C++ -*-
2
3// Copyright (C) 2001-2024 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/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_vector.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{vector}
54 */
55
56#ifndef _STL_VECTOR_H1
57#define _STL_VECTOR_H1 1
58
59#include <bits/stl_iterator_base_funcs.h>
60#include <bits/functexcept.h>
61#include <bits/concept_check.h>
62#if __cplusplus201703L >= 201103L
63#include <initializer_list>
64#endif
65#if __cplusplus201703L >= 202002L
66# include <compare>
67#endif
68
69#include <debug/assertions.h>
70
71#if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR
72extern "C" void
73__sanitizer_annotate_contiguous_container(const void*, const void*,
74 const void*, const void*);
75#endif
76
77namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
78{
79_GLIBCXX_BEGIN_NAMESPACE_VERSION
80_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
81
82 /// See bits/stl_deque.h's _Deque_base for an explanation.
83 template<typename _Tp, typename _Alloc>
84 struct _Vector_base
85 {
86 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
87 rebind<_Tp>::other _Tp_alloc_type;
88 typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
89 pointer;
90
91 struct _Vector_impl_data
92 {
93 pointer _M_start;
94 pointer _M_finish;
95 pointer _M_end_of_storage;
96
97 _GLIBCXX20_CONSTEXPR
98 _Vector_impl_data() _GLIBCXX_NOEXCEPTnoexcept
99 : _M_start(), _M_finish(), _M_end_of_storage()
100 { }
101
102#if __cplusplus201703L >= 201103L
103 _GLIBCXX20_CONSTEXPR
104 _Vector_impl_data(_Vector_impl_data&& __x) noexcept
105 : _M_start(__x._M_start), _M_finish(__x._M_finish),
106 _M_end_of_storage(__x._M_end_of_storage)
107 { __x._M_start = __x._M_finish = __x._M_end_of_storage = pointer(); }
108#endif
109
110 _GLIBCXX20_CONSTEXPR
111 void
112 _M_copy_data(_Vector_impl_data const& __x) _GLIBCXX_NOEXCEPTnoexcept
113 {
114 _M_start = __x._M_start;
115 _M_finish = __x._M_finish;
116 _M_end_of_storage = __x._M_end_of_storage;
117 }
118
119 _GLIBCXX20_CONSTEXPR
120 void
121 _M_swap_data(_Vector_impl_data& __x) _GLIBCXX_NOEXCEPTnoexcept
122 {
123 // Do not use std::swap(_M_start, __x._M_start), etc as it loses
124 // information used by TBAA.
125 _Vector_impl_data __tmp;
126 __tmp._M_copy_data(*this);
127 _M_copy_data(__x);
128 __x._M_copy_data(__tmp);
129 }
130 };
131
132 struct _Vector_impl
133 : public _Tp_alloc_type, public _Vector_impl_data
134 {
135 _GLIBCXX20_CONSTEXPR
136 _Vector_impl() _GLIBCXX_NOEXCEPT_IF(noexcept(is_nothrow_default_constructible<_Tp_alloc_type>
::value)
137 is_nothrow_default_constructible<_Tp_alloc_type>::value)noexcept(is_nothrow_default_constructible<_Tp_alloc_type>
::value)
138#if __cpp_lib_concepts
139 requires is_default_constructible_v<_Tp_alloc_type>
140#endif
141 : _Tp_alloc_type()
142 { }
143
144 _GLIBCXX20_CONSTEXPR
145 _Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPTnoexcept
146 : _Tp_alloc_type(__a)
147 { }
148
149#if __cplusplus201703L >= 201103L
150 // Not defaulted, to enforce noexcept(true) even when
151 // !is_nothrow_move_constructible<_Tp_alloc_type>.
152 _GLIBCXX20_CONSTEXPR
153 _Vector_impl(_Vector_impl&& __x) noexcept
154 : _Tp_alloc_type(std::move(__x)), _Vector_impl_data(std::move(__x))
155 { }
156
157 _GLIBCXX20_CONSTEXPR
158 _Vector_impl(_Tp_alloc_type&& __a) noexcept
159 : _Tp_alloc_type(std::move(__a))
160 { }
161
162 _GLIBCXX20_CONSTEXPR
163 _Vector_impl(_Tp_alloc_type&& __a, _Vector_impl&& __rv) noexcept
164 : _Tp_alloc_type(std::move(__a)), _Vector_impl_data(std::move(__rv))
165 { }
166#endif
167
168#if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR
169 template<typename = _Tp_alloc_type>
170 struct _Asan
171 {
172 typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>
173 ::size_type size_type;
174
175 static _GLIBCXX20_CONSTEXPR void
176 _S_shrink(_Vector_impl&, size_type) { }
177 static _GLIBCXX20_CONSTEXPR void
178 _S_on_dealloc(_Vector_impl&) { }
179
180 typedef _Vector_impl& _Reinit;
181
182 struct _Grow
183 {
184 _GLIBCXX20_CONSTEXPR _Grow(_Vector_impl&, size_type) { }
185 _GLIBCXX20_CONSTEXPR void _M_grew(size_type) { }
186 };
187 };
188
189 // Enable ASan annotations for memory obtained from std::allocator.
190 template<typename _Up>
191 struct _Asan<allocator<_Up> >
192 {
193 typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>
194 ::size_type size_type;
195
196 // Adjust ASan annotation for [_M_start, _M_end_of_storage) to
197 // mark end of valid region as __curr instead of __prev.
198 static _GLIBCXX20_CONSTEXPR void
199 _S_adjust(_Vector_impl& __impl, pointer __prev, pointer __curr)
200 {
201#if __cpp_lib_is_constant_evaluated
202 if (std::is_constant_evaluated())
203 return;
204#endif
205 __sanitizer_annotate_contiguous_container(__impl._M_start,
206 __impl._M_end_of_storage, __prev, __curr);
207 }
208
209 static _GLIBCXX20_CONSTEXPR void
210 _S_grow(_Vector_impl& __impl, size_type __n)
211 { _S_adjust(__impl, __impl._M_finish, __impl._M_finish + __n); }
212
213 static _GLIBCXX20_CONSTEXPR void
214 _S_shrink(_Vector_impl& __impl, size_type __n)
215 { _S_adjust(__impl, __impl._M_finish + __n, __impl._M_finish); }
216
217 static _GLIBCXX20_CONSTEXPR void
218 _S_on_dealloc(_Vector_impl& __impl)
219 {
220 if (__impl._M_start)
221 _S_adjust(__impl, __impl._M_finish, __impl._M_end_of_storage);
222 }
223
224 // Used on reallocation to tell ASan unused capacity is invalid.
225 struct _Reinit
226 {
227 explicit _GLIBCXX20_CONSTEXPR
228 _Reinit(_Vector_impl& __impl) : _M_impl(__impl)
229 {
230 // Mark unused capacity as valid again before deallocating it.
231 _S_on_dealloc(_M_impl);
232 }
233
234 _GLIBCXX20_CONSTEXPR
235 ~_Reinit()
236 {
237 // Mark unused capacity as invalid after reallocation.
238 if (_M_impl._M_start)
239 _S_adjust(_M_impl, _M_impl._M_end_of_storage,
240 _M_impl._M_finish);
241 }
242
243 _Vector_impl& _M_impl;
244
245#if __cplusplus201703L >= 201103L
246 _Reinit(const _Reinit&) = delete;
247 _Reinit& operator=(const _Reinit&) = delete;
248#endif
249 };
250
251 // Tell ASan when unused capacity is initialized to be valid.
252 struct _Grow
253 {
254 _GLIBCXX20_CONSTEXPR
255 _Grow(_Vector_impl& __impl, size_type __n)
256 : _M_impl(__impl), _M_n(__n)
257 { _S_grow(_M_impl, __n); }
258
259 _GLIBCXX20_CONSTEXPR
260 ~_Grow() { if (_M_n) _S_shrink(_M_impl, _M_n); }
261
262 _GLIBCXX20_CONSTEXPR
263 void _M_grew(size_type __n) { _M_n -= __n; }
264
265#if __cplusplus201703L >= 201103L
266 _Grow(const _Grow&) = delete;
267 _Grow& operator=(const _Grow&) = delete;
268#endif
269 private:
270 _Vector_impl& _M_impl;
271 size_type _M_n;
272 };
273 };
274
275#define _GLIBCXX_ASAN_ANNOTATE_REINIT \
276 typename _Base::_Vector_impl::template _Asan<>::_Reinit const \
277 __attribute__((__unused__)) __reinit_guard(this->_M_impl)
278#define _GLIBCXX_ASAN_ANNOTATE_GROW(n) \
279 typename _Base::_Vector_impl::template _Asan<>::_Grow \
280 __attribute__((__unused__)) __grow_guard(this->_M_impl, (n))
281#define _GLIBCXX_ASAN_ANNOTATE_GREW(n) __grow_guard._M_grew(n)
282#define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) \
283 _Base::_Vector_impl::template _Asan<>::_S_shrink(this->_M_impl, n)
284#define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC \
285 _Base::_Vector_impl::template _Asan<>::_S_on_dealloc(this->_M_impl)
286#else // ! (_GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR)
287#define _GLIBCXX_ASAN_ANNOTATE_REINIT
288#define _GLIBCXX_ASAN_ANNOTATE_GROW(n)
289#define _GLIBCXX_ASAN_ANNOTATE_GREW(n)
290#define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n)
291#define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC
292#endif // _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR
293 };
294
295 public:
296 typedef _Alloc allocator_type;
297
298 _GLIBCXX20_CONSTEXPR
299 _Tp_alloc_type&
300 _M_get_Tp_allocator() _GLIBCXX_NOEXCEPTnoexcept
301 { return this->_M_impl; }
302
303 _GLIBCXX20_CONSTEXPR
304 const _Tp_alloc_type&
305 _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPTnoexcept
306 { return this->_M_impl; }
307
308 _GLIBCXX20_CONSTEXPR
309 allocator_type
310 get_allocator() const _GLIBCXX_NOEXCEPTnoexcept
311 { return allocator_type(_M_get_Tp_allocator()); }
312
313#if __cplusplus201703L >= 201103L
314 _Vector_base() = default;
315#else
316 _Vector_base() { }
317#endif
318
319 _GLIBCXX20_CONSTEXPR
320 _Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPTnoexcept
321 : _M_impl(__a) { }
322
323 // Kept for ABI compatibility.
324#if !_GLIBCXX_INLINE_VERSION0
325 _GLIBCXX20_CONSTEXPR
326 _Vector_base(size_t __n)
327 : _M_impl()
328 { _M_create_storage(__n); }
329#endif
330
331 _GLIBCXX20_CONSTEXPR
332 _Vector_base(size_t __n, const allocator_type& __a)
333 : _M_impl(__a)
334 { _M_create_storage(__n); }
335
336#if __cplusplus201703L >= 201103L
337 _Vector_base(_Vector_base&&) = default;
338
339 // Kept for ABI compatibility.
340# if !_GLIBCXX_INLINE_VERSION0
341 _GLIBCXX20_CONSTEXPR
342 _Vector_base(_Tp_alloc_type&& __a) noexcept
343 : _M_impl(std::move(__a)) { }
344
345 _GLIBCXX20_CONSTEXPR
346 _Vector_base(_Vector_base&& __x, const allocator_type& __a)
347 : _M_impl(__a)
348 {
349 if (__x.get_allocator() == __a)
350 this->_M_impl._M_swap_data(__x._M_impl);
351 else
352 {
353 size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
354 _M_create_storage(__n);
355 }
356 }
357# endif
358
359 _GLIBCXX20_CONSTEXPR
360 _Vector_base(const allocator_type& __a, _Vector_base&& __x)
361 : _M_impl(_Tp_alloc_type(__a), std::move(__x._M_impl))
362 { }
363#endif
364
365 _GLIBCXX20_CONSTEXPR
366 ~_Vector_base() _GLIBCXX_NOEXCEPTnoexcept
367 {
368 _M_deallocate(_M_impl._M_start,
369 _M_impl._M_end_of_storage - _M_impl._M_start);
370 }
371
372 public:
373 _Vector_impl _M_impl;
374
375 _GLIBCXX20_CONSTEXPR
376 pointer
377 _M_allocate(size_t __n)
378 {
379 typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
380 return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
381 }
382
383 _GLIBCXX20_CONSTEXPR
384 void
385 _M_deallocate(pointer __p, size_t __n)
386 {
387 typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
388 if (__p)
389 _Tr::deallocate(_M_impl, __p, __n);
390 }
391
392 protected:
393
394 _GLIBCXX20_CONSTEXPR
395 void
396 _M_create_storage(size_t __n)
397 {
398 this->_M_impl._M_start = this->_M_allocate(__n);
399 this->_M_impl._M_finish = this->_M_impl._M_start;
400 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
401 }
402 };
403
404 /**
405 * @brief A standard container which offers fixed time access to
406 * individual elements in any order.
407 *
408 * @ingroup sequences
409 * @headerfile vector
410 * @since C++98
411 *
412 * @tparam _Tp Type of element.
413 * @tparam _Alloc Allocator type, defaults to allocator<_Tp>.
414 *
415 * Meets the requirements of a <a href="tables.html#65">container</a>, a
416 * <a href="tables.html#66">reversible container</a>, and a
417 * <a href="tables.html#67">sequence</a>, including the
418 * <a href="tables.html#68">optional sequence requirements</a> with the
419 * %exception of @c push_front and @c pop_front.
420 *
421 * In some terminology a %vector can be described as a dynamic
422 * C-style array, it offers fast and efficient access to individual
423 * elements in any order and saves the user from worrying about
424 * memory and size allocation. Subscripting ( @c [] ) access is
425 * also provided as with C-style arrays.
426 */
427 template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
428 class vector : protected _Vector_base<_Tp, _Alloc>
429 {
430#ifdef _GLIBCXX_CONCEPT_CHECKS
431 // Concept requirements.
432 typedef typename _Alloc::value_type _Alloc_value_type;
433# if __cplusplus201703L < 201103L
434 __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
435# endif
436 __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
437#endif
438
439#if __cplusplus201703L >= 201103L
440 static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
441 "std::vector must have a non-const, non-volatile value_type");
442# if __cplusplus201703L > 201703L || defined __STRICT_ANSI__
443 static_assert(is_same<typename _Alloc::value_type, _Tp>::value,
444 "std::vector must have the same value_type as its allocator");
445# endif
446#endif
447
448 typedef _Vector_base<_Tp, _Alloc> _Base;
449 typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
450 typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits;
451
452 public:
453 typedef _Tp value_type;
454 typedef typename _Base::pointer pointer;
455 typedef typename _Alloc_traits::const_pointer const_pointer;
456 typedef typename _Alloc_traits::reference reference;
457 typedef typename _Alloc_traits::const_reference const_reference;
458 typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
459 typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
460 const_iterator;
461 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
462 typedef std::reverse_iterator<iterator> reverse_iterator;
463 typedef size_t size_type;
464 typedef ptrdiff_t difference_type;
465 typedef _Alloc allocator_type;
466
467 private:
468#if __cplusplus201703L >= 201103L
469 static constexpr bool
470 _S_nothrow_relocate(true_type)
471 {
472 return noexcept(std::__relocate_a(std::declval<pointer>(),
473 std::declval<pointer>(),
474 std::declval<pointer>(),
475 std::declval<_Tp_alloc_type&>()));
476 }
477
478 static constexpr bool
479 _S_nothrow_relocate(false_type)
480 { return false; }
481
482 static constexpr bool
483 _S_use_relocate()
484 {
485 // Instantiating std::__relocate_a might cause an error outside the
486 // immediate context (in __relocate_object_a's noexcept-specifier),
487 // so only do it if we know the type can be move-inserted into *this.
488 return _S_nothrow_relocate(__is_move_insertable<_Tp_alloc_type>{});
489 }
490
491 static pointer
492 _S_do_relocate(pointer __first, pointer __last, pointer __result,
493 _Tp_alloc_type& __alloc, true_type) noexcept
494 {
495 return std::__relocate_a(__first, __last, __result, __alloc);
496 }
497
498 static pointer
499 _S_do_relocate(pointer, pointer, pointer __result,
500 _Tp_alloc_type&, false_type) noexcept
501 { return __result; }
502
503 static _GLIBCXX20_CONSTEXPR pointer
504 _S_relocate(pointer __first, pointer __last, pointer __result,
505 _Tp_alloc_type& __alloc) noexcept
506 {
507#if __cpp_if_constexpr201606L
508 // All callers have already checked _S_use_relocate() so just do it.
509 return std::__relocate_a(__first, __last, __result, __alloc);
510#else
511 using __do_it = __bool_constant<_S_use_relocate()>;
512 return _S_do_relocate(__first, __last, __result, __alloc, __do_it{});
513#endif
514 }
515#endif // C++11
516
517 protected:
518 using _Base::_M_allocate;
519 using _Base::_M_deallocate;
520 using _Base::_M_impl;
521 using _Base::_M_get_Tp_allocator;
522
523 public:
524 // [23.2.4.1] construct/copy/destroy
525 // (assign() and get_allocator() are also listed in this section)
526
527 /**
528 * @brief Creates a %vector with no elements.
529 */
530#if __cplusplus201703L >= 201103L
531 vector() = default;
532#else
533 vector() { }
534#endif
535
536 /**
537 * @brief Creates a %vector with no elements.
538 * @param __a An allocator object.
539 */
540 explicit
541 _GLIBCXX20_CONSTEXPR
542 vector(const allocator_type& __a) _GLIBCXX_NOEXCEPTnoexcept
543 : _Base(__a) { }
544
545#if __cplusplus201703L >= 201103L
546 /**
547 * @brief Creates a %vector with default constructed elements.
548 * @param __n The number of elements to initially create.
549 * @param __a An allocator.
550 *
551 * This constructor fills the %vector with @a __n default
552 * constructed elements.
553 */
554 explicit
555 _GLIBCXX20_CONSTEXPR
556 vector(size_type __n, const allocator_type& __a = allocator_type())
557 : _Base(_S_check_init_len(__n, __a), __a)
558 { _M_default_initialize(__n); }
559
560 /**
561 * @brief Creates a %vector with copies of an exemplar element.
562 * @param __n The number of elements to initially create.
563 * @param __value An element to copy.
564 * @param __a An allocator.
565 *
566 * This constructor fills the %vector with @a __n copies of @a __value.
567 */
568 _GLIBCXX20_CONSTEXPR
569 vector(size_type __n, const value_type& __value,
570 const allocator_type& __a = allocator_type())
571 : _Base(_S_check_init_len(__n, __a), __a)
572 { _M_fill_initialize(__n, __value); }
573#else
574 /**
575 * @brief Creates a %vector with copies of an exemplar element.
576 * @param __n The number of elements to initially create.
577 * @param __value An element to copy.
578 * @param __a An allocator.
579 *
580 * This constructor fills the %vector with @a __n copies of @a __value.
581 */
582 explicit
583 vector(size_type __n, const value_type& __value = value_type(),
584 const allocator_type& __a = allocator_type())
585 : _Base(_S_check_init_len(__n, __a), __a)
586 { _M_fill_initialize(__n, __value); }
587#endif
588
589 /**
590 * @brief %Vector copy constructor.
591 * @param __x A %vector of identical element and allocator types.
592 *
593 * All the elements of @a __x are copied, but any unused capacity in
594 * @a __x will not be copied
595 * (i.e. capacity() == size() in the new %vector).
596 *
597 * The newly-created %vector uses a copy of the allocator object used
598 * by @a __x (unless the allocator traits dictate a different object).
599 */
600 _GLIBCXX20_CONSTEXPR
601 vector(const vector& __x)
602 : _Base(__x.size(),
603 _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
604 {
605 this->_M_impl._M_finish =
606 std::__uninitialized_copy_a(__x.begin(), __x.end(),
607 this->_M_impl._M_start,
608 _M_get_Tp_allocator());
609 }
610
611#if __cplusplus201703L >= 201103L
612 /**
613 * @brief %Vector move constructor.
614 *
615 * The newly-created %vector contains the exact contents of the
616 * moved instance.
617 * The contents of the moved instance are a valid, but unspecified
618 * %vector.
619 */
620 vector(vector&&) noexcept = default;
621
622 /// Copy constructor with alternative allocator
623 _GLIBCXX20_CONSTEXPR
624 vector(const vector& __x, const __type_identity_t<allocator_type>& __a)
625 : _Base(__x.size(), __a)
626 {
627 this->_M_impl._M_finish =
628 std::__uninitialized_copy_a(__x.begin(), __x.end(),
629 this->_M_impl._M_start,
630 _M_get_Tp_allocator());
631 }
632
633 private:
634 _GLIBCXX20_CONSTEXPR
635 vector(vector&& __rv, const allocator_type& __m, true_type) noexcept
636 : _Base(__m, std::move(__rv))
637 { }
638
639 _GLIBCXX20_CONSTEXPR
640 vector(vector&& __rv, const allocator_type& __m, false_type)
641 : _Base(__m)
642 {
643 if (__rv.get_allocator() == __m)
644 this->_M_impl._M_swap_data(__rv._M_impl);
645 else if (!__rv.empty())
646 {
647 this->_M_create_storage(__rv.size());
648 this->_M_impl._M_finish =
649 std::__uninitialized_move_a(__rv.begin(), __rv.end(),
650 this->_M_impl._M_start,
651 _M_get_Tp_allocator());
652 __rv.clear();
653 }
654 }
655
656 public:
657 /// Move constructor with alternative allocator
658 _GLIBCXX20_CONSTEXPR
659 vector(vector&& __rv, const __type_identity_t<allocator_type>& __m)
660 noexcept( noexcept(
661 vector(std::declval<vector&&>(), std::declval<const allocator_type&>(),
662 std::declval<typename _Alloc_traits::is_always_equal>())) )
663 : vector(std::move(__rv), __m, typename _Alloc_traits::is_always_equal{})
664 { }
665
666 /**
667 * @brief Builds a %vector from an initializer list.
668 * @param __l An initializer_list.
669 * @param __a An allocator.
670 *
671 * Create a %vector consisting of copies of the elements in the
672 * initializer_list @a __l.
673 *
674 * This will call the element type's copy constructor N times
675 * (where N is @a __l.size()) and do no memory reallocation.
676 */
677 _GLIBCXX20_CONSTEXPR
678 vector(initializer_list<value_type> __l,
679 const allocator_type& __a = allocator_type())
680 : _Base(__a)
681 {
682 _M_range_initialize(__l.begin(), __l.end(),
683 random_access_iterator_tag());
684 }
685#endif
686
687 /**
688 * @brief Builds a %vector from a range.
689 * @param __first An input iterator.
690 * @param __last An input iterator.
691 * @param __a An allocator.
692 *
693 * Create a %vector consisting of copies of the elements from
694 * [first,last).
695 *
696 * If the iterators are forward, bidirectional, or
697 * random-access, then this will call the elements' copy
698 * constructor N times (where N is distance(first,last)) and do
699 * no memory reallocation. But if only input iterators are
700 * used, then this will do at most 2N calls to the copy
701 * constructor, and logN memory reallocations.
702 */
703#if __cplusplus201703L >= 201103L
704 template<typename _InputIterator,
705 typename = std::_RequireInputIter<_InputIterator>>
706 _GLIBCXX20_CONSTEXPR
707 vector(_InputIterator __first, _InputIterator __last,
708 const allocator_type& __a = allocator_type())
709 : _Base(__a)
710 {
711 _M_range_initialize(__first, __last,
712 std::__iterator_category(__first));
713 }
714#else
715 template<typename _InputIterator>
716 vector(_InputIterator __first, _InputIterator __last,
717 const allocator_type& __a = allocator_type())
718 : _Base(__a)
719 {
720 // Check whether it's an integral type. If so, it's not an iterator.
721 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
722 _M_initialize_dispatch(__first, __last, _Integral());
723 }
724#endif
725
726 /**
727 * The dtor only erases the elements, and note that if the
728 * elements themselves are pointers, the pointed-to memory is
729 * not touched in any way. Managing the pointer is the user's
730 * responsibility.
731 */
732 _GLIBCXX20_CONSTEXPR
733 ~vector() _GLIBCXX_NOEXCEPTnoexcept
734 {
735 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
736 _M_get_Tp_allocator());
737 _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC;
738 }
739
740 /**
741 * @brief %Vector assignment operator.
742 * @param __x A %vector of identical element and allocator types.
743 *
744 * All the elements of @a __x are copied, but any unused capacity in
745 * @a __x will not be copied.
746 *
747 * Whether the allocator is copied depends on the allocator traits.
748 */
749 _GLIBCXX20_CONSTEXPR
750 vector&
751 operator=(const vector& __x);
752
753#if __cplusplus201703L >= 201103L
754 /**
755 * @brief %Vector move assignment operator.
756 * @param __x A %vector of identical element and allocator types.
757 *
758 * The contents of @a __x are moved into this %vector (without copying,
759 * if the allocators permit it).
760 * Afterwards @a __x is a valid, but unspecified %vector.
761 *
762 * Whether the allocator is moved depends on the allocator traits.
763 */
764 _GLIBCXX20_CONSTEXPR
765 vector&
766 operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
767 {
768 constexpr bool __move_storage =
769 _Alloc_traits::_S_propagate_on_move_assign()
770 || _Alloc_traits::_S_always_equal();
771 _M_move_assign(std::move(__x), __bool_constant<__move_storage>());
772 return *this;
773 }
774
775 /**
776 * @brief %Vector list assignment operator.
777 * @param __l An initializer_list.
778 *
779 * This function fills a %vector with copies of the elements in the
780 * initializer list @a __l.
781 *
782 * Note that the assignment completely changes the %vector and
783 * that the resulting %vector's size is the same as the number
784 * of elements assigned.
785 */
786 _GLIBCXX20_CONSTEXPR
787 vector&
788 operator=(initializer_list<value_type> __l)
789 {
790 this->_M_assign_aux(__l.begin(), __l.end(),
791 random_access_iterator_tag());
792 return *this;
793 }
794#endif
795
796 /**
797 * @brief Assigns a given value to a %vector.
798 * @param __n Number of elements to be assigned.
799 * @param __val Value to be assigned.
800 *
801 * This function fills a %vector with @a __n copies of the given
802 * value. Note that the assignment completely changes the
803 * %vector and that the resulting %vector's size is the same as
804 * the number of elements assigned.
805 */
806 _GLIBCXX20_CONSTEXPR
807 void
808 assign(size_type __n, const value_type& __val)
809 { _M_fill_assign(__n, __val); }
810
811 /**
812 * @brief Assigns a range to a %vector.
813 * @param __first An input iterator.
814 * @param __last An input iterator.
815 *
816 * This function fills a %vector with copies of the elements in the
817 * range [__first,__last).
818 *
819 * Note that the assignment completely changes the %vector and
820 * that the resulting %vector's size is the same as the number
821 * of elements assigned.
822 */
823#if __cplusplus201703L >= 201103L
824 template<typename _InputIterator,
825 typename = std::_RequireInputIter<_InputIterator>>
826 _GLIBCXX20_CONSTEXPR
827 void
828 assign(_InputIterator __first, _InputIterator __last)
829 { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
830#else
831 template<typename _InputIterator>
832 void
833 assign(_InputIterator __first, _InputIterator __last)
834 {
835 // Check whether it's an integral type. If so, it's not an iterator.
836 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
837 _M_assign_dispatch(__first, __last, _Integral());
838 }
839#endif
840
841#if __cplusplus201703L >= 201103L
842 /**
843 * @brief Assigns an initializer list to a %vector.
844 * @param __l An initializer_list.
845 *
846 * This function fills a %vector with copies of the elements in the
847 * initializer list @a __l.
848 *
849 * Note that the assignment completely changes the %vector and
850 * that the resulting %vector's size is the same as the number
851 * of elements assigned.
852 */
853 _GLIBCXX20_CONSTEXPR
854 void
855 assign(initializer_list<value_type> __l)
856 {
857 this->_M_assign_aux(__l.begin(), __l.end(),
858 random_access_iterator_tag());
859 }
860#endif
861
862 /// Get a copy of the memory allocation object.
863 using _Base::get_allocator;
864
865 // iterators
866 /**
867 * Returns a read/write iterator that points to the first
868 * element in the %vector. Iteration is done in ordinary
869 * element order.
870 */
871 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
872 iterator
873 begin() _GLIBCXX_NOEXCEPTnoexcept
874 { return iterator(this->_M_impl._M_start); }
875
876 /**
877 * Returns a read-only (constant) iterator that points to the
878 * first element in the %vector. Iteration is done in ordinary
879 * element order.
880 */
881 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
882 const_iterator
883 begin() const _GLIBCXX_NOEXCEPTnoexcept
884 { return const_iterator(this->_M_impl._M_start); }
885
886 /**
887 * Returns a read/write iterator that points one past the last
888 * element in the %vector. Iteration is done in ordinary
889 * element order.
890 */
891 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
892 iterator
893 end() _GLIBCXX_NOEXCEPTnoexcept
894 { return iterator(this->_M_impl._M_finish); }
895
896 /**
897 * Returns a read-only (constant) iterator that points one past
898 * the last element in the %vector. Iteration is done in
899 * ordinary element order.
900 */
901 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
902 const_iterator
903 end() const _GLIBCXX_NOEXCEPTnoexcept
904 { return const_iterator(this->_M_impl._M_finish); }
905
906 /**
907 * Returns a read/write reverse iterator that points to the
908 * last element in the %vector. Iteration is done in reverse
909 * element order.
910 */
911 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
912 reverse_iterator
913 rbegin() _GLIBCXX_NOEXCEPTnoexcept
914 { return reverse_iterator(end()); }
915
916 /**
917 * Returns a read-only (constant) reverse iterator that points
918 * to the last element in the %vector. Iteration is done in
919 * reverse element order.
920 */
921 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
922 const_reverse_iterator
923 rbegin() const _GLIBCXX_NOEXCEPTnoexcept
924 { return const_reverse_iterator(end()); }
925
926 /**
927 * Returns a read/write reverse iterator that points to one
928 * before the first element in the %vector. Iteration is done
929 * in reverse element order.
930 */
931 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
932 reverse_iterator
933 rend() _GLIBCXX_NOEXCEPTnoexcept
934 { return reverse_iterator(begin()); }
935
936 /**
937 * Returns a read-only (constant) reverse iterator that points
938 * to one before the first element in the %vector. Iteration
939 * is done in reverse element order.
940 */
941 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
942 const_reverse_iterator
943 rend() const _GLIBCXX_NOEXCEPTnoexcept
944 { return const_reverse_iterator(begin()); }
945
946#if __cplusplus201703L >= 201103L
947 /**
948 * Returns a read-only (constant) iterator that points to the
949 * first element in the %vector. Iteration is done in ordinary
950 * element order.
951 */
952 [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
953 const_iterator
954 cbegin() const noexcept
955 { return const_iterator(this->_M_impl._M_start); }
956
957 /**
958 * Returns a read-only (constant) iterator that points one past
959 * the last element in the %vector. Iteration is done in
960 * ordinary element order.
961 */
962 [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
963 const_iterator
964 cend() const noexcept
965 { return const_iterator(this->_M_impl._M_finish); }
966
967 /**
968 * Returns a read-only (constant) reverse iterator that points
969 * to the last element in the %vector. Iteration is done in
970 * reverse element order.
971 */
972 [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
973 const_reverse_iterator
974 crbegin() const noexcept
975 { return const_reverse_iterator(end()); }
976
977 /**
978 * Returns a read-only (constant) reverse iterator that points
979 * to one before the first element in the %vector. Iteration
980 * is done in reverse element order.
981 */
982 [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
983 const_reverse_iterator
984 crend() const noexcept
985 { return const_reverse_iterator(begin()); }
986#endif
987
988 // [23.2.4.2] capacity
989 /** Returns the number of elements in the %vector. */
990 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
991 size_type
992 size() const _GLIBCXX_NOEXCEPTnoexcept
993 { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
994
995 /** Returns the size() of the largest possible %vector. */
996 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
997 size_type
998 max_size() const _GLIBCXX_NOEXCEPTnoexcept
999 { return _S_max_size(_M_get_Tp_allocator()); }
1000
1001#if __cplusplus201703L >= 201103L
1002 /**
1003 * @brief Resizes the %vector to the specified number of elements.
1004 * @param __new_size Number of elements the %vector should contain.
1005 *
1006 * This function will %resize the %vector to the specified
1007 * number of elements. If the number is smaller than the
1008 * %vector's current size the %vector is truncated, otherwise
1009 * default constructed elements are appended.
1010 */
1011 _GLIBCXX20_CONSTEXPR
1012 void
1013 resize(size_type __new_size)
1014 {
1015 if (__new_size > size())
1016 _M_default_append(__new_size - size());
1017 else if (__new_size < size())
1018 _M_erase_at_end(this->_M_impl._M_start + __new_size);
1019 }
1020
1021 /**
1022 * @brief Resizes the %vector to the specified number of elements.
1023 * @param __new_size Number of elements the %vector should contain.
1024 * @param __x Data with which new elements should be populated.
1025 *
1026 * This function will %resize the %vector to the specified
1027 * number of elements. If the number is smaller than the
1028 * %vector's current size the %vector is truncated, otherwise
1029 * the %vector is extended and new elements are populated with
1030 * given data.
1031 */
1032 _GLIBCXX20_CONSTEXPR
1033 void
1034 resize(size_type __new_size, const value_type& __x)
1035 {
1036 if (__new_size > size())
1037 _M_fill_insert(end(), __new_size - size(), __x);
1038 else if (__new_size < size())
1039 _M_erase_at_end(this->_M_impl._M_start + __new_size);
1040 }
1041#else
1042 /**
1043 * @brief Resizes the %vector to the specified number of elements.
1044 * @param __new_size Number of elements the %vector should contain.
1045 * @param __x Data with which new elements should be populated.
1046 *
1047 * This function will %resize the %vector to the specified
1048 * number of elements. If the number is smaller than the
1049 * %vector's current size the %vector is truncated, otherwise
1050 * the %vector is extended and new elements are populated with
1051 * given data.
1052 */
1053 _GLIBCXX20_CONSTEXPR
1054 void
1055 resize(size_type __new_size, value_type __x = value_type())
1056 {
1057 if (__new_size > size())
1058 _M_fill_insert(end(), __new_size - size(), __x);
1059 else if (__new_size < size())
1060 _M_erase_at_end(this->_M_impl._M_start + __new_size);
1061 }
1062#endif
1063
1064#if __cplusplus201703L >= 201103L
1065 /** A non-binding request to reduce capacity() to size(). */
1066 _GLIBCXX20_CONSTEXPR
1067 void
1068 shrink_to_fit()
1069 { _M_shrink_to_fit(); }
1070#endif
1071
1072 /**
1073 * Returns the total number of elements that the %vector can
1074 * hold before needing to allocate more memory.
1075 */
1076 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1077 size_type
1078 capacity() const _GLIBCXX_NOEXCEPTnoexcept
1079 {
1080 return size_type(this->_M_impl._M_end_of_storage
1081 - this->_M_impl._M_start);
1082 }
1083
1084 /**
1085 * Returns true if the %vector is empty. (Thus begin() would
1086 * equal end().)
1087 */
1088 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1089 bool
1090 empty() const _GLIBCXX_NOEXCEPTnoexcept
1091 { return begin() == end(); }
1092
1093 /**
1094 * @brief Attempt to preallocate enough memory for specified number of
1095 * elements.
1096 * @param __n Number of elements required.
1097 * @throw std::length_error If @a n exceeds @c max_size().
1098 *
1099 * This function attempts to reserve enough memory for the
1100 * %vector to hold the specified number of elements. If the
1101 * number requested is more than max_size(), length_error is
1102 * thrown.
1103 *
1104 * The advantage of this function is that if optimal code is a
1105 * necessity and the user can determine the number of elements
1106 * that will be required, the user can reserve the memory in
1107 * %advance, and thus prevent a possible reallocation of memory
1108 * and copying of %vector data.
1109 */
1110 _GLIBCXX20_CONSTEXPR
1111 void
1112 reserve(size_type __n);
1113
1114 // element access
1115 /**
1116 * @brief Subscript access to the data contained in the %vector.
1117 * @param __n The index of the element for which data should be
1118 * accessed.
1119 * @return Read/write reference to data.
1120 *
1121 * This operator allows for easy, array-style, data access.
1122 * Note that data access with this operator is unchecked and
1123 * out_of_range lookups are not defined. (For checked lookups
1124 * see at().)
1125 */
1126 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1127 reference
1128 operator[](size_type __n) _GLIBCXX_NOEXCEPTnoexcept
1129 {
1130 __glibcxx_requires_subscript(__n);
1131 return *(this->_M_impl._M_start + __n);
1132 }
1133
1134 /**
1135 * @brief Subscript access to the data contained in the %vector.
1136 * @param __n The index of the element for which data should be
1137 * accessed.
1138 * @return Read-only (constant) reference to data.
1139 *
1140 * This operator allows for easy, array-style, data access.
1141 * Note that data access with this operator is unchecked and
1142 * out_of_range lookups are not defined. (For checked lookups
1143 * see at().)
1144 */
1145 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1146 const_reference
1147 operator[](size_type __n) const _GLIBCXX_NOEXCEPTnoexcept
1148 {
1149 __glibcxx_requires_subscript(__n);
1150 return *(this->_M_impl._M_start + __n);
1151 }
1152
1153 protected:
1154 /// Safety check used only from at().
1155 _GLIBCXX20_CONSTEXPR
1156 void
1157 _M_range_check(size_type __n) const
1158 {
1159 if (__n >= this->size())
1160 __throw_out_of_range_fmt(__N("vector::_M_range_check: __n "("vector::_M_range_check: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1161 "(which is %zu) >= this->size() "("vector::_M_range_check: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
1162 "(which is %zu)")("vector::_M_range_check: __n " "(which is %zu) >= this->size() "
"(which is %zu)")
,
1163 __n, this->size());
1164 }
1165
1166 public:
1167 /**
1168 * @brief Provides access to the data contained in the %vector.
1169 * @param __n The index of the element for which data should be
1170 * accessed.
1171 * @return Read/write reference to data.
1172 * @throw std::out_of_range If @a __n is an invalid index.
1173 *
1174 * This function provides for safer data access. The parameter
1175 * is first checked that it is in the range of the vector. The
1176 * function throws out_of_range if the check fails.
1177 */
1178 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1179 reference
1180 at(size_type __n)
1181 {
1182 _M_range_check(__n);
1183 return (*this)[__n];
1184 }
1185
1186 /**
1187 * @brief Provides access to the data contained in the %vector.
1188 * @param __n The index of the element for which data should be
1189 * accessed.
1190 * @return Read-only (constant) reference to data.
1191 * @throw std::out_of_range If @a __n is an invalid index.
1192 *
1193 * This function provides for safer data access. The parameter
1194 * is first checked that it is in the range of the vector. The
1195 * function throws out_of_range if the check fails.
1196 */
1197 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1198 const_reference
1199 at(size_type __n) const
1200 {
1201 _M_range_check(__n);
1202 return (*this)[__n];
1203 }
1204
1205 /**
1206 * Returns a read/write reference to the data at the first
1207 * element of the %vector.
1208 */
1209 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1210 reference
1211 front() _GLIBCXX_NOEXCEPTnoexcept
1212 {
1213 __glibcxx_requires_nonempty();
1214 return *begin();
1215 }
1216
1217 /**
1218 * Returns a read-only (constant) reference to the data at the first
1219 * element of the %vector.
1220 */
1221 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1222 const_reference
1223 front() const _GLIBCXX_NOEXCEPTnoexcept
1224 {
1225 __glibcxx_requires_nonempty();
1226 return *begin();
1227 }
1228
1229 /**
1230 * Returns a read/write reference to the data at the last
1231 * element of the %vector.
1232 */
1233 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1234 reference
1235 back() _GLIBCXX_NOEXCEPTnoexcept
1236 {
1237 __glibcxx_requires_nonempty();
1238 return *(end() - 1);
1239 }
1240
1241 /**
1242 * Returns a read-only (constant) reference to the data at the
1243 * last element of the %vector.
1244 */
1245 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1246 const_reference
1247 back() const _GLIBCXX_NOEXCEPTnoexcept
1248 {
1249 __glibcxx_requires_nonempty();
1250 return *(end() - 1);
1251 }
1252
1253 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1254 // DR 464. Suggestion for new member functions in standard containers.
1255 // data access
1256 /**
1257 * Returns a pointer such that [data(), data() + size()) is a valid
1258 * range. For a non-empty %vector, data() == &front().
1259 */
1260 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1261 _Tp*
1262 data() _GLIBCXX_NOEXCEPTnoexcept
1263 { return _M_data_ptr(this->_M_impl._M_start); }
1264
1265 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1266 const _Tp*
1267 data() const _GLIBCXX_NOEXCEPTnoexcept
1268 { return _M_data_ptr(this->_M_impl._M_start); }
1269
1270 // [23.2.4.3] modifiers
1271 /**
1272 * @brief Add data to the end of the %vector.
1273 * @param __x Data to be added.
1274 *
1275 * This is a typical stack operation. The function creates an
1276 * element at the end of the %vector and assigns the given data
1277 * to it. Due to the nature of a %vector this operation can be
1278 * done in constant time if the %vector has preallocated space
1279 * available.
1280 */
1281 _GLIBCXX20_CONSTEXPR
1282 void
1283 push_back(const value_type& __x)
1284 {
1285 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
1286 {
1287 _GLIBCXX_ASAN_ANNOTATE_GROW(1);
1288 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
1289 __x);
1290 ++this->_M_impl._M_finish;
1291 _GLIBCXX_ASAN_ANNOTATE_GREW(1);
1292 }
1293 else
1294 _M_realloc_append(__x);
1295 }
1296
1297#if __cplusplus201703L >= 201103L
1298 _GLIBCXX20_CONSTEXPR
1299 void
1300 push_back(value_type&& __x)
1301 { emplace_back(std::move(__x)); }
1302
1303 template<typename... _Args>
1304#if __cplusplus201703L > 201402L
1305 _GLIBCXX20_CONSTEXPR
1306 reference
1307#else
1308 void
1309#endif
1310 emplace_back(_Args&&... __args);
1311#endif
1312
1313 /**
1314 * @brief Removes last element.
1315 *
1316 * This is a typical stack operation. It shrinks the %vector by one.
1317 *
1318 * Note that no data is returned, and if the last element's
1319 * data is needed, it should be retrieved before pop_back() is
1320 * called.
1321 */
1322 _GLIBCXX20_CONSTEXPR
1323 void
1324 pop_back() _GLIBCXX_NOEXCEPTnoexcept
1325 {
1326 __glibcxx_requires_nonempty();
1327 --this->_M_impl._M_finish;
1328 _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
1329 _GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
1330 }
1331
1332#if __cplusplus201703L >= 201103L
1333 /**
1334 * @brief Inserts an object in %vector before specified iterator.
1335 * @param __position A const_iterator into the %vector.
1336 * @param __args Arguments.
1337 * @return An iterator that points to the inserted data.
1338 *
1339 * This function will insert an object of type T constructed
1340 * with T(std::forward<Args>(args)...) before the specified location.
1341 * Note that this kind of operation could be expensive for a %vector
1342 * and if it is frequently used the user should consider using
1343 * std::list.
1344 */
1345 template<typename... _Args>
1346 _GLIBCXX20_CONSTEXPR
1347 iterator
1348 emplace(const_iterator __position, _Args&&... __args)
1349 { return _M_emplace_aux(__position, std::forward<_Args>(__args)...); }
1350
1351 /**
1352 * @brief Inserts given value into %vector before specified iterator.
1353 * @param __position A const_iterator into the %vector.
1354 * @param __x Data to be inserted.
1355 * @return An iterator that points to the inserted data.
1356 *
1357 * This function will insert a copy of the given value before
1358 * the specified location. Note that this kind of operation
1359 * could be expensive for a %vector and if it is frequently
1360 * used the user should consider using std::list.
1361 */
1362 _GLIBCXX20_CONSTEXPR
1363 iterator
1364 insert(const_iterator __position, const value_type& __x);
1365#else
1366 /**
1367 * @brief Inserts given value into %vector before specified iterator.
1368 * @param __position An iterator into the %vector.
1369 * @param __x Data to be inserted.
1370 * @return An iterator that points to the inserted data.
1371 *
1372 * This function will insert a copy of the given value before
1373 * the specified location. Note that this kind of operation
1374 * could be expensive for a %vector and if it is frequently
1375 * used the user should consider using std::list.
1376 */
1377 iterator
1378 insert(iterator __position, const value_type& __x);
1379#endif
1380
1381#if __cplusplus201703L >= 201103L
1382 /**
1383 * @brief Inserts given rvalue into %vector before specified iterator.
1384 * @param __position A const_iterator into the %vector.
1385 * @param __x Data to be inserted.
1386 * @return An iterator that points to the inserted data.
1387 *
1388 * This function will insert a copy of the given rvalue before
1389 * the specified location. Note that this kind of operation
1390 * could be expensive for a %vector and if it is frequently
1391 * used the user should consider using std::list.
1392 */
1393 _GLIBCXX20_CONSTEXPR
1394 iterator
1395 insert(const_iterator __position, value_type&& __x)
1396 { return _M_insert_rval(__position, std::move(__x)); }
1397
1398 /**
1399 * @brief Inserts an initializer_list into the %vector.
1400 * @param __position An iterator into the %vector.
1401 * @param __l An initializer_list.
1402 *
1403 * This function will insert copies of the data in the
1404 * initializer_list @a l into the %vector before the location
1405 * specified by @a position.
1406 *
1407 * Note that this kind of operation could be expensive for a
1408 * %vector and if it is frequently used the user should
1409 * consider using std::list.
1410 */
1411 _GLIBCXX20_CONSTEXPR
1412 iterator
1413 insert(const_iterator __position, initializer_list<value_type> __l)
1414 {
1415 auto __offset = __position - cbegin();
1416 _M_range_insert(begin() + __offset, __l.begin(), __l.end(),
1417 std::random_access_iterator_tag());
1418 return begin() + __offset;
1419 }
1420#endif
1421
1422#if __cplusplus201703L >= 201103L
1423 /**
1424 * @brief Inserts a number of copies of given data into the %vector.
1425 * @param __position A const_iterator into the %vector.
1426 * @param __n Number of elements to be inserted.
1427 * @param __x Data to be inserted.
1428 * @return An iterator that points to the inserted data.
1429 *
1430 * This function will insert a specified number of copies of
1431 * the given data before the location specified by @a position.
1432 *
1433 * Note that this kind of operation could be expensive for a
1434 * %vector and if it is frequently used the user should
1435 * consider using std::list.
1436 */
1437 _GLIBCXX20_CONSTEXPR
1438 iterator
1439 insert(const_iterator __position, size_type __n, const value_type& __x)
1440 {
1441 difference_type __offset = __position - cbegin();
1442 _M_fill_insert(begin() + __offset, __n, __x);
1443 return begin() + __offset;
1444 }
1445#else
1446 /**
1447 * @brief Inserts a number of copies of given data into the %vector.
1448 * @param __position An iterator into the %vector.
1449 * @param __n Number of elements to be inserted.
1450 * @param __x Data to be inserted.
1451 *
1452 * This function will insert a specified number of copies of
1453 * the given data before the location specified by @a position.
1454 *
1455 * Note that this kind of operation could be expensive for a
1456 * %vector and if it is frequently used the user should
1457 * consider using std::list.
1458 */
1459 void
1460 insert(iterator __position, size_type __n, const value_type& __x)
1461 { _M_fill_insert(__position, __n, __x); }
1462#endif
1463
1464#if __cplusplus201703L >= 201103L
1465 /**
1466 * @brief Inserts a range into the %vector.
1467 * @param __position A const_iterator into the %vector.
1468 * @param __first An input iterator.
1469 * @param __last An input iterator.
1470 * @return An iterator that points to the inserted data.
1471 *
1472 * This function will insert copies of the data in the range
1473 * [__first,__last) into the %vector before the location specified
1474 * by @a pos.
1475 *
1476 * Note that this kind of operation could be expensive for a
1477 * %vector and if it is frequently used the user should
1478 * consider using std::list.
1479 */
1480 template<typename _InputIterator,
1481 typename = std::_RequireInputIter<_InputIterator>>
1482 _GLIBCXX20_CONSTEXPR
1483 iterator
1484 insert(const_iterator __position, _InputIterator __first,
1485 _InputIterator __last)
1486 {
1487 difference_type __offset = __position - cbegin();
1488 _M_range_insert(begin() + __offset, __first, __last,
1489 std::__iterator_category(__first));
1490 return begin() + __offset;
1491 }
1492#else
1493 /**
1494 * @brief Inserts a range into the %vector.
1495 * @param __position An iterator into the %vector.
1496 * @param __first An input iterator.
1497 * @param __last An input iterator.
1498 *
1499 * This function will insert copies of the data in the range
1500 * [__first,__last) into the %vector before the location specified
1501 * by @a pos.
1502 *
1503 * Note that this kind of operation could be expensive for a
1504 * %vector and if it is frequently used the user should
1505 * consider using std::list.
1506 */
1507 template<typename _InputIterator>
1508 void
1509 insert(iterator __position, _InputIterator __first,
1510 _InputIterator __last)
1511 {
1512 // Check whether it's an integral type. If so, it's not an iterator.
1513 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1514 _M_insert_dispatch(__position, __first, __last, _Integral());
1515 }
1516#endif
1517
1518 /**
1519 * @brief Remove element at given position.
1520 * @param __position Iterator pointing to element to be erased.
1521 * @return An iterator pointing to the next element (or end()).
1522 *
1523 * This function will erase the element at the given position and thus
1524 * shorten the %vector by one.
1525 *
1526 * Note This operation could be expensive and if it is
1527 * frequently used the user should consider using std::list.
1528 * The user is also cautioned that this function only erases
1529 * the element, and that if the element is itself a pointer,
1530 * the pointed-to memory is not touched in any way. Managing
1531 * the pointer is the user's responsibility.
1532 */
1533 _GLIBCXX20_CONSTEXPR
1534 iterator
1535#if __cplusplus201703L >= 201103L
1536 erase(const_iterator __position)
1537 { return _M_erase(begin() + (__position - cbegin())); }
1538#else
1539 erase(iterator __position)
1540 { return _M_erase(__position); }
1541#endif
1542
1543 /**
1544 * @brief Remove a range of elements.
1545 * @param __first Iterator pointing to the first element to be erased.
1546 * @param __last Iterator pointing to one past the last element to be
1547 * erased.
1548 * @return An iterator pointing to the element pointed to by @a __last
1549 * prior to erasing (or end()).
1550 *
1551 * This function will erase the elements in the range
1552 * [__first,__last) and shorten the %vector accordingly.
1553 *
1554 * Note This operation could be expensive and if it is
1555 * frequently used the user should consider using std::list.
1556 * The user is also cautioned that this function only erases
1557 * the elements, and that if the elements themselves are
1558 * pointers, the pointed-to memory is not touched in any way.
1559 * Managing the pointer is the user's responsibility.
1560 */
1561 _GLIBCXX20_CONSTEXPR
1562 iterator
1563#if __cplusplus201703L >= 201103L
1564 erase(const_iterator __first, const_iterator __last)
1565 {
1566 const auto __beg = begin();
1567 const auto __cbeg = cbegin();
1568 return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
1569 }
1570#else
1571 erase(iterator __first, iterator __last)
1572 { return _M_erase(__first, __last); }
1573#endif
1574
1575 /**
1576 * @brief Swaps data with another %vector.
1577 * @param __x A %vector of the same element and allocator types.
1578 *
1579 * This exchanges the elements between two vectors in constant time.
1580 * (Three pointers, so it should be quite fast.)
1581 * Note that the global std::swap() function is specialized such that
1582 * std::swap(v1,v2) will feed to this function.
1583 *
1584 * Whether the allocators are swapped depends on the allocator traits.
1585 */
1586 _GLIBCXX20_CONSTEXPR
1587 void
1588 swap(vector& __x) _GLIBCXX_NOEXCEPTnoexcept
1589 {
1590#if __cplusplus201703L >= 201103L
1591 __glibcxx_assert(_Alloc_traits::propagate_on_container_swap::valuedo { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(_Alloc_traits::propagate_on_container_swap::value || _M_get_Tp_allocator
() == __x._M_get_Tp_allocator()), false)) std::__glibcxx_assert_fail
(); } while (false)
1592 || _M_get_Tp_allocator() == __x._M_get_Tp_allocator())do { if (std::__is_constant_evaluated()) if (__builtin_expect
(!bool(_Alloc_traits::propagate_on_container_swap::value || _M_get_Tp_allocator
() == __x._M_get_Tp_allocator()), false)) std::__glibcxx_assert_fail
(); } while (false)
;
1593#endif
1594 this->_M_impl._M_swap_data(__x._M_impl);
1595 _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
1596 __x._M_get_Tp_allocator());
1597 }
1598
1599 /**
1600 * Erases all the elements. Note that this function only erases the
1601 * elements, and that if the elements themselves are pointers, the
1602 * pointed-to memory is not touched in any way. Managing the pointer is
1603 * the user's responsibility.
1604 */
1605 _GLIBCXX20_CONSTEXPR
1606 void
1607 clear() _GLIBCXX_NOEXCEPTnoexcept
1608 { _M_erase_at_end(this->_M_impl._M_start); }
1609
1610 protected:
1611 /**
1612 * Memory expansion handler. Uses the member allocation function to
1613 * obtain @a n bytes of memory, and then copies [first,last) into it.
1614 */
1615 template<typename _ForwardIterator>
1616 _GLIBCXX20_CONSTEXPR
1617 pointer
1618 _M_allocate_and_copy(size_type __n,
1619 _ForwardIterator __first, _ForwardIterator __last)
1620 {
1621 pointer __result = this->_M_allocate(__n);
1622 __trytry
1623 {
1624 std::__uninitialized_copy_a(__first, __last, __result,
1625 _M_get_Tp_allocator());
1626 return __result;
1627 }
1628 __catch(...)catch(...)
1629 {
1630 _M_deallocate(__result, __n);
1631 __throw_exception_againthrow;
1632 }
1633 }
1634
1635
1636 // Internal constructor functions follow.
1637
1638 // Called by the range constructor to implement [23.1.1]/9
1639
1640#if __cplusplus201703L < 201103L
1641 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1642 // 438. Ambiguity in the "do the right thing" clause
1643 template<typename _Integer>
1644 void
1645 _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
1646 {
1647 this->_M_impl._M_start = _M_allocate(_S_check_init_len(
1648 static_cast<size_type>(__n), _M_get_Tp_allocator()));
1649 this->_M_impl._M_end_of_storage =
1650 this->_M_impl._M_start + static_cast<size_type>(__n);
1651 _M_fill_initialize(static_cast<size_type>(__n), __value);
1652 }
1653
1654 // Called by the range constructor to implement [23.1.1]/9
1655 template<typename _InputIterator>
1656 void
1657 _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
1658 __false_type)
1659 {
1660 _M_range_initialize(__first, __last,
1661 std::__iterator_category(__first));
1662 }
1663#endif
1664
1665 // Called by the second initialize_dispatch above
1666 template<typename _InputIterator>
1667 _GLIBCXX20_CONSTEXPR
1668 void
1669 _M_range_initialize(_InputIterator __first, _InputIterator __last,
1670 std::input_iterator_tag)
1671 {
1672 __trytry {
1673 for (; __first != __last; ++__first)
1674#if __cplusplus201703L >= 201103L
1675 emplace_back(*__first);
1676#else
1677 push_back(*__first);
1678#endif
1679 } __catch(...)catch(...) {
1680 clear();
1681 __throw_exception_againthrow;
1682 }
1683 }
1684
1685 // Called by the second initialize_dispatch above
1686 template<typename _ForwardIterator>
1687 _GLIBCXX20_CONSTEXPR
1688 void
1689 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
1690 std::forward_iterator_tag)
1691 {
1692 const size_type __n = std::distance(__first, __last);
1693 this->_M_impl._M_start
1694 = this->_M_allocate(_S_check_init_len(__n, _M_get_Tp_allocator()));
1695 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
1696 this->_M_impl._M_finish =
1697 std::__uninitialized_copy_a(__first, __last,
1698 this->_M_impl._M_start,
1699 _M_get_Tp_allocator());
1700 }
1701
1702 // Called by the first initialize_dispatch above and by the
1703 // vector(n,value,a) constructor.
1704 _GLIBCXX20_CONSTEXPR
1705 void
1706 _M_fill_initialize(size_type __n, const value_type& __value)
1707 {
1708 this->_M_impl._M_finish =
1709 std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
1710 _M_get_Tp_allocator());
1711 }
1712
1713#if __cplusplus201703L >= 201103L
1714 // Called by the vector(n) constructor.
1715 _GLIBCXX20_CONSTEXPR
1716 void
1717 _M_default_initialize(size_type __n)
1718 {
1719 this->_M_impl._M_finish =
1720 std::__uninitialized_default_n_a(this->_M_impl._M_start, __n,
1721 _M_get_Tp_allocator());
1722 }
1723#endif
1724
1725 // Internal assign functions follow. The *_aux functions do the actual
1726 // assignment work for the range versions.
1727
1728 // Called by the range assign to implement [23.1.1]/9
1729
1730 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1731 // 438. Ambiguity in the "do the right thing" clause
1732 template<typename _Integer>
1733 _GLIBCXX20_CONSTEXPR
1734 void
1735 _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
1736 { _M_fill_assign(__n, __val); }
1737
1738 // Called by the range assign to implement [23.1.1]/9
1739 template<typename _InputIterator>
1740 _GLIBCXX20_CONSTEXPR
1741 void
1742 _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
1743 __false_type)
1744 { _M_assign_aux(__first, __last, std::__iterator_category(__first)); }
1745
1746 // Called by the second assign_dispatch above
1747 template<typename _InputIterator>
1748 _GLIBCXX20_CONSTEXPR
1749 void
1750 _M_assign_aux(_InputIterator __first, _InputIterator __last,
1751 std::input_iterator_tag);
1752
1753 // Called by the second assign_dispatch above
1754 template<typename _ForwardIterator>
1755 _GLIBCXX20_CONSTEXPR
1756 void
1757 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
1758 std::forward_iterator_tag);
1759
1760 // Called by assign(n,t), and the range assign when it turns out
1761 // to be the same thing.
1762 _GLIBCXX20_CONSTEXPR
1763 void
1764 _M_fill_assign(size_type __n, const value_type& __val);
1765
1766 // Internal insert functions follow.
1767
1768 // Called by the range insert to implement [23.1.1]/9
1769
1770 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1771 // 438. Ambiguity in the "do the right thing" clause
1772 template<typename _Integer>
1773 _GLIBCXX20_CONSTEXPR
1774 void
1775 _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
1776 __true_type)
1777 { _M_fill_insert(__pos, __n, __val); }
1778
1779 // Called by the range insert to implement [23.1.1]/9
1780 template<typename _InputIterator>
1781 _GLIBCXX20_CONSTEXPR
1782 void
1783 _M_insert_dispatch(iterator __pos, _InputIterator __first,
1784 _InputIterator __last, __false_type)
1785 {
1786 _M_range_insert(__pos, __first, __last,
1787 std::__iterator_category(__first));
1788 }
1789
1790 // Called by the second insert_dispatch above
1791 template<typename _InputIterator>
1792 _GLIBCXX20_CONSTEXPR
1793 void
1794 _M_range_insert(iterator __pos, _InputIterator __first,
1795 _InputIterator __last, std::input_iterator_tag);
1796
1797 // Called by the second insert_dispatch above
1798 template<typename _ForwardIterator>
1799 _GLIBCXX20_CONSTEXPR
1800 void
1801 _M_range_insert(iterator __pos, _ForwardIterator __first,
1802 _ForwardIterator __last, std::forward_iterator_tag);
1803
1804 // Called by insert(p,n,x), and the range insert when it turns out to be
1805 // the same thing.
1806 _GLIBCXX20_CONSTEXPR
1807 void
1808 _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
1809
1810#if __cplusplus201703L >= 201103L
1811 // Called by resize(n).
1812 _GLIBCXX20_CONSTEXPR
1813 void
1814 _M_default_append(size_type __n);
1815
1816 _GLIBCXX20_CONSTEXPR
1817 bool
1818 _M_shrink_to_fit();
1819#endif
1820
1821#if __cplusplus201703L < 201103L
1822 // Called by insert(p,x)
1823 void
1824 _M_insert_aux(iterator __position, const value_type& __x);
1825
1826 void
1827 _M_realloc_insert(iterator __position, const value_type& __x);
1828
1829 void
1830 _M_realloc_append(const value_type& __x);
1831#else
1832 // A value_type object constructed with _Alloc_traits::construct()
1833 // and destroyed with _Alloc_traits::destroy().
1834 struct _Temporary_value
1835 {
1836 template<typename... _Args>
1837 _GLIBCXX20_CONSTEXPR explicit
1838 _Temporary_value(vector* __vec, _Args&&... __args) : _M_this(__vec)
1839 {
1840 _Alloc_traits::construct(_M_this->_M_impl, _M_ptr(),
1841 std::forward<_Args>(__args)...);
1842 }
1843
1844 _GLIBCXX20_CONSTEXPR
1845 ~_Temporary_value()
1846 { _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); }
1847
1848 _GLIBCXX20_CONSTEXPR value_type&
1849 _M_val() noexcept { return _M_storage._M_val; }
1850
1851 private:
1852 _GLIBCXX20_CONSTEXPR _Tp*
1853 _M_ptr() noexcept { return std::__addressof(_M_storage._M_val); }
1854
1855 union _Storage
1856 {
1857 constexpr _Storage() : _M_byte() { }
1858 _GLIBCXX20_CONSTEXPR ~_Storage() { }
1859 _Storage& operator=(const _Storage&) = delete;
1860 unsigned char _M_byte;
1861 _Tp _M_val;
1862 };
1863
1864 vector* _M_this;
1865 _Storage _M_storage;
1866 };
1867
1868 // Called by insert(p,x) and other functions when insertion needs to
1869 // reallocate or move existing elements. _Arg is either _Tp& or _Tp.
1870 template<typename _Arg>
1871 _GLIBCXX20_CONSTEXPR
1872 void
1873 _M_insert_aux(iterator __position, _Arg&& __arg);
1874
1875 template<typename... _Args>
1876 _GLIBCXX20_CONSTEXPR
1877 void
1878 _M_realloc_insert(iterator __position, _Args&&... __args);
1879
1880 template<typename... _Args>
1881 _GLIBCXX20_CONSTEXPR
1882 void
1883 _M_realloc_append(_Args&&... __args);
1884
1885 // Either move-construct at the end, or forward to _M_insert_aux.
1886 _GLIBCXX20_CONSTEXPR
1887 iterator
1888 _M_insert_rval(const_iterator __position, value_type&& __v);
1889
1890 // Try to emplace at the end, otherwise forward to _M_insert_aux.
1891 template<typename... _Args>
1892 _GLIBCXX20_CONSTEXPR
1893 iterator
1894 _M_emplace_aux(const_iterator __position, _Args&&... __args);
1895
1896 // Emplacing an rvalue of the correct type can use _M_insert_rval.
1897 _GLIBCXX20_CONSTEXPR
1898 iterator
1899 _M_emplace_aux(const_iterator __position, value_type&& __v)
1900 { return _M_insert_rval(__position, std::move(__v)); }
1901#endif
1902
1903 // Called by _M_fill_insert, _M_insert_aux etc.
1904 _GLIBCXX20_CONSTEXPR
1905 size_type
1906 _M_check_len(size_type __n, const char* __s) const
1907 {
1908 if (max_size() - size() < __n)
1909 __throw_length_error(__N(__s)(__s));
1910
1911 const size_type __len = size() + (std::max)(size(), __n);
1912 return (__len < size() || __len > max_size()) ? max_size() : __len;
1913 }
1914
1915 // Called by constructors to check initial size.
1916 static _GLIBCXX20_CONSTEXPR size_type
1917 _S_check_init_len(size_type __n, const allocator_type& __a)
1918 {
1919 if (__n > _S_max_size(_Tp_alloc_type(__a)))
1920 __throw_length_error(
1921 __N("cannot create std::vector larger than max_size()")("cannot create std::vector larger than max_size()"));
1922 return __n;
1923 }
1924
1925 static _GLIBCXX20_CONSTEXPR size_type
1926 _S_max_size(const _Tp_alloc_type& __a) _GLIBCXX_NOEXCEPTnoexcept
1927 {
1928 // std::distance(begin(), end()) cannot be greater than PTRDIFF_MAX,
1929 // and realistically we can't store more than PTRDIFF_MAX/sizeof(T)
1930 // (even if std::allocator_traits::max_size says we can).
1931 const size_t __diffmax
1932 = __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp);
1933 const size_t __allocmax = _Alloc_traits::max_size(__a);
1934 return (std::min)(__diffmax, __allocmax);
1935 }
1936
1937 // Internal erase functions follow.
1938
1939 // Called by erase(q1,q2), clear(), resize(), _M_fill_assign,
1940 // _M_assign_aux.
1941 _GLIBCXX20_CONSTEXPR
1942 void
1943 _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPTnoexcept
1944 {
1945 if (size_type __n = this->_M_impl._M_finish - __pos)
1946 {
1947 std::_Destroy(__pos, this->_M_impl._M_finish,
1948 _M_get_Tp_allocator());
1949 this->_M_impl._M_finish = __pos;
1950 _GLIBCXX_ASAN_ANNOTATE_SHRINK(__n);
1951 }
1952 }
1953
1954 _GLIBCXX20_CONSTEXPR
1955 iterator
1956 _M_erase(iterator __position);
1957
1958 _GLIBCXX20_CONSTEXPR
1959 iterator
1960 _M_erase(iterator __first, iterator __last);
1961
1962#if __cplusplus201703L >= 201103L
1963 private:
1964 // Constant-time move assignment when source object's memory can be
1965 // moved, either because the source's allocator will move too
1966 // or because the allocators are equal.
1967 _GLIBCXX20_CONSTEXPR
1968 void
1969 _M_move_assign(vector&& __x, true_type) noexcept
1970 {
1971 vector __tmp(get_allocator());
1972 this->_M_impl._M_swap_data(__x._M_impl);
1973 __tmp._M_impl._M_swap_data(__x._M_impl);
1974 std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator());
1975 }
1976
1977 // Do move assignment when it might not be possible to move source
1978 // object's memory, resulting in a linear-time operation.
1979 _GLIBCXX20_CONSTEXPR
1980 void
1981 _M_move_assign(vector&& __x, false_type)
1982 {
1983 if (__x._M_get_Tp_allocator() == this->_M_get_Tp_allocator())
1984 _M_move_assign(std::move(__x), true_type());
1985 else
1986 {
1987 // The rvalue's allocator cannot be moved and is not equal,
1988 // so we need to individually move each element.
1989 this->_M_assign_aux(std::make_move_iterator(__x.begin()),
1990 std::make_move_iterator(__x.end()),
1991 std::random_access_iterator_tag());
1992 __x.clear();
1993 }
1994 }
1995#endif
1996
1997 template<typename _Up>
1998 _GLIBCXX20_CONSTEXPR
1999 _Up*
2000 _M_data_ptr(_Up* __ptr) const _GLIBCXX_NOEXCEPTnoexcept
2001 { return __ptr; }
2002
2003#if __cplusplus201703L >= 201103L
2004 template<typename _Ptr>
2005 _GLIBCXX20_CONSTEXPR
2006 typename std::pointer_traits<_Ptr>::element_type*
2007 _M_data_ptr(_Ptr __ptr) const
2008 { return empty() ? nullptr : std::__to_address(__ptr); }
2009#else
2010 template<typename _Up>
2011 _Up*
2012 _M_data_ptr(_Up* __ptr) _GLIBCXX_NOEXCEPTnoexcept
2013 { return __ptr; }
2014
2015 template<typename _Ptr>
2016 value_type*
2017 _M_data_ptr(_Ptr __ptr)
2018 { return empty() ? (value_type*)0 : __ptr.operator->(); }
2019
2020 template<typename _Ptr>
2021 const value_type*
2022 _M_data_ptr(_Ptr __ptr) const
2023 { return empty() ? (const value_type*)0 : __ptr.operator->(); }
2024#endif
2025 };
2026
2027#if __cpp_deduction_guides201703L >= 201606
2028 template<typename _InputIterator, typename _ValT
2029 = typename iterator_traits<_InputIterator>::value_type,
2030 typename _Allocator = allocator<_ValT>,
2031 typename = _RequireInputIter<_InputIterator>,
2032 typename = _RequireAllocator<_Allocator>>
2033 vector(_InputIterator, _InputIterator, _Allocator = _Allocator())
2034 -> vector<_ValT, _Allocator>;
2035#endif
2036
2037 /**
2038 * @brief Vector equality comparison.
2039 * @param __x A %vector.
2040 * @param __y A %vector of the same type as @a __x.
2041 * @return True iff the size and elements of the vectors are equal.
2042 *
2043 * This is an equivalence relation. It is linear in the size of the
2044 * vectors. Vectors are considered equivalent if their sizes are equal,
2045 * and if corresponding elements compare equal.
2046 */
2047 template<typename _Tp, typename _Alloc>
2048 _GLIBCXX_NODISCARD[[__nodiscard__]] _GLIBCXX20_CONSTEXPR
2049 inline bool
2050 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2051 { return (__x.size() == __y.size()
2052 && std::equal(__x.begin(), __x.end(), __y.begin())); }
2053
2054#if __cpp_lib_three_way_comparison // >= C++20
2055 /**
2056 * @brief Vector ordering relation.
2057 * @param __x A `vector`.
2058 * @param __y A `vector` of the same type as `__x`.
2059 * @return A value indicating whether `__x` is less than, equal to,
2060 * greater than, or incomparable with `__y`.
2061 *
2062 * See `std::lexicographical_compare_three_way()` for how the determination
2063 * is made. This operator is used to synthesize relational operators like
2064 * `<` and `>=` etc.
2065 */
2066 template<typename _Tp, typename _Alloc>
2067 [[nodiscard]]
2068 constexpr __detail::__synth3way_t<_Tp>
2069 operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2070 {
2071 return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
2072 __y.begin(), __y.end(),
2073 __detail::__synth3way);
2074 }
2075#else
2076 /**
2077 * @brief Vector ordering relation.
2078 * @param __x A %vector.
2079 * @param __y A %vector of the same type as @a __x.
2080 * @return True iff @a __x is lexicographically less than @a __y.
2081 *
2082 * This is a total ordering relation. It is linear in the size of the
2083 * vectors. The elements must be comparable with @c <.
2084 *
2085 * See std::lexicographical_compare() for how the determination is made.
2086 */
2087 template<typename _Tp, typename _Alloc>
2088 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
2089 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2090 { return std::lexicographical_compare(__x.begin(), __x.end(),
2091 __y.begin(), __y.end()); }
2092
2093 /// Based on operator==
2094 template<typename _Tp, typename _Alloc>
2095 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
2096 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2097 { return !(__x == __y); }
2098
2099 /// Based on operator<
2100 template<typename _Tp, typename _Alloc>
2101 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
2102 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2103 { return __y < __x; }
2104
2105 /// Based on operator<
2106 template<typename _Tp, typename _Alloc>
2107 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
2108 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2109 { return !(__y < __x); }
2110
2111 /// Based on operator<
2112 template<typename _Tp, typename _Alloc>
2113 _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool
2114 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
2115 { return !(__x < __y); }
2116#endif // three-way comparison
2117
2118 /// See std::vector::swap().
2119 template<typename _Tp, typename _Alloc>
2120 _GLIBCXX20_CONSTEXPR
2121 inline void
2122 swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
2123 _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))noexcept(noexcept(__x.swap(__y)))
2124 { __x.swap(__y); }
2125
2126_GLIBCXX_END_NAMESPACE_CONTAINER
2127
2128#if __cplusplus201703L >= 201703L
2129 namespace __detail::__variant
2130 {
2131 template<typename> struct _Never_valueless_alt; // see <variant>
2132
2133 // Provide the strong exception-safety guarantee when emplacing a
2134 // vector into a variant, but only if move assignment cannot throw.
2135 template<typename _Tp, typename _Alloc>
2136 struct _Never_valueless_alt<_GLIBCXX_STD_Cstd::vector<_Tp, _Alloc>>
2137 : std::is_nothrow_move_assignable<_GLIBCXX_STD_Cstd::vector<_Tp, _Alloc>>
2138 { };
2139 } // namespace __detail::__variant
2140#endif // C++17
2141
2142_GLIBCXX_END_NAMESPACE_VERSION
2143} // namespace std
2144
2145#endif /* _STL_VECTOR_H */

/usr/include/wx-3.2/wx/generic/panelg.h

1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/generic/panelg.h
3// Purpose: wxPanel: a container for child controls
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// Copyright: (c) Julian Smart
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifndef _WX_GENERIC_PANELG_H_
12#define _WX_GENERIC_PANELG_H_
13
14#include "wx/bitmap.h"
15
16class WXDLLIMPEXP_CORE__attribute__ ((visibility("default"))) wxPanel : public wxPanelBase
17{
18public:
19 wxPanel() { }
20
21 // Constructor
22 wxPanel(wxWindow *parent,
23 wxWindowID winid = wxID_ANY,
24 const wxPoint& pos = wxDefaultPosition,
25 const wxSize& size = wxDefaultSize,
26 long style = wxTAB_TRAVERSAL0x00080000 | wxNO_BORDERwxBORDER_NONE,
27 const wxString& name = wxASCII_STR(wxPanelNameStr)wxString::FromAscii(wxPanelNameStr))
28 {
29 Create(parent, winid, pos, size, style, name);
30 }
31
32#if WXWIN_COMPATIBILITY_2_80
33 wxDEPRECATED_CONSTRUCTOR(__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
34 wxPanel(wxWindow *parent,__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
35 int x, int y, int width, int height,__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
36 long style = wxTAB_TRAVERSAL | wxNO_BORDER,__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
37 const wxString& name = wxASCII_STR(wxPanelNameStr))__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
38 {__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
39 Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height), style, name);__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
40 }__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
41 )__attribute__((deprecated)) wxPanel(wxWindow *parent, int x, int
y, int width, int height, long style = 0x00080000 | wxBORDER_NONE
, const wxString& name = wxString::FromAscii(wxPanelNameStr
)) { Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height
), style, name); }
42#endif // WXWIN_COMPATIBILITY_2_8
43
44private:
45 wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxPanel)private: wxPanel(const wxPanel&) = delete; wxPanel& operator
=(const wxPanel&) = delete; public: GCC diagnostic push GCC
diagnostic ignored "-Wsuggest-override" GCC diagnostic push
GCC diagnostic ignored "-Winconsistent-missing-override" virtual
wxClassInfo *GetClassInfo() const ; GCC diagnostic pop GCC diagnostic
pop static wxClassInfo ms_classInfo; static wxObject* wxCreateObject
()
;
46};
47
48#endif // _WX_GENERIC_PANELG_H_

/usr/include/wx-3.2/wx/translation.h

1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/translation.h
3// Purpose: Internationalization and localisation for wxWidgets
4// Author: Vadim Zeitlin, Vaclav Slavik,
5// Michael N. Filippov <michael@idisys.iae.nsk.su>
6// Created: 2010-04-23
7// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8// (c) 2010 Vaclav Slavik <vslavik@fastmail.fm>
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_TRANSLATION_H_
13#define _WX_TRANSLATION_H_
14
15#include "wx/defs.h"
16#include "wx/string.h"
17
18#if wxUSE_INTL1
19
20#include "wx/buffer.h"
21#include "wx/language.h"
22#include "wx/hashmap.h"
23#include "wx/strconv.h"
24#include "wx/scopedptr.h"
25
26// ============================================================================
27// global decls
28// ============================================================================
29
30// ----------------------------------------------------------------------------
31// macros
32// ----------------------------------------------------------------------------
33
34// gettext() style macros (notice that xgettext should be invoked with
35// --keyword="_" --keyword="wxPLURAL:1,2" options
36// to extract the strings from the sources)
37#ifndef WXINTL_NO_GETTEXT_MACRO
38#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
39 #define _(s)wxGetTranslation((s)) wxGetTranslation((s))
40#else
41 #define _(s)wxGetTranslation((s)) wxGetTranslation(wxASCII_STR(s)wxString::FromAscii(s))
42#endif
43 #define wxPLURAL(sing, plur, n)wxGetTranslation((sing), (plur), n) wxGetTranslation((sing), (plur), n)
44#endif
45
46// wx-specific macro for translating strings in the given context: if you use
47// them, you need to also add
48// --keyword="wxGETTEXT_IN_CONTEXT:1c,2" --keyword="wxGETTEXT_IN_CONTEXT_PLURAL:1c,2,3"
49// options to xgettext invocation.
50#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
51#define wxGETTEXT_IN_CONTEXT(c, s)wxGetTranslation((s), wxString(), c) \
52 wxGetTranslation((s), wxString(), c)
53#else
54#define wxGETTEXT_IN_CONTEXT(c, s)wxGetTranslation((s), wxString(), c) \
55 wxGetTranslation(wxASCII_STR(s)wxString::FromAscii(s), wxString(), c)
56#endif
57#define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n)wxGetTranslation((sing), (plur), n, wxString(), c) \
58 wxGetTranslation((sing), (plur), n, wxString(), c)
59
60// another one which just marks the strings for extraction, but doesn't
61// perform the translation (use -kwxTRANSLATE with xgettext!)
62#define wxTRANSLATE(str)str str
63
64// another one which just marks the strings, with a context, for extraction,
65// but doesn't perform the translation (use -kwxTRANSLATE_IN_CONTEXT:1c,2 with
66// xgettext!)
67#define wxTRANSLATE_IN_CONTEXT(c, str)str str
68
69// ----------------------------------------------------------------------------
70// forward decls
71// ----------------------------------------------------------------------------
72
73class WXDLLIMPEXP_FWD_BASE wxArrayString;
74class WXDLLIMPEXP_FWD_BASE wxTranslationsLoader;
75class WXDLLIMPEXP_FWD_BASE wxLocale;
76
77class wxPluralFormsCalculator;
78wxDECLARE_SCOPED_PTR(wxPluralFormsCalculator, wxPluralFormsCalculatorPtr)class wxPluralFormsCalculatorPtr { private: wxPluralFormsCalculator
* m_ptr; wxPluralFormsCalculatorPtr(wxPluralFormsCalculatorPtr
const &); wxPluralFormsCalculatorPtr & operator=(wxPluralFormsCalculatorPtr
const &); public: explicit wxPluralFormsCalculatorPtr(wxPluralFormsCalculator
* ptr = __null) : m_ptr(ptr) { } ~wxPluralFormsCalculatorPtr
(); void reset(wxPluralFormsCalculator * ptr = __null); wxPluralFormsCalculator
*release() { wxPluralFormsCalculator *ptr = m_ptr; m_ptr = __null
; return ptr; } wxPluralFormsCalculator & operator*() const
{ do { if ( m_ptr != __null ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("/usr/include/wx-3.2/wx/translation.h"
, 78, __FUNCTION__, "m_ptr != __null", (const char*)__null), wxTrapInAssert
) ) { wxTrapInAssert = false; asm volatile ("int $3"); } } while
( (void)0, 0 ); return *m_ptr; } wxPluralFormsCalculator * operator
->() const { do { if ( m_ptr != __null ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("/usr/include/wx-3.2/wx/translation.h"
, 78, __FUNCTION__, "m_ptr != __null", (const char*)__null), wxTrapInAssert
) ) { wxTrapInAssert = false; asm volatile ("int $3"); } } while
( (void)0, 0 ); return m_ptr; } wxPluralFormsCalculator * get
() const { return m_ptr; } void swap(wxPluralFormsCalculatorPtr
& ot) { wxPluralFormsCalculator * tmp = ot.m_ptr; ot.m_ptr
= m_ptr; m_ptr = tmp; } };
79
80// ----------------------------------------------------------------------------
81// wxMsgCatalog corresponds to one loaded message catalog.
82// ----------------------------------------------------------------------------
83
84class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxMsgCatalog
85{
86public:
87 // Ctor is protected, because CreateFromXXX functions must be used,
88 // but destruction should be unrestricted
89#if !wxUSE_UNICODE1
90 ~wxMsgCatalog();
91#endif
92
93 // load the catalog from disk or from data; caller is responsible for
94 // deleting them if not NULL
95 static wxMsgCatalog *CreateFromFile(const wxString& filename,
96 const wxString& domain);
97
98 static wxMsgCatalog *CreateFromData(const wxScopedCharBuffer& data,
99 const wxString& domain);
100
101 // get name of the catalog
102 wxString GetDomain() const { return m_domain; }
103
104 // get the translated string: returns NULL if not found
105 const wxString *GetString(const wxString& sz, unsigned n = UINT_MAX(2147483647 *2U +1U), const wxString& ct = wxEmptyString) const;
106
107protected:
108 wxMsgCatalog(const wxString& domain)
109 : m_pNext(NULL__null), m_domain(domain)
110#if !wxUSE_UNICODE1
111 , m_conv(NULL__null)
112#endif
113 {}
114
115private:
116 // variable pointing to the next element in a linked list (or NULL)
117 wxMsgCatalog *m_pNext;
118 friend class wxTranslations;
119
120 wxStringToStringHashMap m_messages; // all messages in the catalog
121 wxString m_domain; // name of the domain
122
123#if !wxUSE_UNICODE1
124 // the conversion corresponding to this catalog charset if we installed it
125 // as the global one
126 wxCSConv *m_conv;
127#endif
128
129 wxPluralFormsCalculatorPtr m_pluralFormsCalculator;
130};
131
132// ----------------------------------------------------------------------------
133// wxTranslations: message catalogs
134// ----------------------------------------------------------------------------
135
136// this class allows to get translations for strings
137class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxTranslations
138{
139public:
140 wxTranslations();
141 ~wxTranslations();
142
143 // returns current translations object, may return NULL
144 static wxTranslations *Get();
145 // sets current translations object (takes ownership; may be NULL)
146 static void Set(wxTranslations *t);
147
148 // changes loader to non-default one; takes ownership of 'loader'
149 void SetLoader(wxTranslationsLoader *loader);
150
151 void SetLanguage(wxLanguage lang);
152 void SetLanguage(const wxString& lang);
153
154 // get languages available for this app
155 wxArrayString GetAvailableTranslations(const wxString& domain) const;
156
157#if wxABI_VERSION( 3 * 10000 + 2 * 100 + 99 ) >= 30203
158 // find best available translation language for given domain
159 wxString GetBestAvailableTranslation(const wxString& domain);
160#endif // wxABI_VERSION >= 3.2.3
161
162 wxString GetBestTranslation(const wxString& domain, wxLanguage msgIdLanguage);
163 wxString GetBestTranslation(const wxString& domain,
164 const wxString& msgIdLanguage = wxASCII_STR("en")wxString::FromAscii("en"));
165
166#if wxABI_VERSION( 3 * 10000 + 2 * 100 + 99 ) >= 30203
167 // add catalog for the given domain returning true if it could be found by
168 // wxTranslationsLoader
169 bool AddAvailableCatalog(const wxString& domain);
170#endif // wxABI_VERSION >= 3.2.3
171#if wxABI_VERSION( 3 * 10000 + 2 * 100 + 99 ) >= 30206
172 bool AddAvailableCatalog(const wxString& domain, wxLanguage msgIdLanguage);
173#endif // wxABI_VERSION >= 3.2.5
174
175 // add standard wxWidgets catalog ("wxstd")
176 bool AddStdCatalog();
177
178 // add catalog with given domain name and language, looking it up via
179 // wxTranslationsLoader -- unlike AddAvailableCatalog(), this function also
180 // returns true if this catalog is not needed at all because msgIdLanguage
181 // is an acceptable language to use directly
182 bool AddCatalog(const wxString& domain,
183 wxLanguage msgIdLanguage = wxLANGUAGE_ENGLISH_US);
184#if !wxUSE_UNICODE1
185 bool AddCatalog(const wxString& domain,
186 wxLanguage msgIdLanguage,
187 const wxString& msgIdCharset);
188#endif
189
190 // check if the given catalog is loaded
191 bool IsLoaded(const wxString& domain) const;
192
193 // access to translations
194 const wxString *GetTranslatedString(const wxString& origString,
195 const wxString& domain = wxEmptyString,
196 const wxString& context = wxEmptyString) const;
197 const wxString *GetTranslatedString(const wxString& origString,
198 unsigned n,
199 const wxString& domain = wxEmptyString,
200 const wxString& context = wxEmptyString) const;
201
202 wxString GetHeaderValue(const wxString& header,
203 const wxString& domain = wxEmptyString) const;
204
205 // this is hack to work around a problem with wxGetTranslation() which
206 // returns const wxString& and not wxString, so when it returns untranslated
207 // string, it needs to have a copy of it somewhere
208 static const wxString& GetUntranslatedString(const wxString& str);
209
210private:
211 enum Translations
212 {
213 Translations_NotNeeded = -1,
214 Translations_NotFound = 0,
215 Translations_Found = 1
216 };
217
218 Translations DoAddCatalog(const wxString& domain, wxLanguage msgIdLanguage);
219
220 // perform loading of the catalog via m_loader
221 bool LoadCatalog(const wxString& domain, const wxString& lang, const wxString& msgIdLang);
222
223 // find catalog by name in a linked list, return NULL if !found
224 wxMsgCatalog *FindCatalog(const wxString& domain) const;
225
226 // same as Set(), without taking ownership; only for wxLocale
227 static void SetNonOwned(wxTranslations *t);
228 friend class wxLocale;
229
230 wxString DoGetBestAvailableTranslation(const wxString& domain, const wxString& additionalAvailableLanguage);
231
232private:
233 wxString m_lang;
234 wxTranslationsLoader *m_loader;
235
236 wxMsgCatalog *m_pMsgCat; // pointer to linked list of catalogs
237
238 // In addition to keeping all the catalogs in the linked list, we also
239 // store them in a hash map indexed by the domain name to allow finding
240 // them by name efficiently.
241 WX_DECLARE_HASH_MAP(wxString, wxMsgCatalog *, wxStringHash, wxStringEqual, wxMsgCatalogMap)class wxMsgCatalogMap_wxImplementation_Pair { public: typedef
wxString first_type; typedef wxMsgCatalog * second_type; typedef
wxString t1; typedef wxMsgCatalog * t2; typedef const wxString
const_t1; typedef const wxMsgCatalog * const_t2; wxMsgCatalogMap_wxImplementation_Pair
(const const_t1& f, const const_t2& s) : first(const_cast
<t1&>(f)), second(const_cast<t2&>(s)) {} t1
first; t2 second; }; class wxMsgCatalogMap_wxImplementation_KeyEx
{ typedef wxString key_type; typedef wxMsgCatalogMap_wxImplementation_Pair
pair_type; typedef const key_type const_key_type; typedef const
pair_type const_pair_type; typedef const_key_type& const_key_reference
; typedef const_pair_type& const_pair_reference; public: wxMsgCatalogMap_wxImplementation_KeyEx
() { } const_key_reference operator()( const_pair_reference pair
) const { return pair.first; }}; class wxMsgCatalogMap_wxImplementation_HashTable
: protected _wxHashTableBase2 { public: typedef wxString key_type
; typedef wxMsgCatalogMap_wxImplementation_Pair value_type; typedef
wxStringHash hasher; typedef wxStringEqual key_equal; typedef
size_t size_type; typedef ptrdiff_t difference_type; typedef
value_type* pointer; typedef const value_type* const_pointer
; typedef value_type& reference; typedef const value_type
& const_reference; typedef const wxString const_key_type;
typedef const wxMsgCatalogMap_wxImplementation_Pair const_mapped_type
; public: typedef wxMsgCatalogMap_wxImplementation_KeyEx key_extractor
; typedef wxMsgCatalogMap_wxImplementation_HashTable Self; protected
: _wxHashTable_NodeBase** m_table; size_t m_tableBuckets; size_t
m_items; hasher m_hasher; key_equal m_equals; key_extractor m_getKey
; public: struct Node:public _wxHashTable_NodeBase { public: Node
( const value_type& value ) : m_value( value ) {} Node* next
() { return static_cast<Node*>(m_next); } value_type m_value
; }; protected: static void DeleteNode( _wxHashTable_NodeBase
* node ) { delete static_cast<Node*>(node); } public: class
Iterator { public: Node* m_node; Self* m_ht; Iterator() : m_node
(__null), m_ht(__null) {} Iterator( Node* node, const Self* ht
) : m_node(node), m_ht(const_cast<Self*>(ht)) {} bool operator
==( const Iterator& it ) const { return m_node == it.m_node
; } bool operator !=( const Iterator& it ) const { return
m_node != it.m_node; } protected: Node* GetNextNode() { size_type
bucket = GetBucketForNode(m_ht,m_node); for( size_type i = bucket
+ 1; i < m_ht->m_tableBuckets; ++i ) { if( m_ht->m_table
[i] ) return static_cast<Node*>(m_ht->m_table[i]); }
return __null; } void PlusPlus() { Node* next = m_node->next
(); m_node = next ? next : GetNextNode(); } }; friend class Iterator
; public: class iterator : public Iterator { public: iterator
() : Iterator() {} iterator( Node* node, Self* ht ) : Iterator
( node, ht ) {} iterator& operator++() { PlusPlus(); return
*this; } iterator operator++(int) { iterator it=*this;PlusPlus
();return it; } reference operator *() const { return m_node->
m_value; } pointer operator ->() const { return &(m_node
->m_value); } }; class const_iterator : public Iterator { public
: const_iterator() : Iterator() {} const_iterator(iterator i)
: Iterator(i) {} const_iterator( Node* node, const Self* ht )
: Iterator(node, const_cast<Self*>(ht)) {} const_iterator
& operator++() { PlusPlus();return *this; } const_iterator
operator++(int) { const_iterator it=*this;PlusPlus();return it
; } const_reference operator *() const { return m_node->m_value
; } const_pointer operator ->() const { return &(m_node
->m_value); } }; wxMsgCatalogMap_wxImplementation_HashTable
( size_type sz = 10, const hasher& hfun = hasher(), const
key_equal& k_eq = key_equal(), const key_extractor& k_ex
= key_extractor() ) : m_tableBuckets( GetNextPrime( (unsigned
long) sz ) ), m_items( 0 ), m_hasher( hfun ), m_equals( k_eq
), m_getKey( k_ex ) { m_table = (_wxHashTable_NodeBase**)AllocTable
(m_tableBuckets); } wxMsgCatalogMap_wxImplementation_HashTable
( const Self& ht ) : m_table(__null), m_tableBuckets( 0 )
, m_items( ht.m_items ), m_hasher( ht.m_hasher ), m_equals( ht
.m_equals ), m_getKey( ht.m_getKey ) { HashCopy( ht ); } const
Self& operator=( const Self& ht ) { if (&ht != this
) { clear(); m_hasher = ht.m_hasher; m_equals = ht.m_equals; m_getKey
= ht.m_getKey; m_items = ht.m_items; HashCopy( ht ); } return
*this; } ~wxMsgCatalogMap_wxImplementation_HashTable() { clear
(); FreeTable(m_table); } hasher hash_funct() { return m_hasher
; } key_equal key_eq() { return m_equals; } void clear() { DeleteNodes
(m_tableBuckets, m_table, DeleteNode); m_items = 0; } size_type
size() const { return m_items; } size_type max_size() const {
return size_type(-1); } bool empty() const { return size() ==
0; } const_iterator end() const { return const_iterator(__null
, this); } iterator end() { return iterator(__null, this); } const_iterator
begin() const { return const_iterator(static_cast<Node*>
(GetFirstNode(m_tableBuckets, m_table)), this); } iterator begin
() { return iterator(static_cast<Node*>(GetFirstNode(m_tableBuckets
, m_table)), this); } size_type erase( const const_key_type&
key ) { _wxHashTable_NodeBase** node = GetNodePtr(key); if( !
node ) return 0; --m_items; _wxHashTable_NodeBase* temp = (*node
)->m_next; delete static_cast<Node*>(*node); (*node)
= temp; if( never_shrink( m_tableBuckets, m_items ) ) ResizeTable
( GetPreviousPrime( (unsigned long) m_tableBuckets ) - 1 ); return
1; } protected: static size_type GetBucketForNode( Self* ht,
Node* node ) { return ht->m_hasher( ht->m_getKey( node
->m_value ) ) % ht->m_tableBuckets; } static Node* CopyNode
( Node* node ) { return new Node( *node ); } Node* GetOrCreateNode
( const value_type& value, bool& created ) { const const_key_type
& key = m_getKey( value ); size_t bucket = m_hasher( key )
% m_tableBuckets; Node* node = static_cast<Node*>(m_table
[bucket]); while( node ) { if( m_equals( m_getKey( node->m_value
), key ) ) { created = false; return node; } node = node->
next(); } created = true; return CreateNode( value, bucket); }
Node * CreateNode( const value_type& value, size_t bucket
) { Node* node = new Node( value ); node->m_next = m_table
[bucket]; m_table[bucket] = node; ++m_items; if( grow_lf70( m_tableBuckets
, m_items ) ) ResizeTable( m_tableBuckets ); return node; } void
CreateNode( const value_type& value ) { CreateNode(value
, m_hasher( m_getKey(value) ) % m_tableBuckets ); } _wxHashTable_NodeBase
** GetNodePtr(const const_key_type& key) const { size_t bucket
= m_hasher( key ) % m_tableBuckets; _wxHashTable_NodeBase** node
= &m_table[bucket]; while( *node ) { if (m_equals(m_getKey
(static_cast<Node*>(*node)->m_value), key)) return node
; node = &(*node)->m_next; } return __null; } Node* GetNode
( const const_key_type& key ) const { size_t bucket = m_hasher
( key ) % m_tableBuckets; Node* node = static_cast<Node*>
(m_table[bucket]); while( node ) { if( m_equals( m_getKey( node
->m_value ), key ) ) return node; node = node->next(); }
return __null; } void ResizeTable( size_t newSize ) { newSize
= GetNextPrime( (unsigned long)newSize ); _wxHashTable_NodeBase
** srcTable = m_table; size_t srcBuckets = m_tableBuckets; m_table
= (_wxHashTable_NodeBase**)AllocTable( newSize ); m_tableBuckets
= newSize; CopyHashTable( srcTable, srcBuckets, this, m_table
, (BucketFromNode)GetBucketForNode, (ProcessNode)&DummyProcessNode
); FreeTable(srcTable); } void HashCopy( const Self& ht )
{ ResizeTable( ht.size() ); CopyHashTable( ht.m_table, ht.m_tableBuckets
, (_wxHashTableBase2*)this, m_table, (BucketFromNode)GetBucketForNode
, (ProcessNode)CopyNode ); } }; class wxMsgCatalogMap:public wxMsgCatalogMap_wxImplementation_HashTable
{ public: typedef wxMsgCatalog * mapped_type; class Insert_Result
{ public: typedef iterator first_type; typedef bool second_type
; typedef iterator t1; typedef bool t2; typedef const iterator
const_t1; typedef const bool const_t2; Insert_Result(const const_t1
& f, const const_t2& s) : first(const_cast<t1&
>(f)), second(const_cast<t2&>(s)) {} t1 first; t2
second; }; explicit wxMsgCatalogMap( size_type hint = 100, hasher
hf = hasher(), key_equal eq = key_equal() ) : wxMsgCatalogMap_wxImplementation_HashTable
( hint, hf, eq, wxMsgCatalogMap_wxImplementation_KeyEx() ) {}
mapped_type& operator[]( const const_key_type& key )
{ bool created; return GetOrCreateNode( wxMsgCatalogMap_wxImplementation_Pair
( key, mapped_type() ), created)->m_value.second; } const_iterator
find( const const_key_type& key ) const { return const_iterator
( GetNode( key ), this ); } iterator find( const const_key_type
& key ) { return iterator( GetNode( key ), this ); } Insert_Result
insert( const value_type& v ) { bool created; Node *node
= GetOrCreateNode( wxMsgCatalogMap_wxImplementation_Pair( v.
first, v.second ), created); return Insert_Result(iterator(node
, this), created); } size_type erase( const key_type& k )
{ return wxMsgCatalogMap_wxImplementation_HashTable::erase( k
); } void erase( const iterator& it ) { erase( (*it).first
); } size_type count( const const_key_type& key ) { return
GetNode( key ) ? 1u : 0u; } }
;
242 wxMsgCatalogMap m_catalogMap;
243};
244
245
246// abstraction of translations discovery and loading
247class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxTranslationsLoader
248{
249public:
250 wxTranslationsLoader() {}
251 virtual ~wxTranslationsLoader() {}
252
253 virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
254 const wxString& lang) = 0;
255
256 virtual wxArrayString GetAvailableTranslations(const wxString& domain) const = 0;
257};
258
259
260// standard wxTranslationsLoader implementation, using filesystem
261class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxFileTranslationsLoader
262 : public wxTranslationsLoader
263{
264public:
265 static void AddCatalogLookupPathPrefix(const wxString& prefix);
266
267 virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
268 const wxString& lang) wxOVERRIDEoverride;
269
270 virtual wxArrayString GetAvailableTranslations(const wxString& domain) const wxOVERRIDEoverride;
271};
272
273
274#ifdef __WINDOWS__
275// loads translations from win32 resources
276class WXDLLIMPEXP_BASE__attribute__ ((visibility("default"))) wxResourceTranslationsLoader
277 : public wxTranslationsLoader
278{
279public:
280 virtual wxMsgCatalog *LoadCatalog(const wxString& domain,
281 const wxString& lang) wxOVERRIDEoverride;
282
283 virtual wxArrayString GetAvailableTranslations(const wxString& domain) const wxOVERRIDEoverride;
284
285protected:
286 // returns resource type to use for translations
287 virtual wxString GetResourceType() const { return wxASCII_STR("MOFILE")wxString::FromAscii("MOFILE"); }
288
289 // returns module to load resources from
290 virtual WXHINSTANCE GetModule() const { return NULL__null; }
291};
292#endif // __WINDOWS__
293
294
295// ----------------------------------------------------------------------------
296// global functions
297// ----------------------------------------------------------------------------
298
299// get the translation of the string in the current locale
300inline const wxString& wxGetTranslation(const wxString& str,
301 const wxString& domain = wxString(),
302 const wxString& context = wxString())
303{
304 wxTranslations *trans = wxTranslations::Get();
305 const wxString *transStr = trans ? trans->GetTranslatedString(str, domain, context)
306 : NULL__null;
307 if ( transStr )
308 return *transStr;
309 else
310 // NB: this function returns reference to a string, so we have to keep
311 // a copy of it somewhere
312 return wxTranslations::GetUntranslatedString(str);
313}
314
315inline const wxString& wxGetTranslation(const wxString& str1,
316 const wxString& str2,
317 unsigned n,
318 const wxString& domain = wxString(),
319 const wxString& context = wxString())
320{
321 wxTranslations *trans = wxTranslations::Get();
322 const wxString *transStr = trans ? trans->GetTranslatedString(str1, n, domain, context)
323 : NULL__null;
324 if ( transStr )
325 return *transStr;
326 else
327 // NB: this function returns reference to a string, so we have to keep
328 // a copy of it somewhere
329 return n == 1
330 ? wxTranslations::GetUntranslatedString(str1)
331 : wxTranslations::GetUntranslatedString(str2);
332}
333
334#ifdef wxNO_IMPLICIT_WXSTRING_ENCODING
335
336/*
337 * It must always be possible to call wxGetTranslation() with const
338 * char* arguments.
339 */
340inline const wxString& wxGetTranslation(const char *str,
341 const char *domain = "",
342 const char *context = "") {
343 const wxMBConv &conv = wxConvWhateverWorkswxGet_wxConvWhateverWorks();
344 return wxGetTranslation(wxString(str, conv), wxString(domain, conv),
345 wxString(context, conv));
346}
347
348inline const wxString& wxGetTranslation(const char *str1,
349 const char *str2,
350 unsigned n,
351 const char *domain = "",
352 const char *context = "") {
353 const wxMBConv &conv = wxConvWhateverWorkswxGet_wxConvWhateverWorks();
354 return wxGetTranslation(wxString(str1, conv), wxString(str2, conv), n,
355 wxString(domain, conv),
356 wxString(context, conv));
357}
358
359#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
360
361#else // !wxUSE_INTL
362
363// the macros should still be defined - otherwise compilation would fail
364
365#if !defined(WXINTL_NO_GETTEXT_MACRO)
366 #if !defined(_)
367#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
368 #define _(s)wxGetTranslation((s)) (s)
369#else
370 #define _(s)wxGetTranslation((s)) wxASCII_STR(s)wxString::FromAscii(s)
371#endif
372 #endif
373 #define wxPLURAL(sing, plur, n)wxGetTranslation((sing), (plur), n) ((n) == 1 ? (sing) : (plur))
374 #define wxGETTEXT_IN_CONTEXT(c, s)wxGetTranslation((s), wxString(), c) (s)
375 #define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n)wxGetTranslation((sing), (plur), n, wxString(), c) wxPLURAL(sing, plur, n)wxGetTranslation((sing), (plur), n)
376#endif
377
378#define wxTRANSLATE(str)str str
379#define wxTRANSLATE_IN_CONTEXT(c, str)str str
380
381// NB: we use a template here in order to avoid using
382// wxLocale::GetUntranslatedString() above, which would be required if
383// we returned const wxString&; this way, the compiler should be able to
384// optimize wxGetTranslation() away
385
386template<typename TString>
387inline TString wxGetTranslation(TString str)
388 { return str; }
389
390template<typename TString, typename TDomain>
391inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain))
392 { return str; }
393
394template<typename TString, typename TDomain, typename TContext>
395inline TString wxGetTranslation(TString str, TDomain WXUNUSED(domain), TContext WXUNUSED(context))
396 { return str; }
397
398template<typename TString, typename TDomain>
399inline TString wxGetTranslation(TString str1, TString str2, size_t n)
400 { return n == 1 ? str1 : str2; }
401
402template<typename TString, typename TDomain>
403inline TString wxGetTranslation(TString str1, TString str2, size_t n,
404 TDomain WXUNUSED(domain))
405 { return n == 1 ? str1 : str2; }
406
407template<typename TString, typename TDomain, typename TContext>
408inline TString wxGetTranslation(TString str1, TString str2, size_t n,
409 TDomain WXUNUSED(domain),
410 TContext WXUNUSED(context))
411 { return n == 1 ? str1 : str2; }
412
413#endif // wxUSE_INTL/!wxUSE_INTL
414
415// define this one just in case it occurs somewhere (instead of preferred
416// wxTRANSLATE) too
417#if !defined(WXINTL_NO_GETTEXT_MACRO)
418 #if !defined(gettext_noop)
419 #define gettext_noop(str)(str) (str)
420 #endif
421 #if !defined(N_)
422 #define N_(s)(s) (s)
423 #endif
424#endif
425
426#endif // _WX_TRANSLATION_H_