GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/options/managed_streams.h Lines: 12 18 66.7 %
Date: 2021-09-29 Branches: 1 8 12.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Gereon Kremer
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Wrappers to handle memory management of streams.
14
 *
15
 * This file contains wrappers to handle special cases of managing memory
16
 * related to streams stored in options.
17
 */
18
19
#include "cvc5_public.h"
20
21
#ifndef CVC5__OPTIONS__MANAGED_STREAMS_H
22
#define CVC5__OPTIONS__MANAGED_STREAMS_H
23
24
#include <memory>
25
#include <ostream>
26
27
namespace cvc5 {
28
29
namespace detail {
30
/*
31
 * Open a file as an output stream and return it as a pointer. The caller
32
 * assumes the ownership of the returned pointer.
33
 */
34
std::ostream* openOStream(const std::string& filename);
35
/*
36
 * Open a file as an input stream and return it as a pointer. The caller
37
 * assumes the ownership of the returned pointer.
38
 */
39
std::istream* openIStream(const std::string& filename);
40
}  // namespace detail
41
42
/**
43
 * Implements memory management for streams, both input and output. It is
44
 * intended to be subclassed, where a subclass can provide a default value and
45
 * special cases. Usually, users should use one of these subclasses.
46
 * The template argument type should be either std::istream or std::ostream,
47
 * indicating whether the type wraps an input or output stream.
48
 */
49
template <typename Stream>
50
55028
class ManagedStream
51
{
52
 public:
53
72348
  ManagedStream() {}
54
51172
  virtual ~ManagedStream() {}
55
56
  /**
57
   * Open the stream from the given value. First check the special cases and
58
   * then fall back to using `std::ofstream` or `std::ifstream`.
59
   */
60
  void open(const std::string& value)
61
  {
62
    if (specialCases(value)) return;
63
    if constexpr (std::is_same<Stream, std::ostream>::value)
64
    {
65
      d_stream.reset(detail::openOStream(value));
66
    }
67
    else if constexpr (std::is_same<Stream, std::istream>::value)
68
    {
69
      d_stream.reset(detail::openIStream(value));
70
    }
71
  }
72
73
225485
  Stream& operator*() const { return *getPtr(); }
74
  Stream* operator->() const { return getPtr(); }
75
3911
  operator Stream&() const { return *getPtr(); }
76
6
  operator Stream*() const { return getPtr(); }
77
78
 protected:
79
  std::shared_ptr<Stream> d_stream;
80
81
 private:
82
  /** Returns the value to be used if d_stream is not set. */
83
  virtual Stream* defaultValue() const = 0;
84
  /**
85
   * Check if there is a special case for this value. If so, the implementation
86
   * should set d_stream appropriately and return true to skip the default
87
   * methods for opening a stream.
88
   */
89
  virtual bool specialCases(const std::string& value) = 0;
90
91
  /** Return the pointer, either from d_stream of from defaultValue(). */
92
229402
  Stream* getPtr() const
93
  {
94
229402
    if (d_stream) return d_stream.get();
95
229402
    return defaultValue();
96
  }
97
};
98
99
template <typename Stream>
100
std::ostream& operator<<(std::ostream& os, const ManagedStream<Stream>& ms)
101
{
102
  return os << "ManagedStream";
103
}
104
105
/**
106
 * Managed error output. It recognizes "stderr" and "--" as special valued for
107
 * std::cerr.
108
 */
109
44637
class ManagedErr : public ManagedStream<std::ostream>
110
{
111
  std::ostream* defaultValue() const override final;
112
  bool specialCases(const std::string& value) override final;
113
};
114
115
/**
116
 * Managed standard input. It recognizes "stdin" and "--" as special valued for
117
 * std::cin.
118
 */
119
44637
class ManagedIn : public ManagedStream<std::istream>
120
{
121
  std::istream* defaultValue() const override final;
122
  bool specialCases(const std::string& value) override final;
123
};
124
125
/**
126
 * Managed standard output. It recognizes "stdout" and "--" as special valued
127
 * for std::cout.
128
 */
129
89274
class ManagedOut : public ManagedStream<std::ostream>
130
{
131
  std::ostream* defaultValue() const override final;
132
  bool specialCases(const std::string& value) override final;
133
};
134
135
}  // namespace cvc5
136
137
#endif /* CVC5__OPTIONS__MANAGED_STREAMS_H */