COMPΞZ 🧬
390 subscribers
1.85K photos
50 videos
24 files
731 links
متخصص کامپیوتر و نرم‌افزار • سازنده • هنرمند و طراح • مجموعه‌دار • نویسنده • تحلیل‌گر • مشاور استارتاپی و ایده‌پرداز

𐎲𐎴𐎠𐎼𐎴𐎫𐎹 𐏃𐎢𐎶𐎠𐎫𐎹

We create because the world deserves better code.

https://linktr.ee/compez
Download Telegram
سوأل کردین که در مورد وضعیت نمودار دیجن تحلیل بده!

راستش دیجن خیلی وقته بوسهٔ مرگ رو زده! نمودار ماهانش هیچ حرفی از نظر مثبت نداره اما در روزانه هم نسبتاً قابل دیدن هست! هیچ سیگنال امیدوار کننده‌ای توش نمی‌بینم و تنها سیگنال امیدوار کنندش که هیچ تصمیمی در فروشش ندارم اینه که این فاندرش دو روزی هست مارو جمع کرده تو یه گروه و سعی داره یجور پروژه رو نجات بده، خود این سیگنال خوبی هست!

خودمم کلی لاک دارم و توی دره چی رو بفروشم؟ 👀کلی هم توی ضرر هستم و شاید فقط با ساخت و ساز بتونم بخشیش رو جبران کنم! این تصمیم خودم هست نسبت به شرایط خودم. اما خب برای شما هم پیشنهاد می‌کنم صبر پیشه کنید البته (DYOR و حرف من رو هیچ‌گاه سند قرار ندیدن)! در بدترین حالت احتمال میدم بازم پایین‌تر رو ببینه اما خب با توجه به صحبت‌هایی که توی گروه توسعهٔ دیجن می‌بینم یه سری ایده‌ها منجر به بهتر شدت وضعیت فعلی می‌تونه بشه و این تشویق‌ها و پاداش‌ها هم با هدف همین هست که از پروژه حمایت بشه.

هرچی باشه یا هر برنامه‌ای شکل بگیره اینجا اطلاع میدم بهتون.
👍5🔥2😭1
1
صفت assume در استاندارد ۲۳

صفت (attribute) در قالبِ [[assume]] نسخهٔ استاندارد شده‌ای از برخی از ویژگی‌های خاص به کامپایلر که قبلاً موجود بودند است، مانند ()__assume (در MSVC و ICC) و ()__builtin_assume (در Clang) است. با استفاده از آن‌ها، برنامه‌نویس می‌تواند به کامپایلر بگوید که یک عبارت درست خواهد بود بدون اینکه کامپایلر بخواهد آن را ارزیابی کند.

این صفت به کامپایلر دستور می‌دهد تا کد را با این فرض بهینه‌سازی کند که یک عبارت خاص همیشه در یک نقطه خاص از برنامه مقدار true را برمی‌گرداند.

به این ترتیب، کامپایلر می‌تواند کد کارآمدتر و سریع‌تر تولید کند. این می‌تواند مزایای قابل توجهی را در برخی توضیحات با عملکرد بالا و تاخیر کم به ارمغان بیاورد.

نحو (سینتکس) آن به این صورت است:

[[assume( expression )]]

import std;

auto main() ->int {

const auto x = 128;
if (x > 0) {
[[assume(x > 0)]];
const auto res = x * 2;
std::print("Res : {}", res);
}

}



در این مثال، کامپایلر می‌تواند کد داخل بلوک if را با فرض مثبت بودن x به دلیل صفت assume بهینه‌سازی کند. این ممکن است شامل حذف بررسی‌های مثبت بودن x قبل از عملیات باشد.

نکته‌ها
- عبارتی که با assume استفاده می‌شود باید یک مقدار بولین (قابل تبدیل به bool) را برگرداند.
- خود عبارت لزوماً ارزیابی نمی‌شود، اما کامپایلر ممکن است هنوز هم برخی از تجزیه و تحلیل‌ها را روی آن انجام دهد.
- اگر عبارت در زمان اجرا نادرست باشد، رفتار برنامه نامشخص می‌شود.
- صفت assume فقط می‌تواند برای عبارات null اعمال شود.
- با این حال، استفاده از assume باید با احتیاط انجام شود. استفاده نادرست از آن می‌تواند در صورت عدم صحت فرض در زمان اجرا، منجر به رفتار غیرمنتظره شود.


