Outils pour utilisateurs

Outils du site


lib:boost

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lib:boost [2019/11/12 17:41] – Ajout de l'exécuteur rootlib:boost [2020/07/05 00:37] (Version actuelle) – [boost::asio::execution_context] : code -> gh root
Ligne 1: Ligne 1:
-===Compilation sous Windows===+====Windows==== 
 +===Compilation===
 <code bash> <code bash>
 git clone https://github.com/boostorg/boost.git git clone https://github.com/boostorg/boost.git
Ligne 16: Ligne 17:
 ''-mt'', ''-gd'', ... voir [[https://www.boost.org/doc/libs/1_69_0/more/getting_started/windows.html]] ''-mt'', ''-gd'', ... voir [[https://www.boost.org/doc/libs/1_69_0/more/getting_started/windows.html]]
  
-===Exécuteur===+====boost::asio::execution_context====
 L'exécuteur a les caractéristiques suivantes : L'exécuteur a les caractéristiques suivantes :
   * Fonctionnement entre thread, pas entre application via TCP,   * Fonctionnement entre thread, pas entre application via TCP,
   * Toujours en fonctionnement. En attente s'il n'a plus de travail à faire.   * Toujours en fonctionnement. En attente s'il n'a plus de travail à faire.
  
-Entête :+{{gh>https://github.com/bansan85/wiki_le_garrec_fr/blob/master/cpp/boost/executor/executor.h}} 
 + 
 +{{gh>https://github.com/bansan85/wiki_le_garrec_fr/blob/master/cpp/boost/executor/executor.cpp}} 
 + 
 +{{gh>https://github.com/bansan85/wiki_le_garrec_fr/blob/master/cpp/boost/executor/main.cpp}} 
 +====boost::algorithm==== 
 +===boost::algorithm::join et boost::adaptors::transformed===
 <code cpp> <code cpp>
-#include <functional> +#include <iostream>
-#include <memory>+
  
-class PriorityScheduler +#include <boost/algorithm/string/join.hpp> 
-+#include <boost/range/adaptor/transformed.hpp>
- public: +
-  // Classe satisfaisant l'interface Executor. +
-  class ExecutorType +
-  { +
-   public: +
-    ExecutorType(PriorityScheduler& ctx, int pri); +
-    ~ExecutorType();+
  
-    ExecutorType(ExecutorType&& other) noexcept; +#include <string>
-    ExecutorType(ExecutorType const& other) = delete; +
-    ExecutorType& operator=(ExecutorType&& other) noexcept = delete; +
-    ExecutorType& operator=(ExecutorType const& other) = delete;+
  
-    // Pour boost::asio::dispatch +struct Data 
-    PriorityScheduler& context() const noexcept;+
 +  std::string name; 
 +  std::string version; 
 +};
  
-    void add(std::function<void()f);+int main(
 +
 +  std::vector<Datav{ {"Name1", "Version 1"}, {"Name2", "Version 2"} };
  
-   private+  std::cout << 
-    class ExecutorTypeImpl; +  boost::algorithm::join( 
-    std::unique_ptr<ExecutorTypeImpl> impl_+    v | 
-  };+    boost::adaptors::transformed( 
 +      [](const Data& firmware) 
 +      { 
 +        return firmware.name + " / " + firmware.version
 +      } 
 +    ), 
 +    ", ") << 
 +  std::endl;
  
-  PriorityScheduler()+  return 0
-  ~PriorityScheduler();+
 +</code>
  
-  ExecutorType get_executor(int pri) noexcept;+====Migrer de boost vers std==== 
 +===Pointeur intelligent===
  
-  void run();+Aucune différence entre : 
 +  * ''std::shared_ptr'' et ''boost::shared_ptr'', 
 +  * ''std::unique_ptr'' et ''boost::unique_ptr'', 
 +  * ''std::weak_ptr'' et ''boost::weak_ptr'', 
 +  * ''std::make_shared'' et ''boost::make_shared'', 
 +  * ''std::enable_shared_from_this'' et ''boost::enable_shared_from_this''.
  
-  void stop();+<WRAP center round important 60%> 
 +''shared_ptr'', ''make_shared'' et ''enable_shared_from_this'' doivent tous venir de la même libraire. L'un en version ''std'' et l'autre en version ''boost'' sont incompatibles. 
 +</WRAP>
  
- private: +  * boost::ref et std::ref.
-  class PrioritySchedulerImpl; +
-  std::unique_ptr<PrioritySchedulerImpl> impl_; +
-};+
  
-bool operator==(const PriorityScheduler::ExecutorType& a, +===assign===
-                const PriorityScheduler::ExecutorType& b) noexcept;+
  
-bool operator!=(const PriorityScheduler::ExecutorType& a, +Utiliser list_initializer. 
-                const PriorityScheduler::ExecutorType& bnoexcept+ 
-}+<code cpp> 
 +//const std::list<int> primes = boost::assign::list_of(2)(3)(5)(7)(11); 
 +const std::list<int> primes {2, 3, 5, 7, 11};
 </code> </code>
  
-Source :+===foreach===
  
 <code cpp> <code cpp>
-#include "Executeur.h"+short array_short[] = { 1, 2, 3 }; 
 +BOOST_FOREACH( short & i, array_short ) 
 +  ++i; 
 +</code>
  
-#include <atomic+<code cpp
-#include <boost/asio.hpp> +short array_short[] = { 1, 2, 3 }; 
-#include <queue> +for (short & i : array_short) 
-#include <vector>+  ++i; 
 +</code>
  
-class PriorityScheduler::PrioritySchedulerImpl +Et avec des containers multi valeurs 
-    public boost::asio::execution_context+ 
 +<code cpp> 
 +std::map<const int, int> m; 
 +int key, value; 
 +BOOST_FOREACH(boost::tie(key, value), m)
 { {
- public: +  // do something with key and value here 
-  void run() +} 
-  { +</code>
-    std::unique_lock<std::mutexlock(mutex_); +
-    for (;;) +
-    { +
-      condition_.wait(lock, [&] { return stopped_ || !queue_.empty(); }); +
-      if (stopped_) return; +
-      auto p(queue_.top()); +
-      queue_.pop(); +
-      lock.unlock(); +
-      p->execute_(p); +
-      lock.lock(); +
-    } +
-  }+
  
-  void stop() +<code cpp> 
-  { +std::map<int, int> m; 
-    stopped_ = true+int key, value
-    condition_.notify_all(); +// Ici, key sera en lecture seule (implicite à la structure de std::map) et value sera accessible en écriture. 
-  }+// En cas de présente / absence explicite de const, cela s'applique obligatoirement à toutes les variables. 
 +for(auto & [key, value] : m) 
 +{ 
 +  // do something with key and value here 
 +} 
 +</code>
  
-  struct item_base +===optional===
-  { +
-    // Priorité de l'ordre. +
-    int priority_; +
-    // Pour trier les item ayant le même ordre. +
-    std::chrono::high_resolution_clock::time_point timestamp; +
-    // Fonction a exécuter dans un wrapper compatible avec +
-    // boost::asio::dispatch. +
-    std::function<void(std::shared_ptr<item_base>&)> execute_; +
-  };+
  
-  template <class Func> +Il ne devrait pas y avoir de problèmes. Il faut noter que ''std'' ne supporte pas les références ''std::optional<int&>''.
-  struct item : item_base +
-  { +
-    item(int pri, Func f) : function_(std::move(f)) +
-    { +
-      priority_ = pri; +
-      execute_ = [](std::shared_ptr<item_base>p) { +
-        Func tmp(std::move(static_cast<item*>(p.get())->function_)); +
-        p.reset(); +
-        tmp(); +
-      }; +
-      timestamp = std::chrono::high_resolution_clock::now(); +
-    }+
  
-    Func function_; +''boost::none'' devient ''std::nullopt''.
-  };+
  
-  // Pour comparer les items et savoir quel sera la prochaine fonction à +===regex===
-  // exécuter. +
-  struct item_comp +
-  { +
-    bool operator()(const std::shared_ptr<item_base>& a, +
-                    const std::shared_ptr<item_base>& b) +
-    { +
-      if (a->priority_ !b->priority_) +
-        return a->priority_ < b->priority_; +
-      else +
-        return a->timestamp > b->timestamp; +
-    } +
-  };+
  
-  std::mutex mutex_; +Cette fonctionnalité était très peu utilisée.
-  std::condition_variable condition_; +
-  std::priority_queue<std::shared_ptr<item_base>, +
-                      std::vector<std::shared_ptr<item_base>>, item_comp> +
-      queue_; +
-  std::atomic<bool> stopped_ = false; +
-};+
  
-class PriorityScheduler::ExecutorType::ExecutorTypeImpl +<code cpp> 
-+boost::regex_search(name, whatpath, expmatchIndexPath, boost::match_default); 
- public+// std::regex_search ne supporte pas le 4ème paramètre. 
-  ExecutorTypeImpl(PriorityScheduler& ctx, int pri) noexcept +std::regex_search(namewhatpath, expmatchIndexPath); 
-      context_(ctx)priority_(pri+</code>
-  { +
-  }+
  
-  ExecutorTypeImpl(ExecutorTypeImpl&& other) noexcept = default; +Sinon, ''boost::cmatch'' et ''boost::regex'' sont identiques à ''std::cmatch'' et ''std::regex''.
-  ExecutorTypeImpl(ExecutorTypeImpl const& other) = delete; +
-  ExecutorTypeImpl& operator=(ExecutorTypeImpl&& other) noexcept = default; +
-  ExecutorTypeImpl& operator=(ExecutorTypeImpl const& other) = delete;+
  
-  // Pour boost::asio::dispatch +===variant===
-  PriorityScheduler& context() const noexcept { return context_; }+
  
-  // Pour boost::asio::dispatch +<code cpp> 
-  void on_work_started() const noexcept {}+boost::variant<int, double> v = 5; 
 +double d = boost::get<double>(v); // Génère une exception 
 +double *d = boost::get<double>(&v); // Renvoi nullptr 
 +</code>
  
-  // Pour boost::asio::dispatch +devient
-  void on_work_finished() const noexcept {}+
  
-  // Partout Func est boost::asio::detail::work_dispatcher<void()+<code cpp
-  template <class Funcclass Alloc+std::variant<intdoublev = 5; 
-  void dispatch(Func&& f, const Alloc& aconst +double d = std::get<double>(v); // Génère une exception 
-  { +double *d = std::get_if<double>(&v); // Renvoi nullptr 
-    post(std::forward<Func>(f), a); +</code>
-  }+
  
- private: +''boost::apply_visitor'' devient ''std::visit''.
-  PriorityScheduler& context_; +
-  int priority_;+
  
-  template <class Funcclass Alloc> +Attention, ''boost::variant<int, int>'' est accepté mais pas ''std::variant<intint>''Dans tous les cas, il ne faut pas y avoir deux fois le même type.
-  void post(Func f, const Alloc& a) const +
-  { +
-    // On se force à utiliser l'allocateur fournit. +
-    auto p(std::allocate_shared< +
-           PriorityScheduler::PrioritySchedulerImpl::item<Func>>( +
-        typename std::allocator_traits<Alloc>::template rebind_alloc<char>(a), +
-        priority_, std::move(f))); +
-    // On sécurise seulement queue_. +
-    { +
-      std::lock_guard<std::mutexlock(context_.impl_->mutex_); +
-      context_.impl_->queue_.push(p); +
-    } +
-    context_.impl_->condition_.notify_one(); +
-  }+
  
-  // Pour boost::asio::dispatch +===tuple===
-  template <class Func, class Alloc> +
-  void defer(Func&& f, const Alloc& a) const +
-  { +
-    post(std::forward<Func>(f), a); +
-  } +
-};+
  
-// Impl idiome +Non testé la migration.
-PriorityScheduler::ExecutorType::ExecutorType(PriorityScheduler& ctx, int pri) +
-    : impl_(std::make_unique<ExecutorTypeImpl>(ctx, pri)) +
-+
-}+
  
-PriorityScheduler::ExecutorType::~ExecutorType() default;+===bind===
  
-PriorityScheduler::ExecutorType::ExecutorType(ExecutorType&& other) noexcept = +Les deux sont compatibles. Mais il est préférable de les remplacer par des fonctions lambda.
-    default;+
  
-PriorityScheduler& PriorityScheduler::ExecutorType::context() const noexcept +===filesystem===
-+
-  return impl_->context(); +
-}+
  
-void PriorityScheduler::ExecutorType::add(std::function<void()> f) +Dans les cas basiques que j'ai eu, je n'ai pas eu de différences. Mais il y a [[https://www.bfilipek.com/2019/05/boost-to-stdfs.html|quelques différences]] apparemment. {{ :lib:boost:bartek_s_coding_blog_converting_from_boost_to_std_filesystem_2020-03-03_10_10_25_am_.html |Archive du 06/05/2019 le 03/03/2020}}
-+
-  boost::asio::dispatch(*impl_, f); +
-}+
  
-bool operator==(const PriorityScheduler::ExecutorType& a, +  * ''boost::filesystem::ifstream''
-                const PriorityScheduler::ExecutorType& b) noexcept +
-+
-  return &a.context() == &b.context(); +
-}+
  
-bool operator!=(const PriorityScheduler::ExecutorType& a, +<code cpp> 
-                const PriorityScheduler::ExecutorType& b) noexcept +#include <boost/filesystem/fstream.hpp>
-+
-  return &a.context() != &b.context(); +
-}+
  
-PriorityScheduler::PriorityScheduler() +boost::filesystem::path currentPath; 
-    impl_(std::make_unique<PrioritySchedulerImpl>()) +boost::filesystem::ifstream ifs(nextPath); 
-+</code>
-}+
  
-PriorityScheduler::~PriorityScheduler() = default;+devient
  
-PriorityScheduler::ExecutorType PriorityScheduler::get_executor( +<code cpp> 
-    int pri) noexcept +#include <filesystem> 
-+#include <fstream>
-  return PriorityScheduler::ExecutorType(*this, pri); +
-}+
  
-void PriorityScheduler::run() { impl_->run()} +std::filesystem::path currentPath
- +std::ifstream ifs(nextPath.c_str());
-void PriorityScheduler::stop() { impl_->stop(); }+
 </code> </code>
  
-Utilisation :+  * ''boost::filesystem::copy_option''
  
-<code cpp> +Il devient ''std::filesystem::copy_options''. Le nom des enum est différent :
-#include <atomic> +
-#include <chrono> +
-#include <iostream> +
-#include <string>+
  
-#include "Executeur.h"+''overwrite_if_exists'' devient ''overwrite_existing''
 +''fail_if_exists'' devient ''skip_existing''.
  
-std::atomic<int> test = 0;+  * Deprecated
  
-int main() +''leaf()'' devient ''filename()''.
-+
-  PriorityScheduler sched;+
  
-  PriorityScheduler::ExecutorType&& nulle = sched.get_executor(-1); +[[https://www.boost.org/doc/libs/1_72_0/libs/filesystem/doc/deprecated.html|Deprecated names and features]] {{ :lib:boost:filesystem_deprecated_features_2020-04-21_2_58_20_pm_.html |Archive du 29/12/2014 le 21/04/2020}}
-  PriorityScheduler::ExecutorType&& low = sched.get_executor(0); +
-  PriorityScheduler::ExecutorType&& med = sched.get_executor(1); +
-  PriorityScheduler::ExecutorType&& high = sched.get_executor(2);+
  
-  med.add([] { std::cout << "2\n"; }); +===thread===
-  low.add([] { std::cout << "1\n"; }); +
-  med.add([] { std::cout << "22\n"; }); +
-  low.add([] { std::cout << "11\n"; }); +
-  high.add([] { std::cout << "3\n"; }); +
-  high.add([] { std::cout << "33\n"; }); +
-  high.add([] { std::cout << "333\n"; });+
  
-  nulle.add([&sched] { sched.stop(); });+  * ''thread.join'' : si le thread n'est pas ''joinable()'', ''boost'' ne fait rien mais ''std'' génère une exception.
  
-  std::thread t([&sched] { sched.run(); });+===shared_mutex===
  
-  t.join(); +Il n'y a pas d'équivalent car ''std'' ne supporte pas le timeout. 
-}+ 
 +Il faut alors faire une boucle où on passe son temps à faire un ''try_lock_shared'' pendant le temps nécessaire. 
 + 
 +===scoped_array=== 
 + 
 +Peut se remplacer sans problème par un ''std::vector''
 + 
 +===algorithm=== 
 +  * string 
 + 
 +<code cpp> 
 +std::string str; 
 +return boost::to_upper_copy(str);
 </code> </code>
  
-Rendu : +devient 
-<code> + 
-3 +<code cpp
-33 +std::string str; 
-333 +std::transform(str.begin(), str.end(), str.begin(), ::toupper); 
-+return std::move(str);
-22 +
-+
-11+
 </code> </code>
 +
 +===boost::lexical_cast===
 +
 +''boost::lexical_cast<std::string>(number)'' devient ''std::to_string(number)''.
lib/boost.1573576881.txt.gz · Dernière modification : de root