Сообщение Re[10]: Философско-практические вопросы про метапрограммиров от 11.02.2023 15:49
Изменено 11.02.2023 16:18 rg45
Re[10]: Философско-практические вопросы про метапрограммиров
Здравствуйте, ботаныч, Вы писали:
Б>https://onlinegdb.com/4hmabsGci
Б>да вот же, я же говорю, это просто проверка на инстанс сета ))
Зачем нам эта проверка? Эта утилита же в контексте задачи родилась, правда? Вот и примени это при решении задачи: http://coliru.stacked-crooked.com/a/dc4a0f66d5c4605b. Только не умозрительно, а чтоб работало. Потом сравним. Обрати внимание, пример немного изменен — добавлены пространства имен, как это обычно бывает в реальной жизни.
Б>https://onlinegdb.com/4hmabsGci
Б>да вот же, я же говорю, это просто проверка на инстанс сета ))
Зачем нам эта проверка? Эта утилита же в контексте задачи родилась, правда? Вот и примени это при решении задачи: http://coliru.stacked-crooked.com/a/dc4a0f66d5c4605b. Только не умозрительно, а чтоб работало. Потом сравним. Обрати внимание, пример немного изменен — добавлены пространства имен, как это обычно бывает в реальной жизни.
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <utility>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Generic Library Area
namespace lib
{
template <typename, typename = void>
struct has_sort_member_function : std::false_type {};
template <typename T>
struct has_sort_member_function<T, std::void_t<decltype(std::declval<T&>().sort())>> : std::true_type {};
template <typename, typename = void>
struct is_std_sort_applicable : std::false_type{};
template <typename T>
struct is_std_sort_applicable<T, std::void_t<
decltype(std::sort(std::begin(std::declval<T&>()), std::end(std::declval<T&>()))),
decltype(*std::begin(std::declval<T&>()) = *std::begin(std::declval<T&>()))
>> : std::true_type {};
template <typename T>
auto assume_sorted_range(const T&) -> std::false_type;
// For standard containers, the traits must be defined beforehand
template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::map<K, T, C, A>&) -> std::true_type;
template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::multimap<K, T, C, A>&) -> std::true_type;
template <typename T, typename C, typename A>
auto assume_sorted_range(const std::set<T, C, A>&) -> std::true_type;
template <typename T, typename C, typename A>
auto assume_sorted_range(const std::multiset<T, C, A>&) -> std::true_type;
template <typename T>
using is_sorted_container = decltype(assume_sorted_range(std::declval<T>()));
template <typename T, std::enable_if_t<has_sort_member_function<T>::value, int> = 0>
void sort(T& t)
{
t.sort();
}
template <typename T, std::enable_if_t<
is_std_sort_applicable<T>::value &&
!has_sort_member_function<T>::value &&
!is_sorted_container<T>::value,
int> = 0>
void sort(T& t)
{
std::sort(std::begin(t), std::end(t));
}
template <typename T, std::enable_if_t<
is_sorted_container<T>::value &&
!has_sort_member_function<T>::value,
int> = 0>
void sort(const T&)
{
// Container is sorted already, so nothing to do.
}
} // namespace lib
namespace app1 {
namespace app2 {
namespace app3 {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Custom Application Area
struct MySortedContainer
{
};
auto assume_sorted_range(const MySortedContainer&) -> std::true_type;
struct MyContainer
{
void sort() { std::cout << "MyContainer::sort" << std::endl; }
};
void test()
{
std::string string = "Hello World!";
lib::sort(string);
std::cout << "<" << string << ">" << std::endl;
int array[] { 3, 5, 2, 9, 1, 7, 4, 8, 0, 6 };
lib::sort(array);
std::vector<int> vector { 3, 5, 2, 9, 1, 7, 4, 8, 0, 6 };
lib::sort(vector);
std::set<int> set { 3, 5, 2, 9, 1, 7, 4, 8, 0, 6 };
lib::sort(set); // no effect
MyContainer my_container;
lib::sort(my_container);
MySortedContainer my_sorted_container;
lib::sort(my_sorted_container); // no effect
char str[] = "Hello World!";
lib::sort(str); // Ok
// lib::sort("Hello World!"); // error: no matching function for call
}
} // namespace app3
} // namespace app2
} // namespace app1
int main()
{
app1::app2::app3::test();
}
Re[10]: Философско-практические вопросы про метапрограммиров
Здравствуйте, ботаныч, Вы писали:
Б>https://onlinegdb.com/4hmabsGci
Б>да вот же, я же говорю, это просто проверка на инстанс сета ))
Зачем нам эта проверка? Эта утилита же в контексте задачи родилась, правда? Вот и примени это при решении задачи: http://coliru.stacked-crooked.com/a/fdbaf2f292d21344. Только не умозрительно, а чтоб работало. Потом сравним. Обрати внимание, пример немного изменен — добавлены пространства имен, как это обычно бывает в реальной жизни.
Б>https://onlinegdb.com/4hmabsGci
Б>да вот же, я же говорю, это просто проверка на инстанс сета ))
Зачем нам эта проверка? Эта утилита же в контексте задачи родилась, правда? Вот и примени это при решении задачи: http://coliru.stacked-crooked.com/a/fdbaf2f292d21344. Только не умозрительно, а чтоб работало. Потом сравним. Обрати внимание, пример немного изменен — добавлены пространства имен, как это обычно бывает в реальной жизни.
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <utility>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Generic Library Area
namespace lib
{
template <typename, typename = void>
struct has_sort_member_function : std::false_type {};
template <typename T>
struct has_sort_member_function<T, std::void_t<decltype(std::declval<T&>().sort())>> : std::true_type {};
template <typename, typename = void>
struct is_std_sort_applicable : std::false_type{};
template <typename T>
struct is_std_sort_applicable<T, std::void_t<
decltype(std::sort(std::begin(std::declval<T&>()), std::end(std::declval<T&>()))),
decltype(*std::begin(std::declval<T&>()) = *std::begin(std::declval<T&>()))
>> : std::true_type {};
template <typename T>
auto assume_sorted_range(const T&) -> std::false_type;
// For standard containers, the traits must be defined beforehand
template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::map<K, T, C, A>&) -> std::true_type;
template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::multimap<K, T, C, A>&) -> std::true_type;
template <typename T, typename C, typename A>
auto assume_sorted_range(const std::set<T, C, A>&) -> std::true_type;
template <typename T, typename C, typename A>
auto assume_sorted_range(const std::multiset<T, C, A>&) -> std::true_type;
template <typename T>
using is_sorted_container = decltype(assume_sorted_range(std::declval<T>()));
template <typename T, std::enable_if_t<has_sort_member_function<T>::value, int> = 0>
void sort(T& t)
{
t.sort();
}
template <typename T, std::enable_if_t<
is_std_sort_applicable<T>::value &&
!has_sort_member_function<T>::value &&
!is_sorted_container<T>::value,
int> = 0>
void sort(T& t)
{
std::sort(std::begin(t), std::end(t));
}
template <typename T, std::enable_if_t<
is_sorted_container<T>::value &&
!has_sort_member_function<T>::value,
int> = 0>
void sort(const T&)
{
// Container is sorted already, so nothing to do.
}
} // namespace lib
namespace app1 {
namespace app2 {
namespace app3 {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Custom Application Area
class MySortedContainer
{
public:
auto begin() const { return m.begin(); }
auto end() const { return m.end(); }
void add_element(int key, int value) { m.emplace(key, value); }
private:
std::map<int, int> m;
};
auto assume_sorted_range(const MySortedContainer&) -> std::true_type;
struct MyContainer
{
void sort() { std::cout << "MyContainer::sort" << std::endl; }
};
void test()
{
std::string string = "Hello World!";
lib::sort(string);
std::cout << "<" << string << ">" << std::endl;
int array[] { 3, 5, 2, 9, 1, 7, 4, 8, 0, 6 };
lib::sort(array);
std::vector<int> vector { 3, 5, 2, 9, 1, 7, 4, 8, 0, 6 };
lib::sort(vector);
std::set<int> set { 3, 5, 2, 9, 1, 7, 4, 8, 0, 6 };
lib::sort(set); // no effect
MyContainer my_container;
lib::sort(my_container);
MySortedContainer my_sorted_container;
lib::sort(my_sorted_container); // no effect
char str[] = "Hello World!";
lib::sort(str); // Ok
// lib::sort("Hello World!"); // error: no matching function for call
}
} // namespace app3
} // namespace app2
} // namespace app1
int main()
{
app1::app2::app3::test();
}