#cpp20 #cpp23 #attribute #صفت
#چالش #سی‌روزه #روز_ششم
COMPΞZ 🧬
صفت assume در استاندارد ۲۳ صفت (attribute) در قالبِ [[assume]] نسخهٔ استاندارد شده‌ای از برخی از ویژگی‌های خاص به کامپایلر که قبلاً موجود بودند است، مانند ()__assume (در MSVC و ICC) و ()__builtin_assume (در Clang) است. با استفاده از آن‌ها، برنامه‌نویس می‌تواند…
بخش تخصصی دوم (به‌روز رسانی Solidity) مروری بر انواع مرجع

مقادیر انواع مرجع (Reference Types) می‌توانند از طریق چندین نام مختلف تغییر یابند. این را با انواع متغیر‌ها مقایسه کنید که هرگاه متغیری از نوع مقدار استفاده شود، یک کپی مستقل دریافت می‌کند. به همین دلیل، انواع مرجع باید با دقت بیشتری نسبت به انواع متغیر مدیریت شوند. در حال حاضر، انواع مرجع شامل ساختارها (structs)، آرایه‌ها و نگاشت‌ها (mappings) هستند. اگر از یک نوع مرجع استفاده کنید، همیشه باید به صراحت منطقه داده‌ای را که نوع در آن ذخیره می‌شود، ارائه دهید.

بخش memory (که عمر زمانیِ آن محدود به یک فراخوانی تابع external است)، storage (مکانی که متغیرهای وضعیت ذخیره می‌شوند، جایی که عمر زمانی آن محدود به عمر یک قرارداد است) یا calldata (مکان داده‌ای ویژه‌ای که حاوی آرگومان‌های تابع است).

یک انتساب یا تبدیل نوع، که مکان داده را تغییر می‌دهد همیشه دارای عملیات کپی خودکار است، در حالی که واگذاری در همان مکان داده فقط در برخی موارد برای انواع ذخیره‌سازی کپی می‌شوند.


مکان داده‌ها (Data location)

هر نوع مرجعی دارای یک حاشیه‌نگاری اضافی به نام «مکان داده» (data location) است که دربارهٔ مکان ذخیره‌سازی آن اطلاعاتی را ارائه می‌دهد.

سه مکان داده وجود دارد:

۱) حافظه (memory).
۲) ذخیره‌سازی (storage).
۳) داده‌های تماس (calldata)، که یک ناحیه غیر قابل تغییر و غیر دائمی است که آرگومان‌های تابع در آن ذخیره می‌شوند و به طور عمده مانند حافظه عمل می‌کند.

مکان داده‌ها و تخصیص رفتار‌ها
مکان‌های داده‌ها نه تنها به پایداری داده‌ها مربوط می‌شوند، بلکه برای معنایی انتساب‌ها نیز مرتبط هستند:

- اختصاص‌ها بین storage و memory (یا از calldata) همیشه یک کپی مستقل ایجاد می‌کنند.
- اختصاص‌ها از memory به memory تنها مراجع (رفرنس) را ایجاد می‌کنند. این بدان معناست که تغییرات در یک متغیر حافظه، همچنین در تمامی متغیرهای حافظه دیگر که به همان داده اشاره می‌کنند، قابل مشاهده است.
- اختصاص‌ها از storage به یک متغیر محلی ذخیره‌سازی نیز تنها یک مرجع را اختصاص می‌دهند.
- تمامی اختصاص‌های دیگر به storage همیشه کپی می‌شوند. مثال‌هایی برای این حالت، اختصاص به متغیرهای وضعیت یا به اعضای متغیرهای محلی از نوع ساختار ذخیره‌سازی است، حتی اگر متغیر محلی خود فقط یک مرجع باشد.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;

