Loading lang_cpp_tr_02...
//----------------------------------------------------------------------------
#ifndef S4PRC_NOISY_HPP #define S4PRC_NOISY_HPP
#include <iostream> #include <string> #include <vector>
namespace s4prc {
inline std::ostream & operator<<(std::ostream &output, const std::string &s) // display string within quotes { using std::operator<<; output << '"'; if(const auto sz=size(s); sz>20) // prevent from using too much space { output << s.substr(0, 10) << "..." << s.substr(sz-10); } else { output << s; } return output << '"'; }
template<typename E> inline std::ostream & operator<<(std::ostream &output, const std::vector<E> &v) // display vector within braces { output << '{'; if(const auto sz=size(v); sz>4) // prevent from using too much space { output << v[0] << ',' << v[1] << ",...," << v[sz-2] << ',' << v[sz-1]; } else { int count=0; for(const auto &elem: v) { if(count++) { output << ','; } output << elem; } } return output << '}'; }
template<typename T> struct Noisy : T { Noisy() : T{} { std::cout << "construct " << *this << " from nothing\n"; }
Noisy(const T &t) : T{t} { std::cout << "copy-construct " << *this << "\n ... from " << t << '\n'; }
Noisy(T &&t) : T{std::move(t)} { std::cout << "move-construct " << *this << "\n ... from (moved) " << t << '\n'; }
Noisy(const Noisy &n) : T{static_cast<const T &>(n)} { std::cout << "copy-construct " << *this << "\n ... from " << n << '\n'; }
Noisy(Noisy &&n) noexcept : T{std::move(static_cast<T &&>(n))} { std::cout << "move-construct " << *this << "\n ... from (moved) " << n << '\n'; }
Noisy & operator=(const T &t) { T::operator=(t); std::cout << "copy-assign " << *this << "\n ... from " << t << '\n'; return *this; }
Noisy & operator=(T &&t) { T::operator=(std::move(t)); std::cout << "move-assign " << *this << "\n ... from (moved) " << t << '\n'; return *this; }
Noisy & operator=(const Noisy &n) { T::operator=(static_cast<const T &>(n)); std::cout << "copy-assign " << *this << "\n ... from " << n << '\n'; return *this; }
Noisy & operator=(Noisy &&n) noexcept { T::operator=(std::move(static_cast<T &&>(n))); std::cout << "move-assign " << *this << "\n ... from (moved) " << n << '\n'; return *this; }
~Noisy() { std::cout << "destroy " << *this << '\n'; }
friend std::ostream & operator<<(std::ostream &output, const Noisy &n) { return output << "Noisy@" << &n << ":" << static_cast<const T &>(n); } };
} // namespace s4prc
#endif // S4PRC_NOISY_HPP
//----------------------------------------------------------------------------
#if 1 s4prc::Noisy<std::vector<int>> values; #else std::vector<int> values; #endif
/*...*/make_IntSet("v1", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
std::string n1="v1"; std::vector<int> d1={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /*...*/make_IntSet(std::move(n1),std::move(d1));
<U>pour symboliser l'union.
v1={1, 2, 3}et l'opérande droit par
v2={2, 4, 6}, alors, après l'opération +=, l'opérande gauche sera représenté par
(v1<U>v2)={1, 2, 3, 4, 6}. Il est usuel, lorsqu'un opérateur += est réalisé, de fournir également un opérateur +.
<I>ou
<D>, selon le cas, pour symboliser l'intersection ou la différence symétrique.
v1={1, 2, 3}et l'opérande droit par
v2={2, 4, 6}, alors l'intersection sera représentée par
(v1<I>v2)={2}et la différence symétrique par
(v1<D>v2)={1, 3, 4, 6}.
//----------------------------------------------------------------------------
#ifndef SHARING_INTSET_HPP #define SHARING_INTSET_HPP
#include <string> #include <vector> #include <tuple> #include "noisy.hpp"
namespace sharing {
struct IntSet { std::string name; #if 1 s4prc::Noisy<std::vector<int>> values; #else std::vector<int> values; #endif };
IntSet make_IntSet(std::string name, std::vector<int> value);
std::string to_string(const IntSet &is);
bool contains(const IntSet &is, int value);
IntSet & operator+=(IntSet &lhs, const IntSet &rhs);
IntSet operator+(const IntSet &lhs, const IntSet &rhs);
std::tuple<IntSet, // intersection IntSet> // symetric-difference intersect(const IntSet &is1, const IntSet &is2);
} // namespace sharing
#endif // SHARING_INTSET_HPP
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#include "int_set.hpp"
namespace sharing {
IntSet make_IntSet(std::string name, std::vector<int> values) { return IntSet{std::move(name), std::move(values)}; }
std::string to_string(const IntSet &is) { std::string txt; for(const auto &elem: is.values) { if(!empty(txt)) { txt+=", "; } txt+=std::to_string(elem); } return is.name+"={"+txt+"}"; }
bool contains(const IntSet &is, int value) { for(const auto &elem: is.values) { if(elem==value) { return true; } } return false; }
IntSet & operator+=(IntSet &lhs, const IntSet &rhs) { lhs.name='('+lhs.name+"<U>"+rhs.name+')'; for(const auto &elem: rhs.values) { if(!contains(lhs, elem)) { lhs.values.emplace_back(elem); } } return lhs; }
IntSet operator+(const IntSet &lhs, const IntSet &rhs) { IntSet result{lhs}; result+=rhs; return result; }
std::tuple<IntSet, // intersection IntSet> // symetric-difference intersect(const IntSet &is1, const IntSet &is2) { IntSet intersection, difference; intersection.name='('+is1.name+"<I>"+is2.name+')'; difference.name='('+is1.name+"<D>"+is2.name+')'; for(const auto &elem: is1.values) { if(contains(is2, elem)) { intersection.values.emplace_back(elem); } else { difference.values.emplace_back(elem); } } for(const auto &elem: is2.values) { if(!contains(is1, elem)) { difference.values.emplace_back(elem); } } return {std::move(intersection), std::move(difference)}; }
} // namespace sharing
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#include <iostream> #include "int_set.hpp"
void test_IntSet() { std::cout << "\n~~~~ " << __func__ << "() ~~~~\n"; std::string n1="v1"; std::vector<int> d1={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; const auto v1=sharing::make_IntSet(std::move(n1),std::move(d1)); // std::cout << to_string(v1) << '\n'; std::cout << "does v1 contain 7? --> " << contains(v1, 7) << '\n'; std::cout << "does v1 contain 12? --> " << contains(v1, 12) << '\n'; // const auto v2=sharing::make_IntSet("v2", {3, 5, 7, 9, 11, 13}); std::cout << to_string(v2) << '\n'; const auto v3=v1+v2; std::cout << to_string(v3) << '\n'; // const auto [v4, v5]=intersect(v1, v2); std::cout << to_string(v4) << '\n'; std::cout << to_string(v5) << '\n'; }
int main() { test_IntSet(); return 0; }
//----------------------------------------------------------------------------