Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

platform dependency #47

Open
kotoroshinoto opened this issue Jul 26, 2018 · 1 comment
Open

platform dependency #47

kotoroshinoto opened this issue Jul 26, 2018 · 1 comment

Comments

@kotoroshinoto
Copy link

couldn't test on windows, due to missing poll.h

@chanangaza
Copy link

If still relevant, I have modified the code into a single header file that successfully compiles on Windows10 (VS19, C++20).
note: add the following library to link (e.g. proj-properties->linker->input: Additional Dependencies)
Ws2_32.lib

mainly supporting non-win32 headers pole.h & unistd.h...
below is the code for single-header tqdm.h:


//! this file was modified by chanangaza into a single-header file. it includes some adjustments to make it compile on Windows.
/* licenses and permutations same as original
`tqdm` is a product of collaborative work.
Unless otherwise stated, all authors (see commit logs) retain copyright
for their respective work, and release the work under the MIT licence
(text below).

Exceptions or notable authors are listed below
in reverse chronological order:

* MPLv2.0 (text below) 2015-2016 (c) Casper da Costa-Luis
  [casperdcl](https://github.com/casperdcl).


Mozilla Public Licence (MPL) v. 2.0 - Exhibit A
-----------------------------------------------

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.


MIT License (MIT)
-----------------

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ADHD_TQDM_H
#define ADHD_TQDM_H

#include <cassert>      // assert
#include <cinttypes>    // PRIu64
#include <cstddef>      // ptrdiff_t, size_t
#include <cstdint>      // int64_t
#include <cstdio>       // printf

#include <iterator>     // iterator
#include <limits>       // numeric_limits
#include <stdexcept>    // throw
#include <string>       // string
#include <type_traits>  // is_pointer, ...
#include <utility>      // swap

// ---------------  INSERTION of https://github.com/tqdm/tqdm.cpp/blob/master/include/tqdm/utils.h to make it a single-header file -------------------

#ifndef CUR_OS

#if !defined(IS_WIN) && (defined(_WIN32) || defined(_WIN64))
#define IS_WIN
#elif !defined IS_NIX &&                                                     \
    (defined(unix) || defined(__unix) || defined(__unix__) ||                \
     defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||     \
     defined(__MACH__))
#define IS_NIX
#endif

#endif  // CUR_OS

#include <cassert>      // assert
#include <cstddef>      // ptrdiff_t, size_t
#include <iterator>     // iterator
#include <type_traits>  // is_pointer, ...
#include <atomic>       // atomic
#include <cstring>      // strlen
#include <cerrno>       // EAGAIN

// ---------------------------- insertion of portable pole.h @sa https://github.com/libressl-portable/portable/blob/master/include/compat/poll.h
//! need to add to link:
//! Ws2_32.dll
//! @sa https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(WINSOCK2%252FWSAPoll);k(WSAPoll);k(DevLang-C%252B%252B);k(TargetOS-Windows)%26rd%3Dtrue
/*
 * Public domain
 *
 * poll(2) emulation for Windows
 *
 * This emulates just-enough poll functionality on Windows to work in the
 * context of the openssl(1) program. This is not a replacement for
 * POSIX.1-2001 poll(2).
 *
 * Dongsheng Song <dongsheng.song@gmail.com>
 * Brent Cook <bcook@openbsd.org>
 */

#ifndef LIBCRYPTOCOMPAT_POLL_H
#define LIBCRYPTOCOMPAT_POLL_H

#ifndef _WIN32
#include_next <poll.h>
#else

#include <winsock2.h> //! chanangaza:  add to projProperties->link->inputs: Ws2_32.dll


/* Type used for the number of file descriptors. */
typedef unsigned long int nfds_t;

#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600)
/* Data structure describing a polling request. */
struct pollfd {
    int fd; /* file descriptor */
    short events; /* requested events */
    short revents; /* returned events */
};

/* Event types that can be polled */
#define POLLIN 0x001 /* There is data to read. */
#define POLLPRI 0x002 /* There is urgent data to read. */
#define POLLOUT 0x004 /* Writing now will not block. */