contract C {
// The data location of x is storage.
// This is the only place where the
// data location can be omitted.
uint[] x;

// The data location of memoryArray is memory.
function f(uint[] memory memoryArray) public {
x = memoryArray; // works, copies the whole array to storage
uint[] storage y = x; // works, assigns a pointer, data location of y is storage
y[7]; // fine, returns the 8th element
y.pop(); // fine, modifies x through y
delete x; // fine, clears the array, also modifies y
// The following does not work; it would need to create a new temporary /
// unnamed array in storage, but storage is "statically" allocated:
// y = memoryArray;
// Similarly, "delete y" is not valid, as assignments to local variables
// referencing storage objects can only be made from existing storage objects.
// It would "reset" the pointer, but there is no sensible location it could point to.
// For more details see the documentation of the "delete" operator.
// delete y;
g(x); // calls g, handing over a reference to x
h(x); // calls h and creates an independent, temporary copy in memory
}

function g(uint[] storage) internal pure {}
function h(uint[] memory) public pure {}
}


#solidity #web3 #update #ether #اتریوم
پسوند تحت‌الفظی‌ (لیترال‌ها) برای std::size_t در استاندارد ۲۳

بهتر است بدانیم، std::size_t می‌تواند بیشینه اندازه‌ٔ یک شیء نظری (تئوری) از هر نوع (شامل آرایه) را ذخیره کند. یک نوع که اندازه‌اش نمی‌تواند توسط std::size_t نمایان شود، (ill-formed) است. در بسیاری از پلتفرم‌ها (استثنا سیستم‌های با آدرس‌دهی قطعه‌ای است)، std::size_t می‌تواند به طور ایمن مقدار هر اشاره‌گر غیر عضو را ذخیره کند، در این صورت مترادف std::uintptr_t است.

از طرفی معمولاً از std::size_t برای شاخص‌گذاری آرایه و شمارش حلقه‌ها استفاده می‌شود. برنامه‌هایی که از انواع دیگری مانند unsigned int برای شاخص‌گذاری آرایه استفاده می‌کنند، ممکن است در سیستم‌های ۶۴ بیتی، به عنوان مثال، زمانی که شاخص از UINT_MAX بیشتر شود با مشکل روبرو شوند یا اگر بر اعتماد به حسابگری مدولار (Modular Arithmetic) ۳۲ بیتی تکیه کنند.

در این میان قبل از استاندارد ۲۳ هیچ پسوند لیترال اختصاصی برای std::size_t و std::ptrdiff_t وجود نداشت، این موضوع منجر به مشکلاتی مانند عدم خوانایی، عدم قابلیت حمل و خطاهای احتمالی نسبت به معماری‌های مختلف می‌شد.

برای مثال کد زیر که فاقد لیترال اختصاصی است، در سیستم‌های ۳۲ بیتی کامپایل می‌شود، اما در نسخه‌های ۶۴ بیتی ممکن است خطا بدهد:

    std::vector<int> v{0, 1, 2, 3};
for (auto i = 0, s = v.size(); i < s; ++i) {
[[maybe_unused]] auto r_v_i = v[i];
[[maybe_unused]] auto r_i = i;
}


برای حل این موضوع و پشتیبانی بهتر، استاندارد ۲۳ پسوندهای لیترال جدیدی را برای نوع std::size_t و نوع علامت‌دار مربوطه (ptrdiff_t) معرفی کرده است. این پسوندها به شما امکان می‌دهند تا مقادیر این نوع‌ها را به طور مستقیم در کد خود بنویسید، بدون اینکه نگران محدودیت‌های پلتفرم یا معماری باشید.

مثال زیر نمونه‌ای به همراه لیترال‌های اختصاصی zu مشکل را حل می‌کند:

import std;

auto main() -> int {

std::vector<int> v {0, 1, 2, 3};
for (auto i = 0zu; i < v.size(); ++i) {
std::println("i:{:>2}", v[i]);
}
}


به طور کلی، این الفاظ تحت‌الفظی اجازه می‌دهند تا مقادیر از نوع عدد صحیح به طور مستقیم در عبارات استفاده شود.
پسوند واقعی برای std::size_t هر ترکیبی از z یا Z با u یا U است (یعنی zu، zU، Zu، ZU، uz، uZ، Uz یا UZ) برای استفاده مجاز هستند.

- پسوند z یا Z برای نوع علامت‌دار std::size_t
- پسوند uz یا zu برای نوع بدون علامت std::size_t
- پسوند t یا T برای نوع علامت‌دار std::ptrdiff_t
- پسوند ut یا tu برای نوع بدون علامت std::ptrdiff_t

