# Closable

## Description

A Closable Filter or Device receives notifications before a stream or stream buffer which contains it is closed.

#### Motivation

The C++ standard library does not recognize the notion of an arbitrary stream or stream buffer being open or closed. For the Iostreams library, however, the notion of opening and closing streams and stream buffers is important. Some Filters and Devices have special behavior reserved for the end of a stream — e.g., an OutputFilter might conclude each sequence of data with a newline character. Other Filters or Devices maintain state during a sequence of i/o operations which must be reset before the Filter or Device can be reused. Such Filters and Devices need to be notified before a stream is closed, and should model Closable.

#### Closure Notifications

The Iostreams library sends closure notifications by invoking the function `close`. For most Closable Filter or Device, `close` delegates to a member function `close`; for non-Closable Devices, `close` calls `flush`. The details regarding when and how `close` is invoked are complicated. However, defining a Filter or Device which receives closure notifications is easy, as illustrated in the following sections.

#### Single-Sequence Devices

If a Device controls a single sequence of characters, it can be made Closable simply by specifying a category tag which is convertible to `closable_tag` and by adding a member function `close`, like so:

        void close() {  /* process closure notification */  }

Filters and Devices which derive from the convenience templates and `typedef`s have category tags convertible to `closable_tag` provided automatically.

#### Single-Sequence Filters

For Filters controlling a single sequence, the signature of `close` is:

        template<typename Device>
        void close(Device&);

#### Two-Sequence Devices

If a Device controls separate input and output sequences, the signature of `close` is:

        void close(std::ios_base::openmode);

This function will be called twice: first with argument `std::ios_base::in`, to signal the closing of the input sequence, and later with argument `std::ios_base::out`, to signal the closing of the output sequence.

#### Two-Sequence Filters

If a Filter controls separate input and output sequences, the signature of `close` is:

        template<typename Device>
        void close(Device&, std::ios_base::openmode);

This function will be called twice: first with argument `std::ios_base::in`, to signal the closing of the input sequence, and later with argument `std::ios_base::out`, to signal the closing of the output sequence.

#### Dual-Use Filters

The signature of `close` for DualUserFilters is the same as that for two-sequence Filters:

        template<typename Device>
        void close(Device&, std::ios_base::openmode);

This function will be called only once, depending on whether the filter is being used for input or output.

## Refinement of

## Associated Types

Character type | The type of the characters in the associated sequence
Category | A category tag convertible to `closable_tag`

## Notation

`C` | - | A type which is a model of Closable
`D` | - | A type which is a model of Blocking, with the same character type as `C` and with mode refining the mode of `C`
`c` | - | Object of type `C`
`d` | - | Object of type `D`
`w` | - | Object of type `std::ios_base::openmode`, equal to `std::ios_base::in` or `std::ios_base::out`

## Valid Expressions / Semantics

Same as Filter or Device, with the following additional requirements:

Expression | Expression Type | Precondition | Semantics | Postcondition
--- | --- | --- | --- | ---
    boost::iostreams::close(c, w)
| `void` | Category convertible to `device_tag` | If `w` is `std::ios_base::out`, writes zero or more characters to the output sequence | `c` is ready to begin processing a new character sequence
    boost::iostreams::close(c, d, w)
| `void` | Category convertible to `filter_tag` | If `w` is `std::ios_base::out`, writes zero or more characters to `d` using `boost::iostreams::put` and `boost::iostreams::write` | `c` is ready to begin processing a new character sequence

## Exceptions

Errors which occur during the execution of `close` are be indicated by throwing exceptions. Such exceptions are caught and ignored if they occur during the execution of stream or stream buffer destructor.

## Models

- Generic Streams and Stream Buffers.
- Filtering Streams and Stream Buffers.
- Standard file streams and stream buffers.

Revised 02 Feb 2008

© Copyright 2008 CodeRage, LLC
© Copyright 2004-2007 Jonathan Turkanis

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)