# define POLLRDNORM 0x040 /* Normal data may be read. */
# define POLLRDBAND 0x080 /* Priority data may be read. */
# define POLLWRNORM 0x100 /* Writing now will not block. */
# define POLLWRBAND 0x200 /* Priority data may be written. */

/* Event types always implicitly polled. */
#define POLLERR 0x008 /* Error condition. */
#define POLLHUP 0x010 /* Hung up. */
#define POLLNVAL 0x020 /* Invalid polling request. */

#endif

#ifdef __cplusplus
extern "C" {
#endif

int poll(struct pollfd *pfds, nfds_t nfds, int timeout) //;
{
    return ::WSAPoll(pfds, nfds, timeout); //! chanangaza: added delegated call to WSAPoll
}

#ifdef __cplusplus
}
#endif

#endif /* HAVE_POLL */

#endif /* LIBCRYPTOCOMPAT_POLL_H */


// ---------------------------- end of pole.h insertion --------

//! chanangaza: the following was taken from :https://github.com/p-ranav/indicators/blob/master/single_include/indicators/indicators.hpp
// This headers provides the `isatty()`/`fileno()` functions,
// which are used for testing whether a standart stream refers
// to the terminal. As for Windows, we also need WinApi funcs
// for changing colors attributes of the terminal.
#if defined(IS_NIX)
#   include <unistd.h>
#elif defined(IS_WIN)
#   if defined(_MSC_VER)
#       if !defined(NOMINMAX)
#           define NOMINMAX
        #endif
#       include <io.h>
#       include <windows.h>
#   endif
#endif

//! chanangaza: back to original code...
/** TODO: port from python
 * colorama win
 * weakset
 * _is_utf(encoding)
 * _is_ascii(s)
 * _supports_unicode(file)
 * _environ_cols()
 * _sh(const char *cmd[], ...)
 */

