GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/options/managed_streams.h Lines: 12 18 66.7 %
Date: 2021-09-07 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
#include "options/options_public.h"
28
29
namespace cvc5 {
30
31
namespace detail {
32
/*
33
 * Open a file as an output stream and return it as a pointer. The caller
34
 * assumes the ownership of the returned pointer.
35
 */
36
std::ostream* openOStream(const std::string& filename);
37
/*
38
 * Open a file as an input stream and return it as a pointer. The caller
39
 * assumes the ownership of the returned pointer.
40
 */
41
std::istream* openIStream(const std::string& filename);
42
}  // namespace detail
43
44
/**
45
 * Implements memory management for streams, both input and output. It is
46
 * intended to be subclassed, where a subclass can provide a default value and
47
 * special cases. Usually, users should use one of these subclasses.
48
 * The template argument type should be either std::istream or std::ostream,
49
 * indicating whether the type wraps an input or output stream.
50
 */
51
template <typename Stream>
52
78824
class ManagedStream
53
{
54
 public:
55
96136
  ManagedStream() {}
56
75008
  virtual ~ManagedStream() {}
57
58
  /**
59
   * Open the stream from the given value. First check the special cases and
60
   * then fall back to using `std::ofstream` or `std::ifstream`.
61
   */
62
  void open(const std::string& value)
63
  {
64
    if (specialCases(value)) return;
65
    if constexpr (std::is_same<Stream, std::ostream>::value)
66
    {
67
      d_stream.reset(detail::openOStream(value));
68
    }
69
    else if constexpr (std::is_same<Stream, std::istream>::value)
70
    {
71
      d_stream.reset(detail::openIStream(value));
72
    }
73
  }
74
75
318035
  Stream& operator*() const { return *getPtr(); }
76
  Stream* operator->() const { return getPtr(); }
77
6184
  operator Stream&() const { return *getPtr(); }
78
6
  operator Stream*() const { return getPtr(); }
79
80
 protected:
81
  std::shared_ptr<Stream> d_stream;
82
83
 private:
84
  /** Returns the value to be used if d_stream is not set. */
85
  virtual Stream* defaultValue() const = 0;
86
  /**
87
   * Check if there is a special case for this value. If so, the implementation
88
   * should set d_stream appropriately and return true to skip the default
89
   * methods for opening a stream.
90
   */
91
  virtual bool specialCases(const std::string& value) = 0;
92
93
  /** Return the pointer, either from d_stream of from defaultValue(). */
94
324225
  Stream* getPtr() const
95
  {
96
324225
    if (d_stream) return d_stream.get();
97
324225
    return defaultValue();
98
  }
99
};
100
101
template <typename Stream>
102
std::ostream& operator<<(std::ostream& os, const ManagedStream<Stream>& ms)
103
{
104
  return os << "ManagedStream";
105
}
106
107
/**
108
 * Managed error output. It recognizes "stderr" and "--" as special valued for
109
 * std::cerr.
110
 */
111
62492
class ManagedErr : public ManagedStream<std::ostream>
112
{
113
  std::ostream* defaultValue() const override final;
114
  bool specialCases(const std::string& value) override final;
115
};
116
117
/**
118
 * Managed standard input. It recognizes "stdin" and "--" as special valued for
119
 * std::cin.
120
 */
121
62492
class ManagedIn : public ManagedStream<std::istream>
122
{
123
  std::istream* defaultValue() const override final;
124
  bool specialCases(const std::string& value) override final;
125
};
126
127
/**
128
 * Managed standard output. It recognizes "stdout" and "--" as special valued
129
 * for std::cout.
130
 */
131
124984
class ManagedOut : public ManagedStream<std::ostream>
132
{
133
  std::ostream* defaultValue() const override final;
134
  bool specialCases(const std::string& value) override final;
135
};
136
137
}  // namespace cvc5
138
139
#endif /* CVC5__OPTIONS__MANAGED_STREAMS_H */