YSTest: XCB.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

XCB.cpp
浏览该文件的文档.
1 /*
2 © 2014-2016, 2018 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
29 #include "YCLib/YModules.h"
30 #include YFM_YCLib_Platform // for YSLib::Drawing, YSLib::RecordLevel,
31 // YSLib::Err, YSLib::Informative, platform::Deref, platform::Nonnull,
32 // YTraceDe;
33 #if YF_Use_XCB
34 # include <ystdex/array.hpp> // for ystdex::cast_array;
35 # include YFM_YCLib_XCB // for YSLib::FilterExceptions;
36 # include YFM_YCLib_Mutex // for platform::Concurrency, platform::Threading;
37 # include <xcb/xcb.h> // for ::uint32_t, ::uint8_t;
38 # include <ystdex/addressof.hpp> // for ystdex::pvoid;
39 # include <ystdex/type_pun.hpp> // for ystdex::aligned_store_cast;
40
41 using namespace YSLib::Drawing;
43
44 using YSLib::RecordLevel;
45 using YSLib::Err;
46 using YSLib::Informative;
47 using platform::Deref;
48 using platform::Nonnull;
50 using namespace platform::Concurrency;
52 using namespace platform::Threading;
53 using ystdex::cast_array;
54
55 namespace platform_ex
56 {
57
58 namespace XCB
59 {
60
62 static_assert(std::is_same<Atom::NativeType, ::xcb_atom_t>(),
63 "Invalid type found.");
65 static_assert(ystdex::and_<std::is_same<WindowData::ID, ::xcb_window_t>,
66 std::is_same<WindowData::ID, ::xcb_drawable_t>>(),
67 "Invalid type found.");
68
70 namespace
71 {
72
74 using GlobalTable = map<ConnectionReference::NativeHandle, map<string, Atom>>;
75
77 shared_ptr<GlobalTable>
78 FetchGlobalTablePtr()
79 {
80 static auto p(make_shared<GlobalTable>());
81
82 return p;
83 }
84
86
87 static mutex TableMutex;
88
90 GlobalTable&
91 FetchGlobalTableRef()
92 {
93 return Deref(FetchGlobalTablePtr());
94 }
95
97 pair<string, Atom>
98 MakeAtomPair(::xcb_connection_t& c_ref, string_view name, bool e) ynothrowv
99 {
100 return pair<string, Atom>{name, Atom(c_ref, name, e)};
101 }
102
103 locked_ptr<map<string, Atom>>
104 LockAtoms(::xcb_connection_t& c_ref)
105 {
106 return {&FetchGlobalTableRef().at(make_observer(&c_ref)), TableMutex};
107 }
109
110
112
113 class XCBConnectionErrorCategory : public std::error_category
114 {
115 public:
116 PDefH(const char*, name, ) const ynothrow override
117 ImplRet("XCBConnectionError")
118
119 std::string
120 message(int) const override;
121 };
122
123 std::string
124 XCBConnectionErrorCategory::message(int err) const
125 {
126 switch(err)
127 {
128 case XCB_CONN_ERROR:
129 return
130 "connection errors because of socket, pipe and other stream errors";
131 case XCB_CONN_CLOSED_EXT_NOTSUPPORTED:
132 return "shutdown because of extension not supported";
133 case XCB_CONN_CLOSED_MEM_INSUFFICIENT:
134 return "malloc(), calloc() and realloc() error upon failure";
135 case XCB_CONN_CLOSED_REQ_LEN_EXCEED:
136 return "exceeding request length that server accepts";
137 case XCB_CONN_CLOSED_PARSE_ERR:
138 return "error during parsing display string";
139 case XCB_CONN_CLOSED_INVALID_SCREEN:
140 return "the server does not have a screen matching the display";
141 case XCB_CONN_CLOSED_FDPASSING_FAILED:
142 return "some FD passing operation failed";
143 default:
144 return "unknown";
145 }
146 }
148
149
150 class XCBErrorCategory : public std::error_category
151 {
152 public:
153 PDefH(const char*, name, ) const ynothrow override
154 ImplRet("XCBError")
155
157 std::string
158 message(int) const override;
159 };
160
161 std::string
162 XCBErrorCategory::message(int err) const
163 {
164 return std::string("XCB ") + [&]()->const char*{
165 switch(err)
166 {
167 # define YCL_Impl_XCB_ErrCategory(_x) \
168 case XCB_##_x: \
169 return #_x;
170 YCL_Impl_XCB_ErrCategory(REQUEST)
171 YCL_Impl_XCB_ErrCategory(VALUE)
172 YCL_Impl_XCB_ErrCategory(WINDOW)
173 YCL_Impl_XCB_ErrCategory(PIXMAP)
174 YCL_Impl_XCB_ErrCategory(ATOM)
175 YCL_Impl_XCB_ErrCategory(CURSOR)
176 YCL_Impl_XCB_ErrCategory(FONT)
177 YCL_Impl_XCB_ErrCategory(MATCH)
178 YCL_Impl_XCB_ErrCategory(DRAWABLE)
179 YCL_Impl_XCB_ErrCategory(ACCESS)
180 YCL_Impl_XCB_ErrCategory(ALLOC)
181 YCL_Impl_XCB_ErrCategory(COLORMAP)
182 YCL_Impl_XCB_ErrCategory(G_CONTEXT)
183 YCL_Impl_XCB_ErrCategory(ID_CHOICE)
184 YCL_Impl_XCB_ErrCategory(NAME)
185 YCL_Impl_XCB_ErrCategory(LENGTH)
186 YCL_Impl_XCB_ErrCategory(IMPLEMENTATION)
187 # undef YCL_Impl_XCB_ErrCategory
188 default:
189 return "unknown";
190 }
191 }() + " error";
192 }
193
194
196 const XCBConnectionErrorCategory&
197 FetchXCBConnectionErrorCategory()
198 {
199 static const XCBConnectionErrorCategory ecat{};
200
201 return ecat;
202 }
203
204 const XCBErrorCategory&
205 FetchXCBErrorCategory()
206 {
207 static const XCBErrorCategory ecat{};
208
209 return ecat;
210 }
211
213
214 template<typename _tParam>
215 YB_NORETURN void
216 ThrowGeneralXCBException(_tParam&& arg, int err = 0, const std::error_category&
217 ecat = FetchXCBErrorCategory(), RecordLevel lv = Err)
218 {
219 throw Exception(err, ecat, yforward(arg), lv);
220 }
221
222 void
223 CheckRequest(::xcb_connection_t& c_ref, ::xcb_void_cookie_t cookie,
224 RecordLevel lv = Err)
225 {
226 if(const auto p
227 = unique_raw(::xcb_request_check(&c_ref, cookie), std::free))
228 throw XCBException("xcb_request_check", p->response_type, p->error_code,
229 p->sequence, p->resource_id, p->minor_code, p->major_code,
230 p->full_sequence, lv);
231 }
232
234 unique_ptr<::xcb_get_geometry_reply_t, decltype(std::free)&>
235 FetchGeometry(::xcb_connection_t& c_ref, ::xcb_drawable_t id,
236 RecordLevel lv = Err)
237 {
238 const auto cookie(::xcb_get_geometry(&c_ref, id));
239 ::xcb_generic_error_t* p_err{};
240 auto p_reply(unique_raw(::xcb_get_geometry_reply(&c_ref, cookie, &p_err),
241 std::free));
242
243 if(const auto p = unique_raw(p_err, std::free))
244 throw XCBException("xcb_get_geometry_reply", p->response_type,
245 p->error_code, p->sequence, p->resource_id, p->minor_code,
246 p->major_code, p->full_sequence, lv);
247 if(YB_UNLIKELY(!p_reply))
248 ThrowGeneralXCBException("XCB reply is null without error detected.");
249 return p_reply;
250 }
252
253 } // unnamed namespace;
254
255
256 XCBException::XCBException(const char* msg, std::uint8_t resp,
257 std::uint8_t ec, std::uint16_t seq, std::uint32_t rid, std::uint16_t minor,
258 std::uint8_t major, std::uint32_t full_seq, RecordLevel lv)
259 : Exception(resp, FetchXCBErrorCategory(), msg, lv),
260 error_code(ec), sequence(seq), resource_id(rid), minor_code(minor),
261 major_code(major), full_sequence(full_seq)
262 {}
263 XCBException::XCBException(string_view msg, std::uint8_t resp,
264 std::uint8_t ec, std::uint16_t seq, std::uint32_t rid, std::uint16_t minor,
265 std::uint8_t major, std::uint32_t full_seq, RecordLevel lv)
266 : Exception(resp, FetchXCBErrorCategory(), msg, lv),
267 error_code(ec), sequence(seq), resource_id(rid), minor_code(minor),
268 major_code(major), full_sequence(full_seq)
269 {}
270 ImplDeDtor(XCBException)
271
272
273 int
274 ConnectionReference::GetError() const ynothrow
275 {
276 return ::xcb_connection_has_error(Nonnull(get()).get()) != 0;
277 }
278 void
279 ConnectionReference::Check() const
280 {
281 const int err(GetError());
282
283 if(err != 0)
284 ThrowGeneralXCBException("XCB connection check failed.",
285 err, FetchXCBConnectionErrorCategory());
286 }
287
288 int
289 ConnectionReference::GetFileDescriptor() const ynothrow
290 {
291 return ::xcb_get_file_descriptor(Nonnull(get()).get());
292 }
293 const ::xcb_setup_t&
294 ConnectionReference::GetSetup() const
295 {
296 if(const auto p = get())
297 {
298 if(const auto p_setup = ::xcb_get_setup(p.get()))
299 return *p_setup;
300 ThrowGeneralXCBException("Getting XCB setup failed.");
301 }
302 ThrowGeneralXCBException("Accessing XCB connection failed.");
303 }
304
305 std::uint32_t
306 ConnectionReference::GenerateID() const ynothrow
307 {
308 return ::xcb_generate_id(Nonnull(get()).get());
309 }
310
311
312 Connection::Connection(const char* disp_name, int* p_scr)
313 : Connection({}, disp_name, p_scr)
314 {}
315 Connection::Connection(::xcb_auth_info_t* p_auth, const char* disp_name,
316 int* p_scr)
317 : Connection((YTraceDe(Informative, "Creating XCB connection"
318 " with authorization information pointer = %p, display name = '%s',"
319 " screen number = '%s'", ystdex::pvoid(p_auth), disp_name ? disp_name
320 : "[NULL]", p_scr ? to_string(*p_scr).c_str() : "[NULL]"), make_observer(
321 ::xcb_connect_to_display_with_auth_info(disp_name, p_auth, p_scr))))
322 {}
323 Connection::Connection(ConnectionReference conn_ref)
324 : ConnectionReference(conn_ref),
325 p_shared([this]{
326 const auto p_conn(get());
327
328 if(!p_conn || IsOnError())
329 ThrowGeneralXCBException("XCB connection failed.",
330 Deref(reinterpret_cast<int*>(p_conn.get())),
331 FetchXCBConnectionErrorCategory());
332 return FetchGlobalTablePtr();
333 }())
334 {
335 auto& c_ref(Deref(get()));
336 lock_guard<mutex> lck(TableMutex);
337
338 Deref(static_cast<GlobalTable*>(p_shared.get()))[make_observer(&c_ref)]
339 = {MakeAtomPair(c_ref, "WM_PROTOCOLS", true),
340 MakeAtomPair(c_ref, "WM_DELETE_WINDOW", {})};
341 }
342 Connection::~Connection()
343 {
344 {
345 lock_guard<mutex> lck(TableMutex);
346
347 FetchGlobalTableRef().erase(get());
348 }
349 ::xcb_disconnect(Nonnull(get()).get());
350 }
351
352
353 Atom::Atom(::xcb_connection_t& c_ref, string_view n,
354 bool only_if_exists) ynothrowv
355 : atom([&](::xcb_intern_atom_cookie_t cookie) -> ::xcb_atom_t {
356 if(const auto p = unique_raw(
357 ::xcb_intern_atom_reply(&c_ref, cookie, {}), std::free))
358 return p->atom;
359 return XCB_ATOM_NONE;
360 }(::xcb_intern_atom_unchecked(&c_ref, only_if_exists, n.length(),
361 (Nonnull(n.data()), n.data()))))
362 {}
363
364
365 Atom::NativeType
366 LookupAtom(::xcb_connection_t& c_ref, const string& name)
367 {
368 // TODO: Blocked. Use %string_view as argument using C++14 heterogeneous
369 // %find template.
370 return Deref(LockAtoms(c_ref)).at(name);
371 }
372
373
374 WindowData::WindowData(::xcb_connection_t& c_ref, const Rect& r)
375 : WindowData(c_ref, r, [&c_ref]{
376 if(const auto p = ::xcb_setup_roots_iterator(
377 &ConnectionReference(make_observer(&c_ref)).GetSetup()).data)
378 return *p;
379 ThrowGeneralXCBException("No XCB screen found.");
380 }())
381 {}
382 WindowData::WindowData(::xcb_connection_t& c_ref, const Rect& r,
383 const ::xcb_screen_t& scr)
384 : WindowData(c_ref, r, scr.root)
385 {}
386 WindowData::WindowData(::xcb_connection_t& c_ref, const Rect& r,
387 WindowData::ID parent)
388 : Drawable(c_ref)
389 {
390 CheckRequest(c_ref, ::xcb_create_window_checked(&c_ref,
391 XCB_COPY_FROM_PARENT, GetID(), parent, r.X, r.Y, r.Width, r.Height, 0,
392 XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, {}));
393 }
394 WindowData::~WindowData()
395 {
396 auto& c_ref(DerefConn());
397
398 YSLib::FilterExceptions([&]{
399 CheckRequest(c_ref, ::xcb_destroy_window_checked(&c_ref, GetID()));
400 });
401 }
402
403 Rect
404 WindowData::GetBounds() const
405 {
406 auto p_rep(FetchGeometry(DerefConn(), GetID()));
407 auto& rep(Deref(p_rep));
408
409 return {rep.x, rep.y, rep.width, rep.height};
410 }
411
412 void
413 WindowData::SetBounds(const Rect& r)
414 {
415 auto& c_ref(DerefConn());
416 const auto values(cast_array<std::uint32_t>(r.X, r.Y, r.Width, r.Height));
417
418 CheckRequest(c_ref, ::xcb_configure_window_checked(&c_ref, GetID(),
419 XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH
420 | XCB_CONFIG_WINDOW_HEIGHT, values.cbegin()));
421 }
422
423 void
424 WindowData::Close()
425 {
426 auto& c_ref(DerefConn());
427 const auto lptr(LockAtoms(c_ref));
428 const auto& atoms(Deref(lptr));
429 ::xcb_client_message_event_t ev{XCB_CLIENT_MESSAGE, 32, 0, GetID(),
430 ::xcb_atom_t(atoms.at("WM_PROTOCOLS")), {}};
431
432 yunseq(ev.data.data32[0] = ::xcb_atom_t(atoms.at("WM_DELETE_WINDOW")),
433 ev.data.data32[1] = XCB_CURRENT_TIME);
434 CheckRequest(c_ref, ::xcb_send_event_checked(&c_ref, {}, GetID(),
435 XCB_EVENT_MASK_PROPERTY_CHANGE, reinterpret_cast<const char*>(&ev)));
436 }
437
438 void
439 WindowData::Hide()
440 {
441 auto& c_ref(DerefConn());
442
443 CheckRequest(c_ref, ::xcb_unmap_window_checked(&c_ref, GetID()));
444 }
445
446 void
447 WindowData::Invalidate(const Rect& r)
448 {
449 auto& c_ref(DerefConn());
450 ::xcb_expose_event_t ev{XCB_EXPOSE, 0, 0, GetID(), std::uint16_t(r.X),
451 std::uint16_t(r.Y), r.Width, r.Height, 0, {0, 0}};
452
453 CheckRequest(c_ref, ::xcb_send_event_checked(&c_ref, {}, GetID(),
454 XCB_EVENT_MASK_EXPOSURE, reinterpret_cast<const char*>(&ev)));
455 }
456
457 void
458 WindowData::Move(const Point& pt)
459 {
460 auto& c_ref(DerefConn());
461 const auto values(cast_array<std::uint32_t>(pt.X, pt.Y));
462
463 CheckRequest(c_ref, ::xcb_configure_window_checked(&c_ref, GetID(),
464 XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values.cbegin()));
465 }
466
467 void
468 WindowData::Resize(const Size& s)
469 {
470 auto& c_ref(DerefConn());
471 const auto values(cast_array<std::uint32_t>(s.Width, s.Height));
472
473 CheckRequest(c_ref, ::xcb_configure_window_checked(&c_ref, GetID(),
474 XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values.cbegin()));
475 }
476
477 void
478 WindowData::Show()
479 {
480 auto& c_ref(DerefConn());
481
482 CheckRequest(c_ref, ::xcb_map_window_checked(&c_ref, GetID()));
483 }
484
485
486 GContext::~GContext()
487 {
488 ::xcb_free_gc_checked(&DerefConn(), GetID());
489 }
490
491
492 void
493 UpdatePixmapBuffer(WindowData& wnd, const Rect& r, const ConstGraphics& g)
494 {
495 auto& c_ref(wnd.DerefConn());
496 GContext gc(c_ref);
497
498 CheckRequest(c_ref, ::xcb_put_image_checked(&c_ref,
499 XCB_IMAGE_FORMAT_Z_PIXMAP, wnd.GetID(), gc.GetID(), r.Width, r.Height,
500 r.X, r.Y, 0, Pixel::traits_type::XYZBitsN,
501 ::uint32_t(g.GetSizeOfBuffer()),
502 ystdex::aligned_store_cast<const ::uint8_t*>(g.GetBufferPtr())));
503 }
504
505 } // namespace XCB;
506
507 } // namespace platform_ex;
508
509 #endif
510
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:112
platform::Nonnull
YB_PURE _type && Nonnull(_type &&p) ynothrowv
断言并返回非空参数。
Definition: Debug.h:518
YSLib::Drawing::Size
屏幕区域大小。
Definition: YGDIBase.h:536
YSLib::Drawing::ImplRet
YB_ATTR_nodiscard YB_STATELESS yconstfn Rotation rot ImplRet(Rotation((size_t(rot)+1) % 4)) YB_ATTR_nodiscard YB_STATELESS yconstfn PDefH(Rotation
YSLib::UI::Hide
YF_API void Hide(IWidget &)
隐藏部件。
Definition: YWidget.cpp:100
platform_ex
平台扩展命名空间。
Definition: Android.h:46
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
YSLib::Drawing::ImageTag::to_string
YB_ATTR_nodiscard YF_API YB_PURE string to_string(const ImageTag &, ImageMetadataModel)
取按指定图像元数据模型解释的标签值字符串表示。
Definition: Image.cpp:707
YSLib::Drawing::GGraphics::Height
const SizeType sGraphics Height
Definition: YGraphics.h:136
platform::Descriptions::RecordLevel
RecordLevel
记录等级。
Definition: YCommon.h:178
ystdex::cpp2017::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:437
ImplDeDtor
#define ImplDeDtor(_t)
Definition: YBaseMacro.h:183
YSLib::UI::Move
@ Move
移动：位置调整。
Definition: YWidgetEvent.h:381
YSLib::Drawing::g
The boundary is out of the const Graphics & g
Definition: YDraw.h:161
ystdex::cast_array
common_array_t< _type, _tParams... > cast_array(_tParams &&... args)
构造指定参数转换初始化的 std::array 对象。
Definition: array.hpp:60
YSLib::Drawing::PDefH
YB_ATTR_nodiscard YB_PURE yconstfn PDefH(Size, Transpose, const Size &s) ynothrow ImplRet(
转置。
Definition: YGDIBase.h:763
YSLib::UI::Invalidate
YF_API void Invalidate(IWidget &, const Rect &)
无效化：使相对部件的指定区域在直接和间接的窗口缓冲区中无效。
Definition: YWidget.cpp:108
YSLib::lv
const char RecordLevel lv
Definition: YException.cpp:61
YSLib::UI::Show
YF_API void Show(IWidget &)
显示部件。
Definition: YWidget.cpp:202
ystdex::unique_raw
std::unique_ptr< _type > unique_raw(_pSrc *p)
Definition: memory.hpp:645
YSLib::Drawing::GGraphics
二维图形接口上下文模板。
Definition: YGraphics.h:63
YB_NORETURN
#define YB_NORETURN
指定无返回值函数。
Definition: ydef.h:877
ystdex::make_observer
observer_ptr< _type > make_observer(_type *p)
Definition: pointer.hpp:405
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::cpp2017::data
auto data(_tRange &c) -> decltype(c.data())
Definition: range.hpp:581
platform::Descriptions::Informative
@ Informative
Definition: YCommon.h:185
platform::Concurrency
Definition: Mutex.h:54
std
Definition: optional.h:982
YSLib::Drawing::GBinaryGroup< SPos >
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1535
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:407
YSLib::FilterExceptions
bool FilterExceptions(_func f, const char *desc={}, RecordLevel lv=Alert, ExceptionTracer trace=ExtractAndTrace) ynothrow
调用函数并过滤宿主异常。
Definition: YException.h:225
platform::Descriptions::Err
@ Err
Definition: YCommon.h:182
YSLib::UI::Close
void Close(IWidget &wgt)
Definition: YWidget.cpp:92
YSLib::UI::Resize
@ Resize
大小调整。
Definition: YWidgetEvent.h:383
YSLib::Drawing::GBinaryGroup::X
_type X
分量。
Definition: YGDIBase.h:305
YSLib::Drawing::Rect
屏幕标准矩形：表示屏幕矩形区域。
Definition: YGDIBase.h:788
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
ystdex::pvoid
enable_if_t< or_< is_object< _type >, is_void< _type > >::value, void * > pvoid(_type *p)
取 void* 类型的指针。
Definition: addressof.hpp:166
YSLib::RecordLevel
YF_API const char RecordLevel
Definition: YException.h:148
type_pun.hpp
共享存储和直接转换。
NPL::A1::name
const char * name
Definition: NPLA1.h:1876
YSLib::Drawing::ynothrow
YB_ATTR_nodiscard yconstfn YB_PURE x x x Bottom YB_ATTR_nodiscard yconstfn YB_PURE x Right y x Top y x Bottom y Bottom YB_ATTR_nodiscard yconstfn YB_PURE x Right y x Top y x Bottom y Bottom YB_ATTR_nodiscard yconstfn YB_PURE const Padding & ynothrow
Definition: YGDI.h:132
platform::Deref
YB_PURE yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:547
YSLib::Drawing
图形处理。
Definition: YGlobal.h:58
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
platform::Threading
Definition: Mutex.h:140
YModules.h
YCLib 库模块配置文件。
NPL::c_str
YF_API const char src c_str())) YF_API void InstallDirectory(const string &
安装目录：复制目录树。
Definition: Dependency.h:140
YSLib::Drawing::GBinaryGroup::Y
_type Y
Definition: YGDIBase.h:305
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:828
platform::p
return p p
Definition: YCLib/FileSystem.h:209
platform::ID
std::uintmax_t ID
YF_Platform_* 宏替换值的公共类型。
Definition: YCommon.h:54
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
addressof.hpp
一元操作符 & 和取指针的相关接口。
ystdex::cpp2017::string
basic_string< char > string
Definition: string.hpp:772
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
NPL::get
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(NPL ref get()
Definition: NPLA.h:1737
array.hpp
数组操作。
NPL::_tParam
_tParam
Definition: NPLA.h:2367
ystdex::and_
逻辑操作元函数。
Definition: integral_constant.hpp:151