namespace tqdm {

template <typename _Iterator>
/**
Wrapper for pointers and std container iterators.
@author Casper da Costa-Luis
*/
class MyIteratorWrapper
    : public std::iterator<
          std::forward_iterator_tag,
          typename std::iterator_traits<_Iterator>::value_type> {
  mutable _Iterator p;  // TODO: remove this mutable

public:
  // already done by std::iterator
  typedef typename std::iterator_traits<_Iterator>::value_type value_type;

  explicit MyIteratorWrapper(_Iterator x) : p(x) {}
  // default construct gives end
  MyIteratorWrapper() : p(nullptr) {}
  explicit MyIteratorWrapper(const MyIteratorWrapper &mit) : p(mit.p) {}

  // override this in Tqdm class
  virtual void _incr() { ++p; }
  // override this in Tqdm class
  virtual void _incr() const { ++p; }

  MyIteratorWrapper &operator++() {
    // assert(this->bool() && "Out-of-bounds iterator increment");
    _incr();
    return *this;
  }
  const MyIteratorWrapper &operator++() const {
    _incr();
    return *this;
  }
  MyIteratorWrapper operator++(int)const {
    MyIteratorWrapper tmp(*this);
    _incr();
    return MyIteratorWrapper{tmp};
  }
  template <class Other>
  // two-way comparison: v.begin() == v.cbegin() and vice versa
  bool operator==(const MyIteratorWrapper<Other> &rhs) const {
    return p == rhs.p;
  }
  template <class Other>
  bool operator!=(const MyIteratorWrapper<Other> &rhs) const {
    return p != rhs.p;
  }
  template <class Other>
  size_t operator-(const MyIteratorWrapper<Other> &rhs) {
    return p - rhs.p;
  }
  // template <typename = typename std::enable_if<
  //               !std::is_const<value_type>::value>::type>
  value_type &operator*() {
    // assert(this->bool() && "Invalid iterator dereference!");
    return *p;
  }
  const value_type &operator*() const {
    // assert(this->bool() && "Invalid iterator dereference!");
    return *p;
  }
  // template <typename = typename std::enable_if<
  //               !std::is_const<value_type>::value>::type>
  value_type &operator->() {
    // assert(this->bool() && "Invalid iterator dereference!");
    return *p;
  }
  const value_type &operator->() const {
    // assert(this->bool() && "Invalid iterator dereference!");
    return *p;
  }
  // @return the underlying iterator
  _Iterator &get() { return p; }
  const _Iterator &get() const { return p; }
  // TODO: const _Iterator &get() const { return p; }, etc ...
  //
  void swap(MyIteratorWrapper &other) noexcept { std::swap(p, other.p); }

  // One way conversion: iterator -> const_iterator
  // template <typename =
  //               typename
  //               std::enable_if<!std::is_const<_Iterator>::value>::type>
  // operator MyIteratorWrapper<typename std::add_const<_Iterator>::type>()
  // const {
  //   return MyIteratorWrapper<const _Iterator>(p);
  // }
  template <typename = typename std::is_pointer<_Iterator>>
  explicit operator bool() const {
    return p != nullptr;
  }
};

template <typename _Iterator,
          typename _MyIteratorWrapper = MyIteratorWrapper<_Iterator>>
_MyIteratorWrapper myIteratorWrapper(_Iterator x) {
  return _MyIteratorWrapper(x);
}

template <typename IntType = int>
class RangeIterator
    : public std::iterator<std::forward_iterator_tag, IntType> {
private:
  mutable IntType current;
  IntType total;
  IntType step;

public:
  RangeIterator(IntType total) : current(0), total(total), step(1) {}
  RangeIterator(IntType start, IntType total)
      : current(start), total(total), step(1) {}
  RangeIterator(IntType start, IntType total, IntType step)
      : current(start), total(total), step(step) {}
  IntType &operator*() { return current; }
  const IntType &operator*() const { return current; }
  RangeIterator &operator++() {
    current += step;
    return *this;
  }
  const RangeIterator &operator++() const {
    current += step;
    return *this;
  }
  RangeIterator operator++(int)const {
    RangeIterator tmp(*this);
    operator++();
    return tmp;
  }
  explicit operator bool() const { return current < total; }
  auto size_remaining() const { return (total - current) / step; }

  /** here be dragons */

  // only use as (it != end), not as (end != it)
  bool operator!=(const RangeIterator &) const { return current < total; }
  bool operator==(const RangeIterator &) const { return current >= total; }
  auto operator-(const RangeIterator &it) const {
    // it's used in `end - begin`, but `end` is only a sentinel
    // so let's use `begin `to be consistent
    return it.size_remaining();
  }
};

const char *_term_move_up() {
  return
#if defined(IS_WIN) && !defined(colorama)
      ""
#else
      "\x1b[A"
#endif
      ;
}

static void wait_for_write(int fd) {
  struct pollfd pfd;
  pfd.fd = fd;
  pfd.events = POLLOUT;
  (void)::poll(&pfd, 1, -1);
}

// Write a buffer fully or not at all.
// If false is returned, caller may check errno to see if it's EAGAIN
// or a real error.
bool write_harder(int fd, const char *buf, size_t len) {
  bool did_anything = false;

  while (len) {
    auto res = ::write(fd, buf, static_cast<unsigned>(len));
    if (res == -1) {
      if (errno == EAGAIN) {
        if (!did_anything) {
          return false;
        }
        wait_for_write(fd);
        continue;
      }
      return false;
    }
    assert(res != 0);
    did_anything = true;
    buf += res;
    len -= res;
  }
  return true;
}

class AbstractLine;

template <class Node> class AtomicList;

// CRTP
template <class Node> class AtomicNode {
  friend class AtomicList<Node>;

  std::atomic<Node *> intrusive_link_next;
  std::atomic<Node *> intrusive_link_prev;

  AtomicNode(Node *next, Node *prev);

public:
  // Node is initially unattached
  AtomicNode();
  ~AtomicNode();
};

// A non-owning intrusive linked list,
// using atomics to ensure thread- and signal- safety.
template <class Node> class AtomicList {
  AtomicNode<Node> meta;

public:
  AtomicList();
  ~AtomicList();

  void append(Node *node);
};

template <class Node> AtomicNode<Node>::AtomicNode(Node *next, Node *prev) {
  intrusive_link_next.store(next);
  intrusive_link_prev.store(prev);
}
template <class Node> AtomicNode<Node>::AtomicNode() {
  intrusive_link_next.store(nullptr);
  intrusive_link_prev.store(nullptr);
}
template <class Node> AtomicNode<Node>::~AtomicNode() {}

class AbstractLine : public AtomicNode<AbstractLine> {
  friend class Sink;

