Nitrogen is a C++ interface to the Macintosh operating system, based on Apple's Carbon interface. It also serves as the exemplar of an economical approach to adapting C libraries to C++. This approach is described in detail in the founding document for Nitrogen, The Nitrogen Manifesto.
In brief, I feel that the common approach of designing C++ classes to express the object-oriented concepts underlying a C library is an approach doomed by its excessive ambition. A great deal of effort must go into designing, documenting, and understanding such a library. In effect, such a library reexamines the problem space of the original C library, and produces a new design suited to C++. Such redesign is expensive, particularly when one considers the cost of documenting the design and the cost to users of learning the new design. And if the C library continues to evolve, the design may need to be rethought.
In contrast, the Nitrogen approach focuses design effort on the difference between the C and C++ libraries. A set of rules expressing the difference are developed, and the C++ library parallels C library, separated uniformly by those rules. This rigid uniformity reduces the need for documentation. For the most part, the C++ library can rely on the documentation for the C library, coupled with meta-documentation: The rules relating the C library to the C++ library are documented, so a programmer who knows the C library can deduce the form of the C++ library.
For example, a fundamental rule in Nitrogen is name reuse: each Carbon function
name in the global namespace is reused in the Nitrogen namespace for the same purpose.
In Carbon, one may create a menu with CreateNewMenu; therefore one may
also create a menu with Nitrogen::CreateNewMenu. And both the signature
and the semantics of the Nitrogen function can be inferred from the signature and semantics
of the Carbon function:
OSStatus CreateNewMenu( MenuID inMenuID, MenuAttributes inMenuAttributes, MenuRef *outMenuRef );
Sets*outMenuRefto a newly created menu with the given ID and attributes. The usual value for the attributes is zero. The caller is responsible for disposing of the menu withDisposeMenu. On failure, returns a nonzero error code. Specifically documented error codes includeparamErrandmemFullErr.
namespace N = Nitrogen; N::Owned< N::MenuRef > N::CreateNewMenu( N::MenuID inMenuID, N::MenuAttributes inMenuAttributes = N::MenuAttributes() );
Returns a newly created menu with the given ID and attributes. The result typeN::Owned<N::MenuRef>is astd::auto_ptr-like type associated withDisposeMenu. On failure, exits with an exception. Noteworthy exceptions includeN::OSStatusand its subclassesN::ParamErrandN::MemFullErr.
This function illustrates several of the most common Nitrogen rules:
Nitrogen::Owned
or std::auto_ptr types to indicate transfer of ownership.Nitrogen::OSStatus represents all OSStatus errors.OSStatus value, there is a similarly-named subclass of
Nitrogen::OSStatus, with the same intent.