import std;

auto main() -> int {

std::vector<int> v {0, 1, 2, 3};
for (auto i = 0zu; i < v.size(); ++i) {
std::println("i:{}", v[i]);
}
}


ماکروی اختصاصی برای بررسی این ویژگی به صورت زیر است:

#ifdef __cpp_size_t_suffix
//TODO...
#endif


#cpp20 #cpp23 #size_t
#چالش #سی‌روزه #روز_هفتم
🔥2
COMPΞZ 🧬
پسوند تحت‌الفظی‌ (لیترال‌ها) برای std::size_t در استاندارد ۲۳ بهتر است بدانیم، std::size_t می‌تواند بیشینه اندازه‌ٔ یک شیء نظری (تئوری) از هر نوع (شامل آرایه) را ذخیره کند. یک نوع که اندازه‌اش نمی‌تواند توسط std::size_t نمایان شود، (ill-formed) است. در بسیاری…
بخش تخصصی دوم (به‌روز رسانی Solidity) | توابع bytes.concat و string.concat

در سالیدیتی می‌توانید تعداد دلخواهی از مقادیر string (رشته) را با استفاده از string.concat ادغام کنید. این تابع یک آرایه string memory تکی را که شامل محتوای آرگومان‌ها بدون padding است را برمی‌گرداند. اگر می‌خواهید از پارامترهای دیگری که به صورت ضمنی به رشته قابل تبدیل نیستند استفاده کنید، ابتدا آن‌ها را به string تبدیل کنید.

به طور مشابه، تابع bytes.concat می‌تواند تعداد دلخواهی از مقادیر بایت یا bytes1 ... bytes32 را ادغام کند. این تابع یک آرایه bytes memory تکی را که شامل محتوای آرگومان‌ها بدون پر کردن است را برمی‌گرداند. اگر می‌خواهید از پارامترهای رشته‌ای یا دیگر انواعی که به صورت ضمنی به bytes قابل تبدیل نیستند استفاده کنید، ابتدا آن‌ها را به بایت یا bytes1/…/bytes32 تبدیل کنید.

کد مثال:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;

contract C {
string s = "Storage";
function f(bytes calldata bc, string memory sm, bytes16 b) public view {
string memory concatString = string.concat(s, string(bc), "Literal", sm);
assert((bytes(s).length + bc.length + 7 + bytes(sm).length) == bytes(concatString).length);

bytes memory concatBytes = bytes.concat(bytes(s), bc, bc[:2], "Literal", bytes(sm), b);
assert((bytes(s).length + bc.length + 2 + 7 + bytes(sm).length + b.length) == concatBytes.length);
}
}


اگر string.concat یا bytes.concat را بدون آرگومان فراخوانی کنید، یک آرایه خالی برمی‌گردانند.

متغیر concatString این خط یک رشته جدید به نام concatString ایجاد می‌کند که توسط تابع string.concat ساخته می‌شود. این تابع ادغام چند رشته مختلف را انجام می‌دهد. مقادیری که ادغام می‌شوند عبارتند از: مقدار s، مقدار bc (که ابتدا به رشته تبدیل می‌شود)، "Literal" (یک رشته ثابت) و مقدار sm.

#solidity #web3 #update #ether #اتریوم
🔥1
حوصله ندارم توضیح بدم اما، اگه چیزی روی USDT دارید، تبدیلش کنید به USDC و دیگه هیچ‌وقت به تتر فکر نکنید.
تمام.
👍5
عاقبت پروژه‌هایی که به حرف مخاطبشون ارزشی قائل نباشن میشه این.
👍2😱1
یک به‌روز رسانی جدید روی ایدهٔ Vault Wars دادم که توی این نسخه دسترسی و داده‌ها با ظاهر و تعامل بهتر در دسترس قرار می‌گیرن.
حالا می‌تونید به آیتم‌های خودتون و سراسری به همراه فیلتر کردن آن‌ها دسترسی داشته باشید.