  struct {
    bool dirty : 1;
  } flags;

public:
  AbstractLine() : flags{} {}
  // Due to how vtables work, it is cheaper to *not* inline this.
  virtual ~AbstractLine(){};

  virtual void write(int fd) = 0;

protected:
  void not_dirty() { this->flags.dirty = false; }
};

class StaticTextLine : public AbstractLine {
  const char *text;

public:
  template <size_t n> StaticTextLine(const char (&lit)[n]) : text(lit) {}
  void write(int fd) override {
    bool ok = write_harder(fd, this->text, strlen(this->text));
    if (ok)
      this->not_dirty();
  }
};

struct SinkOptions {
  // Only mandatory field. Everything else can just be zeroed.
  int fd;

  int tty_width;
  int tty_height;

  // Additional options will be added in future.
  SinkOptions(int fd) : fd(fd){};
};

class Sink;
// We do still need a global list of sinks in order to handle signals.
// This is still a win over making a single global list of AbstractLine
// instances, since we can skip entirely any Sink which does not express
// interest in asynchronous updates.
static AtomicList<Sink> all_sinks;

class Sink : public AtomicNode<Sink> {
  SinkOptions opts;
  AtomicList<AbstractLine> lines;

public:
  explicit Sink(SinkOptions o) : opts(o) { all_sinks.append(this); }
  Sink(Sink &&) = delete;
  Sink &operator=(Sink &&) = delete;
};

Sink standard_sink(SinkOptions(STDERR_FILENO));

// static void wait_for_write(int fd);

// Write a buffer fully or not at all.
// If false is returned, caller may check errno to see if it's EAGAIN
// or a real error.
bool write_harder(int fd, const char *buf, size_t len);

// To more easily maintain the doubly-linked structure, loop to itself
// rather than using NULL pointers.
template <class Node>
AtomicList<Node>::AtomicList()
    : meta(static_cast<Node *>(&meta), static_cast<Node *>(&meta)) {}

// Nothing to do - we didn't allocate any objects, merely borrow.
template <class Node> AtomicList<Node>::~AtomicList() {
  // TODO: We *really* shouldn't get here with a non-empty node set.
  // Should we set all nodes to NULL to indicate they have?
  // Otherwise we're stuck with dangling pointers in the edges ...
}

template <class Node> void AtomicList<Node>::append(Node *node) {
  (void)node;
#if 0
  Node *singular = &meta;
  // TODO when deletion is added, need to disable that
  // for the duration of this function (using a spinlock).
  // But, if the spinlock is currently held by the main thread,
  // and we are a signal handler, we need to advance anyway.
  // I think our spinlocks need to be recursive, which means tracking
  // the thread ID.
  //
  // Actually, we might not need to disable it, just make sure it
  // always points to a later node, perhaps? But what if there
  // is no later node? Maybe use the list-itself-is-a-node trick?
  assert (node->intrusive_link_next.load() == nullptr);
  assert (node->intrusive_link_prev.load() == nullptr);
  // Note that tail is a pointer to a (usually) NULL pointer.
  std::atomic<Node *> *tail = this->approx_tail;
  assert (tail != nullptr);
  while (true)
  {
      // The tail may have moved, if someone else is also appending.
      while (Node *tmp = tail->load())
      {
          tail = &tmp->intrusive_link_next;
      }
      // First argument is a reference, but we can't re-use
      // the new value, because we want to advance.
      Node *expected = nullptr;
      if (tail->compare_exchange_weak(expected, node))
      {
          break;
      }
  }
  // If we're wrong, nobody cares until the next append,
  // which will fix this anyway.
  this->approx_tail = &node->intrusive_link_next;
#endif
}

}  // tqdm

