Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
#ifndef GENERS_REGEX_HH_
#define GENERS_REGEX_HH_

#include "Alignment/Geners/interface/CPP11_config.hh"

#ifdef CPP11_STD_AVAILABLE

// Use C++11 regex matching

#include <regex>

namespace gs {
  typedef std::regex Regex;
}

#else  // CPP11_STD_AVAILABLE

// Use POSIX extended regex matching

#include "Alignment/Geners/interface/IOException.hh"
#include <cassert>
#include <regex.h>
#include <string>
#include <sys/types.h>

namespace gs {
  class SearchSpecifier;

  class Regex {
    friend class SearchSpecifier;

    std::string re_;
    mutable regex_t *preg_;

    inline void cleanup() {
      if (preg_) {
        regfree(preg_);
        delete preg_;
        preg_ = 0;
      }
    }

    inline bool matches(const std::string &sentence) const {
      if (!preg_) {
        preg_ = new regex_t();
        assert(!regcomp(preg_, re_.c_str(), REG_EXTENDED | REG_NOSUB));
      }
      return regexec(preg_, sentence.c_str(), 0, 0, 0) == 0;
    }

  public:
    inline Regex() : preg_(0) {}

    inline Regex(const std::string &re) : re_(re), preg_(new regex_t()) {
      const int statusCode = regcomp(preg_, re_.c_str(), REG_EXTENDED | REG_NOSUB);
      if (statusCode) {
        const size_t n = regerror(statusCode, preg_, 0, 0);
        std::string s;
        s.resize(n + 1);
        regerror(statusCode, preg_, const_cast<char *>(s.data()), n + 1);
        cleanup();
        throw gs::IOInvalidArgument(s.data());
      }
    }

    inline Regex(const Regex &r) : re_(r.re_), preg_(0) {}

    inline Regex &operator=(const Regex &r) {
      if (&r == this)
        return *this;
      re_ = r.re_;
      cleanup();
      return *this;
    }

    inline ~Regex() { cleanup(); }
  };
}  // namespace gs

#endif  // CPP11_STD_AVAILABLE
#endif  // GENERS_REGEX_HH_