https://warpcast.com/compez.eth/0xfff0c24e
👍31
COMPΞZ 🧬
یک به‌روز رسانی جدید روی ایدهٔ Vault Wars دادم که توی این نسخه دسترسی و داده‌ها با ظاهر و تعامل بهتر در دسترس قرار می‌گیرن. حالا می‌تونید به آیتم‌های خودتون و سراسری به همراه فیلتر کردن آن‌ها دسترسی داشته باشید. https://warpcast.com/compez.eth/0xfff0c24e
جزئیات هر آیتم هم قابل نمایش هست که چه آدرسی مالکش هست و در چه شرایطیه.

برای این که بتونم این فیلتر رو ایجاد کنم مجبور شدم یه قرارد دیگه بنویسم به عنوان DegenHelperContract.
🔥2
COMPΞZ 🧬
جزئیات هر آیتم هم قابل نمایش هست که چه آدرسی مالکش هست و در چه شرایطیه. برای این که بتونم این فیلتر رو ایجاد کنم مجبور شدم یه قرارد دیگه بنویسم به عنوان DegenHelperContract.
از دیروز به این طرف ۷۵ تراکنش آزمایشی ثبت شده! ۱۶ ک دیجن ترنسفر شده! ۲۳۰۰ ک سود سازنده‌ها و ۳۴۰۰ ک هم سود مالکان هست که همون ۴۰ به ۶۰ درصد محاسبه می‌شه.

سود توسعه‌دهنده هم باید چیزی حدود ۳۰۰ دیجن باشه که ۵٪ از هر خرید دریافت شده.
🔥1
COMPΞZ 🧬
از دیروز به این طرف ۷۵ تراکنش آزمایشی ثبت شده! ۱۶ ک دیجن ترنسفر شده! ۲۳۰۰ ک سود سازنده‌ها و ۳۴۰۰ ک هم سود مالکان هست که همون ۴۰ به ۶۰ درصد محاسبه می‌شه. سود توسعه‌دهنده هم باید چیزی حدود ۳۰۰ دیجن باشه که ۵٪ از هر خرید دریافت شده.
خب از توی این ایده یه راه درآمدی به جای تیپ دادن می‌شه پیشنهاد کرد برای شما.
۱) مقداری wdegen داشته باشید، هنر خودتون رو مینت کنید، برای مینتش پولی دریافت نمیشه و در حد گس‌فی هست.
۲) سعی کنید کارتون رو به اشتراک بذارید تا کس دیگه‌ای اون رو Unlock و Claim کنه.
۳) همون لحظه ۱۰۰ دیجن به شما داده میشه و می‌تونید بین خودتون خرید و فروش کنید و ۶۰ به ۴۰ درصد سود بردارید. ۵٪ هم میدین به من صداتونم در نیاد. 😐😄

در این حد می‌تونستم برای دیجن یه حرکت بزنم، آزمایش کنید شاید راه حل مناسبی برای کسانی باشه که سهمیه ندارن یا بن شدن.
😁1
روز بخیر، وقتی باور کنی که می‌تونی، جهان هم با تو هم‌صدا می‌شه. 👊🏼

https://warpcast.com/compez.eth/0x5093bcd3
👍1
یک تحلیل کلی هم بدم و برم سر کارم...
روند کمامان صعودی هست! در تایم‌فریم هفتگی تقریباً به کف کانال برخورد کردیم، و با فشار فروش شدیدی هم برخورد کردیم!

کندل جدیدی که ایجاد شده و سبز رنگ هم هست، با توجه به موقعیت RSI ممکنه شُل کنه به پایین!

به هر حال اگه کندل جدید تا ۶ روز دیگه به اندازه و حتی بیشتر از دو کندل قبلی سبز و کامل بسته نشه، امکان مثبت بودن روند می‌تونه برعکس بشه و ریزش بدتری رو هم شاهد باشیم؛ اما در صورت بسته شدن این وضعیت، تبدیل به حمایت در کف کانال میشه و می‌شه امیدوار‌تر بود.
👍2
COMPΞZ 🧬
خب! درود بر برنامه‌نویس عالم! چالش سی روزه رو آغاز می‌کنم 🫵🏼✍🏼 اما هدف آموزش نحوهٔ کد‌نویسی با C++23 و Solidity. شما هم می‌تونید نکته برداری کنید، منم هدفم اینه هرچی به روز رسانی کردم رو یادداشت کنم تا دوباره برای خودم مرور بشه. هیچ سخت نیست، تنهایی پیش…
کلاس std::mdspan و زیر عضو extents در استاندارد ۲۳