// ------- END OF tqdm/utils.h

// ------------------------------ BEGINNING of https://github.com/tqdm/tqdm.cpp/blob/master/include/tqdm/tqdm.h --------------------------------------

/**
Customisable progressbar decorator for iterators.
Includes a default range iterator printing to stderr.
TODO:
* handle s(tep) with operator+/-(=)
* chrono and delay printing
* class status printer
* iterator-less: fake range iterable, update() increments value
Usage:
  # include "tqdm/tqdm.h"
  for(int i : tqdm::range(4))
  // same as:
  //   for (int i : tqdm::tqdm({0, 1, 2, 3}))
  // or:
  //   std::vector<int> v{0, 1, 2, 3};
  //   for (int &i : tqdm::tqdm(v.begin(), v.end())
    ...
@author Casper dC-L <github.com/casperdcl>
*/

#ifndef SIZE_T_MAX
constexpr size_t SIZE_T_MAX = std::numeric_limits<size_t>::max();
#endif

namespace tqdm {

struct Params {
  std::string desc;
  size_t total = -1;
  bool leave = true;
  FILE *f = stderr;
  int ncols = -1;
  float mininterval = 0.1f, maxinterval = 10.0f;
  unsigned miniters = -1;
  std::string ascii = " 123456789#";
  bool disable = false;
  std::string unit = "it";
  bool unit_scale = false;
  bool dynamic_ncols = false;
  float smoothing = 0.3f;
  std::string bar_format;
  size_t initial = 0;
  int position = -1;
  bool gui = false;
};

template <typename _Iterator>
class Tqdm : public MyIteratorWrapper<_Iterator> {
private:
  using TQDM_IT = MyIteratorWrapper<_Iterator>;
  _Iterator e;  // end
  Params self;  // ha, ha

public:
  /**
   containter-like methods
   */
  // actually current value
  // virtual _Iterator begin() { return this->get(); }
  Tqdm &begin() { return *this; }
  const Tqdm &begin() const { return *this; }
  // virtual _Iterator end() { return e; }
  Tqdm end() const { return Tqdm(e, e); }

  explicit operator _Iterator() { return this->get(); }

  /** constructors
   */
  explicit Tqdm(_Iterator begin, _Iterator end)
      : TQDM_IT(begin), e(end), self() {
    self.total = size_t(end - begin);
  }

  explicit Tqdm(_Iterator begin, size_t total)
      : TQDM_IT(begin), e(begin + total), self() {
    self.total = total;
  }

  // Tqdm(const Tqdm& other)
  //     : TQDM_IT(other.get()),
  //       e(other.end().get()),
  //       self(other.self),
  // {
  //   // std::memcpy(this, &other, sizeof(Tqdm));
  // }

  template <typename _Container,
            typename = typename std::enable_if<
                !std::is_same<_Container, Tqdm>::value>::type>
  Tqdm(_Container &v) : TQDM_IT(std::begin(v)), e(std::end(v)), self() {
    self.total = e - this->get();
  }

  explicit operator bool() const { return this->get() != e; }

