السلام عليكم و رحمة الله و بركاته,
أنهيت قبل فترة مشروعاً بسيطة, المشروع بكل بساطة هو عبارة Python-like Range!
و لكن بلغة ++C و لمبرمجي ++C :)
المشروع يتبع المواصفات القياسية للـ Containers و الـ Iterators, و إذا كنت تريد أن تكون دقيقاً كفاية فهو Immutable random access container.
على العموم المشروع بسيط, و لكنه أخذ جهداً لا بأس به من القراءة حول موضوع الـ STL-like containers و للأسف لم أجد مكاناً يتكلم بشكل وافي عن الموضوع,
و دائماً ما اضطررت الرجوع إلى الوثائق الخاصة بـ ++Cإضافة إلى هذا الموقع الرائع.
الآن ما المطلوب من هذا الموضوع؟ لا ليس دعاية لمشروعي الظريف :lol:
المطلوب هو مبرمج آخر أو اثنان, لكي نجعل المشروع محترم, و نقوم بكتابة مقال مطول حول كيفية البداية في كتابة STL-Like container.
كما قلت سابقاً, المعلومات الموجودة حول الموضوع, إما عن كيفية استخدام STL, أو كتب متقدمة لا تصلح لمن يريد أن يتعرف على الموضوع, و تناقش أمور التصميم.
عموماً, أتمنى لمن يريد المشاركة في كتابة المشروع و المقال(سيكون باللغة العربية و الإنجليزية), أن يذكر ذلك هنا, و نرتب بعد ذلك و لو بشكل بسيط لكي يصبح لدينا علم يصلح نشره,
حتى لا نبدأ من الصفر, فإني قمت بكتابة range كمثال على STL-like Container,
و المكتبة تحتوي على كمية جيدة من التعليقات, إضافة إلى كود اختبار جيد, إضافة إلى ثلاث أمثلة شاملة لكيفية البداية في استخدام range و من ثم التعامل مع STL containers إضافة Standard Algrithms,
ربما الكود يعطي فكرة أوضح. أولاً مع أبسط مثال:
#include <iostream>
#include "../range.hpp"
// everything belongs to range is in Range namespace
using namespace Range;
int main()
{
/*
A range is a sequence of numeric elements.
So, when you declare a range, you specify
the first element(inclusive), the last
element(exclusive) and finally how much
difference is there between each two
successive elements:
range x(first_element = 1,
last_element = 10,
step_size = 2);
The range would be like:
[1, 10), [step = 2]
The elements are:
[1, 3, 5, 7, 9]
*/
range x(1, 10, 2);
// you can use the range as if it were an array!
range::value_type sum_of_range_elements = 0;
for(std::size_t i = 0; i < x.size(); ++i)
{
sum_of_range_elements += x;
}
// you can go with STL-style iterators!
range::value_type product_of_range_elements = 1;
for(range::iterator i = x.begin(); i != x.end(); ++i)
{
product_of_range_elements *= *i;
}
// printing the elements of the range
std::cout << "The range x(1, 10, 2) consists of: [ ";
for(range::iterator i = x.begin(); i != x.end(); ++i)
{
std::cout << *i << ' ';
}
std::cout << ']' << std::endl;
std::cout << "The sum of x elements = "
<< sum_of_range_elements << std::endl;
std::cout << "The product of x elements = "
<< product_of_range_elements << std::endl;
}ثانياً مع كيفية استخدامه مع الـ Container:
#include <iostream>
#include <iomanip>
#include <vector>
#include "../range.hpp"
// everything belongs to range is in Range namespace
using namespace std;
using namespace Range;
int main()
{
// [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
range r(0, 100, 10);
// range interpolates with STL-containers very well.
// in fact it is an STL-like container!
// range::value_type: is simply "int"!
vector<int> numbers( r.begin(), r.end() ),
reversed_numbers( r.rbegin(), r.rend() );
std::cout
<< std::setw(10) << "index"
<< std::setw(20) << "numbers"
<< std::setw(20) << "reversed_numbers"
<< std::endl;
for(std::size_t i = 0; i < numbers.size(); ++i)
{
std::cout
<< std::setw(10) << i
<< std::setw(20) << numbers
<< std::setw(20) << reversed_numbers
<< std::endl;
}
}ثالثاً مع الخوارزميات:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include "../range.hpp"
// everything belongs to range is in Range namespace
using namespace Range;
/*
range works with standards algorithms as well!
range is immutable, i.e. you can't apply
modifiying algorithms on it, only the
non-modifiying algorithms can be applied.
*/
// A simple product functor. We will use it
// with for_each
struct functor
{
functor() : product(1) { }
void operator()(int number)
{
product *= number;
}
int product;
};
// to be used with count_if
bool is_odd(int number)
{
return number % 2 == 1;
}
int main()
{
range r(1, 10, 1); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// with for_each
int product
= std::for_each( r.begin(), r.end(), functor() ).product;
std::cout
<< "the product of the range elements = "
<< product << std::endl;
std::cout << std::endl;
// with count_if
int count_odd_numbers
= std::count_if( r.begin(), r.end(), is_odd );
std::cout
<< "there are " << count_odd_numbers
<< " odd numbers in the range" << std::endl;
std::cout << std::endl;
// with accumulate
// sum = 1000 + (range elements summation)
int sum
= std::accumulate( r.begin(), r.end(), 1000 );
std::cout
<< "the sum of the range elements + 1000 = "
<< sum << std::endl;
std::cout << std::endl;
// with partial_sum
std::vector<int> partial_summation( r.size() );
std::partial_sum( r.begin(), r.end(), partial_summation.begin() );
for(std::size_t i = 0; i < partial_summation.size(); ++i)
std::cout
<< "partial summation until " << r
<< " = " << partial_summation << std::endl;
std::cout << std::endl;
}تحياتي,