این کلاس از نوع template (الگو) است که نمایه‌ای از یک دنبالهٔ پیوسته از عناصر را ارائه می‌دهد و به شما اجازه می‌دهد تا با آن مانند یک آرایه چندبعدی رفتار کنید. این کلاس، توسعه‌ای از کلاس std::span موجود در C++20 است که برای داده‌های تک‌بعدی کار می‌کند.

۱) نمای چندبعدی
برخلاف std::span کلاس std::mdspan می‌تواند با داده‌هایی با ابعاد مختلف کار کند، و آن را برای کار با ماتریس‌ها، تانسورها و دیگر ساختارهای چندبعدی مناسب می‌کند.

۲) چیدمان حافظهٔ انعطاف‌پذیر
به شما اجازه می‌دهد تا چیدمان حافظهٔ داده را مانند ترتیب سطر-اصلی یا ستون-اصلی مشخص کنید. این امر برای الگوهای دسترسی کارآمد در سناریوهای مختلف بسیار مهم است.

۳) دسترسی ایمن و کارآمد
کلاس std::mdspan دسترسی ایمن به عناصر درون داده‌های مشاهده‌شده را در حین حفظ کارایی فراهم می‌کند. از کپی‌های غیرضروری جلوگیری می‌کند و بررسی محدوده را انجام می‌دهد.

به عبارت ساده‌تر، تصور کنید یک آرایه یک‌بعدی از اعداد دارید. std::mdspan به شما امکان می‌دهد آن را به عنوان یک شبکهٔ دوبعدی (یا ابعاد بالاتر) با یک چیدمان خاص در حافظه ببینید.

گزینهٔ std::mdspan::extents یک تابع عضو کلاس std::mdspan است که یک شیء از نوع extents را برمی‌گرداند. کلاس extents فضای شاخص چندبعدی را نشان می‌دهد. این کلاس اطلاعاتی در مورد اندازه و رتبه (تعداد ابعاد) یک آرایه ارائه می‌دهد. به عبارت ساده‌تر، زمانی که از std::mdspan برای ایجاد یک نمای چندبعدی از یک بلوک داده زیربنایی استفاده می‌کنید، تابع extents به شما در درک شکل آن نما کمک می‌کند. این تابع به شما می‌گوید که چند عنصر در هر بعد از داده وجود دارد.


به عنوان مثال، اگر یک نمای std::mdspan دو بعدی از یک آرای یک بعدی ایجاد کنید، extents تعداد سطرها و ستون‌ها را در نمای دو بعدی نشان می‌دهد.

مثال:

import std;