  /** TODO: magic methods */
  virtual void _incr() const override {
    if (this->get() == e)
      throw std::out_of_range(
          "exhausted");  // TODO: don't throw, just double total

    TQDM_IT::_incr();
    if (this->get() == e) {
      printf("\nfinished: %" PRIu64 "/%" PRIu64 "\n",
        static_cast<std::uint64_t>(self.total),
        static_cast<std::uint64_t>(self.total));
    } else
      printf("\r%" PRIi64 " left", (int64_t)(e - this->get()));
  }
  virtual void _incr() override { ((Tqdm const &)*this)._incr(); }
};

template <typename _Iterator, typename _Tqdm = Tqdm<_Iterator>>
_Tqdm tqdm(_Iterator begin, _Iterator end) {
  return _Tqdm(begin, end);
}

template <typename _Iterator, typename _Tqdm = Tqdm<_Iterator>>
_Tqdm tqdm(_Iterator begin, size_t total) {
  return _Tqdm(begin, total);
}

template <typename _Container,
          typename _Tqdm = Tqdm<typename _Container::iterator>>
_Tqdm tqdm(_Container &v) {
  return _Tqdm(v);
}

template <size_t N, typename T, typename _Tqdm = Tqdm<T *>>
_Tqdm tqdm(T (&tab)[N]) {
  return _Tqdm(tab, N);
}

template <typename SizeType = int>
using RangeTqdm = Tqdm<RangeIterator<SizeType>>;
template <typename SizeType> RangeTqdm<SizeType> range(SizeType n) {
  return RangeTqdm<SizeType>(RangeIterator<SizeType>(n),
                             RangeIterator<SizeType>(n));
}
template <typename SizeType>
RangeTqdm<SizeType> range(SizeType start, SizeType end) {
  return RangeTqdm<SizeType>(RangeIterator<SizeType>(start, end),
                             RangeIterator<SizeType>(start, end));
}
template <typename SizeType>
RangeTqdm<SizeType> range(SizeType start, SizeType end, SizeType step) {
  return RangeTqdm<SizeType>(RangeIterator<SizeType>(start, end, step),
                             RangeIterator<SizeType>(start, end, step));
}

}  // tqdm