auto main() -> int {

std::array arr {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

// Create a 2D mdspan view of the data
auto mySpan = std::mdspan(arr.data(), 2, 6);

// Get the extents of the mdspan
std::extents myExtents = mySpan.extents();

// Print the number of rows and columns
std::println("Number of rows: {}", myExtents.extent(0));
std::println("Number of columns: {}", myExtents.extent(1));
std::println("Rank of myExtents: {}", myExtents.rank());
}


خروجی:

Number of rows: 2
Number of columns: 6
Rank of myExtents: 2



عضو rank نیز تعداد ابعاد را به extent برمی‌گرداند.

همچنین مثال زیر روشی از نحوهٔ پیاده‌سازی عضو دو و سه بعدی را نمایش می‌دهد.

import std;

auto main() -> int {

std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

// View data as contiguous memory representing 2 rows of 6 ints each
auto ms2 = std::mdspan(v.data(), 2, 6);
// View the same data as a 3D array 2 x 3 x 2
auto ms3 = std::mdspan(v.data(), 2, 3, 2);

// Write data using 2D view
for (std::size_t i = 0; i != ms2.extent(0); i++)
for (std::size_t j = 0; j != ms2.extent(1); j++)
ms2[i, j] = i * 1000 + j;

// Read back using 3D view
for (std::size_t i = 0; i != ms3.extent(0); i++)
{
std::println("slice @ i = {}", i);
for (std::size_t j = 0; j != ms3.extent(1); j++)
{
for (std::size_t k = 0; k != ms3.extent(2); k++)
std::print("{} ", ms3[i, j, k]);
std::println("");
}
}
}


خروجی:

slice @ i = 0
0 1
2 3
4 5
slice @ i = 1
1000 1001
1002 1003
1004 1005


ماکروی اختصاصی برای بررسی این ویژگی به صورت زیر است:

#ifdef __cpp_lib_mdspan
//TODO...
#endif


#cpp20 #cpp23 #mdspan #extent #rank
1
COMPΞZ 🧬
کلاس std::mdspan و زیر عضو extents در استاندارد ۲۳ این کلاس از نوع template (الگو) است که نمایه‌ای از یک دنبالهٔ پیوسته از عناصر را ارائه می‌دهد و به شما اجازه می‌دهد تا با آن مانند یک آرایه چندبعدی رفتار کنید. این کلاس، توسعه‌ای از کلاس std::span موجود در…
بخش تخصصی دوم (به‌روز رسانی Solidity) |الفاظ آرایه‌ای

آرایه لفظی فهرستی از یک یا چند عبارت است که با کاما از هم جدا شده است که در کروشه ([...]) قرار داده شده است. برای مثال
[1, a, f(3)]


که به طور کل نوع آرایهٔ تحت‌اللفظی به صورت زیر تعیین می‌شود:

- همیشه یک آرایه حافظه با اندازه ثابتی است که طول آن، تعداد عبارات است.
- نوع پایه آرایه، نوع اولین عبارت در لیست است به طوری که تمام عبارات دیگر را می‌توان به طور ضمنی به آن تبدیل کرد. اگر این امکان‌پذیر نباشد، یک خطای نوع است.
- این کافی نیست که یک نوع وجود داشته باشد که می‌توان همه عناصر را به آن تبدیل کرد. یکی از عناصر باید از آن نوع باشد.

در مثال زیر، نوع [3 ,2 ,1] حافظه uint8[3] است، زیرا نوع هر یک از این ثابت ها uint8 است. اگر می‌خواهید نتیجه یک نوع حافظه uint[3] باشد، باید اولین عنصر را به uint تبدیل کنید.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract C {
function f() public pure {
g([uint(1), 2, 3]);
}
function g(uint[3] memory) public pure {
// ...
}
}


آرایه لفظی [1- ,1] نامعتبر است زیرا نوع عبارت اول uint8 است در حالی که نوع دوم int8 است و نمی توان آنها را به طور ضمنی به یکدیگر تبدیل کرد. برای اینکه کار کند، می توانید برای مثال از [int8(1)، -1] استفاده کنید.

از آنجایی که آرایه های حافظه با اندازه ثابت از انواع مختلف را نمی توان به یکدیگر تبدیل کرد (حتی اگر انواع پایه امکان پذیر باشد)، اگر می خواهید از آرایه های دو بعدی استفاده کنید، همیشه باید یک نوع پایه مشترک را به صراحت مشخص کنید:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract C {
function f() public pure returns (uint24[2][4] memory) {
uint24[2][4] memory x = [[uint24(0x1), 1], [0xffffff, 2], [uint24(0xff), 3], [uint24(0xffff), 4]];
// The following does not work, because some of the inner arrays are not of the right type.
// uint[2][4] memory x = [[0x1, 1], [0xffffff, 2], [0xff, 3], [0xffff, 4]];
return x;
}
}


آرایه‌های حافظه با اندازه ثابت را نمی‌توان به آرایه‌های حافظه با اندازه پویا اختصاص داد، یعنی موارد زیر امکان پذیر نیست:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

// This will not compile.
contract C {
function f() public {
// The next line creates a type error because uint[3] memory
// cannot be converted to uint[] memory.
uint[] memory x = [uint(1), 3, 4];
}
}


این گونه برنامه‌ریزی شده است که این محدودیت در آینده حذف شود، اما به دلیل نحوهٔ ارسال آرایه‌ها در ABI، عوارضی ایجاد می‌کند.
اگر می‌خواهید آرایه‌هایی با اندازهٔ پویا را مقداردهی اولیه کنید، باید عناصر جداگانه را اختصاص دهید، به صورت زیر:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract C {
function f() public pure {
uint[] memory x = new uint[](3);
x[0] = 1;
x[1] = 3;
x[2] = 4;
}
}


#solidity #web3 #update #ether #اتریوم