/** Things to port:
class TqdmTypeError(TypeError):
class TqdmKeyError(KeyError):
class TqdmDeprecationWarning(Exception):
ASCII_FMT = " 123456789#"
UTF_FMT = u" " + u''.join(map(_unich, range(0x258F, 0x2587, -1)))
class tqdm(object):
    @staticmethod
    def format_sizeof(num, suffix=''):
    @staticmethod
    def format_interval(t):
    @staticmethod
    def status_printer(file):
    @staticmethod
    def format_meter(n, total, elapsed, ncols=None, prefix='',
                     ascii=False, unit='it', unit_scale=False, rate=None,
                     bar_format=None):
    def __new__(cls, *args, **kwargs):
    @classmethod
    def _get_free_pos(cls, instance=None):
    @classmethod
    def _decr_instances(cls, instance):
    @classmethod
    def write(cls, s, file=sys.stdout, end="\n"):
    @classmethod
    def pandas(tclass, *targs, **tkwargs):
    def __init__(self, iterable=None, desc=None, total=None, leave=True,
                 file=sys.stderr, ncols=None, mininterval=0.1,
                 maxinterval=10.0, miniters=None, ascii=None, disable=False,
                 unit='it', unit_scale=False, dynamic_ncols=False,
                 smoothing=0.3, bar_format=None, initial=0, position=None,
                 gui=False, **kwargs):
        """
        Parameters
        ----------
        iterable  : iterable, optional
            Iterable to decorate with a progressbar.
            Leave blank to manually manage the updates.
        desc  : str, optional
            Prefix for the progressbar.
        total  : int, optional
            The number of expected iterations. If unspecified,
            len(iterable) is used if possible. As a last resort, only basic
            progress statistics are displayed (no ETA, no progressbar).
            If `gui` is True and this parameter needs subsequent updating,
            specify an initial arbitrary large positive integer,
            e.g. int(9e9).
        leave  : bool, optional
            If [default: True], keeps all traces of the progressbar
            upon termination of iteration.
        file  : `io.TextIOWrapper` or `io.StringIO`, optional
            Specifies where to output the progress messages
            [default: sys.stderr]. Uses `file.write(str)` and `file.flush()`
            methods.
        ncols  : int, optional
            The width of the entire output message. If specified,
            dynamically resizes the progressbar to stay within this bound.
            If unspecified, attempts to use environment width. The
            fallback is a meter width of 10 and no limit for the counter and
            statistics. If 0, will not print any meter (only stats).
        mininterval  : float, optional
            Minimum progress update interval, in seconds [default: 0.1].
        maxinterval  : float, optional
            Maximum progress update interval, in seconds [default: 10.0].
        miniters  : int, optional
            Minimum progress update interval, in iterations.
            If specified, will set `mininterval` to 0.
        ascii  : bool or str, optional
            If unspecified or False, use unicode (smooth blocks) to fill
            the meter.
            The fallback is to use ASCII characters " 123456789#".
        disable  : bool, optional
            Whether to disable the entire progressbar wrapper
            [default: False].
        unit  : str, optional
            String that will be used to define the unit of each iteration
            [default: it].
        unit_scale  : bool, optional
            If set, the number of iterations will be reduced/scaled
            automatically and a metric prefix following the
            International System of Units standard will be added
            (kilo, mega, etc.) [default: False].
        dynamic_ncols  : bool, optional
            If set, constantly alters `ncols` to the environment (allowing
            for window resizes) [default: False].
        smoothing  : float, optional
            Exponential moving average smoothing factor for speed estimates
            (ignored in GUI mode). Ranges from 0 (average speed) to 1
            (current/instantaneous speed) [default: 0.3].
        bar_format  : str, optional
            Specify a custom bar string formatting. May impact performance.
            If unspecified, will use '{l_bar}{bar}{r_bar}', where l_bar is
            '{desc}{percentage:3.0f}%|' and r_bar is
            '| {n_fmt}/{total_fmt} [{elapsed_str}<{remaining_str},
{rate_fmt}]'
            Possible vars: bar, n, n_fmt, total, total_fmt, percentage,
            rate, rate_fmt, elapsed, remaining, l_bar, r_bar, desc.
        initial  : int, optional
            The initial counter value. Useful when restarting a progress
            bar [default: 0].
        position  : int, optional
            Specify the line offset to print this bar (starting from 0)
            Automatic if unspecified.
            Useful to manage multiple bars at once (eg, from threads).
        gui  : bool, optional
            WARNING: internal parameter - do not use.
            Use tqdm_gui(...) instead. If set, will attempt to use
            matplotlib animations for a graphical output [default: False].
        Returns
        -------
        out  : decorated iterator.
        """
        if disable:
            self.iterable = iterable
            self.disable = disable
            self.pos = self._get_free_pos(self)
            self._instances.remove(self)
            return
        if kwargs:
            self.disable = True
            self.pos = self._get_free_pos(self)
            self._instances.remove(self)
            raise (TqdmDeprecationWarning("""\
`nested` is deprecated and automated. Use position instead for manual control.
""", fp_write=getattr(file, 'write', sys.stderr.write))
                if "nested" in kwargs else
                TqdmKeyError("Unknown argument(s): " + str(kwargs)))
        # Preprocess the arguments
        if total is None and iterable is not None:
            try:
                total = len(iterable)
            except (TypeError, AttributeError):
                total = None
        if ((ncols is None) and (file in (sys.stderr, sys.stdout))) or \
                dynamic_ncols:  # pragma: no cover
            if dynamic_ncols:
                dynamic_ncols = _environ_cols_wrapper()
                ncols = dynamic_ncols(file)
            else:
                ncols = _environ_cols_wrapper()(file)
        if miniters is None:
            miniters = 0
            dynamic_miniters = True
        else:
            dynamic_miniters = False
        if mininterval is None:
            mininterval = 0
        if maxinterval is None:
            maxinterval = 0
        if ascii is None:
            ascii = not _supports_unicode(file)
        if bar_format and not ((ascii is True) or _is_ascii(ascii)):
            # Convert bar format into unicode since terminal uses unicode
            bar_format = _unicode(bar_format)
        if smoothing is None:
            smoothing = 0
        # Store the arguments
        self.iterable = iterable
        self.desc = desc + ': ' if desc else ''
        self.total = total
        self.leave = leave
        self.fp = file
        self.ncols = ncols
        self.mininterval = mininterval
        self.maxinterval = maxinterval
        self.miniters = miniters
        self.dynamic_miniters = dynamic_miniters
        self.ascii = ascii
        self.disable = disable
        self.unit = unit
        self.unit_scale = unit_scale
        self.gui = gui
        self.dynamic_ncols = dynamic_ncols
        self.smoothing = smoothing
        self.avg_time = None
        self._time = time
        self.bar_format = bar_format
        # Init the iterations counters
        self.last_print_n = initial
        self.n = initial
        # if nested, at initial sp() call we replace '\r' by '\n' to
        # not overwrite the outer progress bar
        self.pos = self._get_free_pos(self) if position is None else position
        if not gui:
            # Initialize the screen printer
            self.sp = self.status_printer(self.fp)
            if self.pos:
                self.moveto(self.pos)
            self.sp(self.format_meter(self.n, total, 0,
                    (dynamic_ncols(file) if dynamic_ncols else ncols),
                    self.desc, ascii, unit, unit_scale, None, bar_format))
            if self.pos:
                self.moveto(-self.pos)
        # Init the time counter
        self.start_t = self.last_print_t = self._time()
    def __len__(self):
    def __enter__(self):
    def __exit__(self, *exc):
    def __del__(self):
    def __repr__(self):
    def __lt__(self, other):
    def __le__(self, other):
    def __eq__(self, other):
    def __ne__(self, other):
    def __gt__(self, other):
    def __ge__(self, other):
    def __hash__(self):
    def __iter__(self):
    def update(self, n=1):
        """
        Manually update the progress bar, useful for streams
        such as reading files.
        E.g.:
        >>> t = tqdm(total=filesize) # Initialise
        >>> for current_buffer in stream:
        ...    ...
        ...    t.update(len(current_buffer))
        >>> t.close()
        The last line is highly recommended, but possibly not necessary if
        `t.update()` will be called in such a way that `filesize` will be
        exactly reached and printed.
        Parameters
        ----------
        n  : int
            Increment to add to the internal counter of iterations
            [default: 1].
        """
        if self.disable:
            return
        if n < 0:
            raise ValueError("n ({0}) cannot be negative".format(n))
        self.n += n
        delta_it = self.n - self.last_print_n  # should be n?
        if delta_it >= self.miniters:
            # We check the counter first, to reduce the overhead of time()
            cur_t = self._time()
            delta_t = cur_t - self.last_print_t
            if delta_t >= self.mininterval:
                elapsed = cur_t - self.start_t
                # EMA (not just overall average)
                if self.smoothing and delta_t:
                    self.avg_time = delta_t / delta_it \
                        if self.avg_time is None \
                        else self.smoothing * delta_t / delta_it + \
                        (1 - self.smoothing) * self.avg_time
                if not hasattr(self, "sp"):
                    raise TqdmDeprecationWarning("""\
Please use `tqdm_gui(...)` instead of `tqdm(..., gui=True)`
""", fp_write=getattr(self.fp, 'write', sys.stderr.write))
                if self.pos:
                    self.moveto(self.pos)
                # Print bar's update
                self.sp(self.format_meter(
                    self.n, self.total, elapsed,
                    (self.dynamic_ncols(self.fp) if self.dynamic_ncols
                     else self.ncols),
                    self.desc, self.ascii, self.unit, self.unit_scale,
                    1 / self.avg_time if self.avg_time else None,
                    self.bar_format))
                if self.pos:
                    self.moveto(-self.pos)
                # If no `miniters` was specified, adjust automatically to the
                # maximum iteration rate seen so far.
                # e.g.: After running `tqdm.update(5)`, subsequent
                # calls to `tqdm.update()` will only cause an update after
                # at least 5 more iterations.
                if self.dynamic_miniters:
                    if self.maxinterval and delta_t > self.maxinterval:
                        self.miniters = self.miniters * self.maxinterval \
                            / delta_t
                    elif self.mininterval and delta_t:
                        self.miniters = self.smoothing * delta_it \
                            * self.mininterval / delta_t + \
                            (1 - self.smoothing) * self.miniters
                    else:
                        self.miniters = self.smoothing * delta_it + \
                            (1 - self.smoothing) * self.miniters
                # Store old values for next call
                self.last_print_n = self.n
                self.last_print_t = cur_t
    def close(self):
    def unpause(self):
    def set_description(self, desc=None):
    def moveto(self, n):
    def clear(self, nomove=False):
    def refresh(self):
*/

#endif // !ADHD_TQDM_H

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants