KeyValue
User's Manual - version: 0.1

KeyValue User's Manual

Cassio Neri


Table of Contents

1. Introduction
2. Download and install
2.1. Compiler
2.2. Build tools
2.3. Boost
2.4. Cygwin
2.5. OpenOffice SDK
2.6. Excel SDK
3. Configure and build
3.1. Using Microsoft Visual Studio 2008 IDE
4. Getting started with KeyValue
5. The KEYVALUE function
6. Key-value patterns
6.1. Key in single
6.2. Keys in vector
6.3. Keys in matrix
6.4. Table
7. Reserved keys
7.1. Processor
7.2. ProcessNow
7.3. VectorOutput
7.4. Imports
7.5. Export
8. Reserved processors
8.1. Logger
8.2. NumberOfDataSets
8.3. ListOfDataSets
8.4. DeleteDataSets
9. Key resolution and the Default data set
9.1. Importing a value from another key
9.2. Importing all key-value pairs from other data sets
9.3. Importing key-values from Default data set
10. Lexical conversions
11. Key mappings
11.1. Object map
11.2. Flag map
11.3. Partial map
11.4. No map
12. Design: the basics
12.1. Basic types
12.2. Values
12.2.1. Hierarchy of types and multi-level implicit conversions
12.3. Keys
12.3.1. Converter type
12.3.2. Map type
12.3.3. Generic keys
12.4. DataSet
12.5. Processors
12.6. Exceptions and Messages
13. How to implement the bridge library
13.1. How to implement class Bridge
13.2. How to implement a processor
13.2.1. Implementing a calculator
13.2.2. Implementing an extended calculator
13.2.3. Implementing a builder
13.2.4. Implementing an extended builder
13.3. How to implement a key
13.3.1. Checking methods
13.3.2. Mapping methods

1. Introduction

KeyValue is a cross-platform library for making C++ objects accessible through OpenOffice Calc, Excel and other front-ends. Experience of spreadsheet users is enhanced by an object model and a handy key-value based interface.

Actually, KeyValue does more than just help creating spreadsheet functions. The object model allows end-users to build C++ objects through the front-ends. These objects are stored in a repository for latter use at user's request. Additionally, the KeyValue provides a set of services to an effective use of these objects.

The library is named ater one of its main features: The key-value based interface. Parameters are passed to functions through key-value pairs in contrast to the standard positional interfaces of OpenOffice Calc, Excel, C/C++, etc.

For instance, consider a function which requires stock prices at different dates. Two vectors have to be passed: A vector of dates and a vector of prices. In a positional interface these two vectors would be provided in a specific order, say, first the vector of dates followed by the vector of prices. In contrast, KeyValue allows a label (or key) to be attached to each vector (the value associated to the key) in order to distinguish their meanings. In the example, the keys could be Dates and Prices while the values would be the vectors of dates and prices themselves.

To give a taste of KeyValue, let us develop this example a bit further. Suppose we want to write a C++ function that, given a set of dates and corresponding stock prices, returns to the spreadsheet the earliest date where the stock has reached its lowest level. In the termsheet we would see something like in Figure 1.

Figure 1. Data organized in the spreadsheet.

Data organized in the spreadsheet.


The C++ code (see keyvalue/bridge-example/bridge-example/processor/LowTime.cpp) could be:

template <>
value::Value
Calculator<LowTime>::getValue(const DataSet& data) const {              // A

  const key::MonotoneBoundedVector<ptime, key::StrictlyIncreasing>
    keyDates("Dates");                                                  // B

  const std::vector<ptime>& dates(*data.getValue(keyDates));            // C

  const key::MonotoneBoundedVector<double, key::NonMonotone, key::Geq>
    keyPrices("Prices", 0.0, dates.size());                             // D

  std::vector<double>& prices(*data.getValue(keyPrices));               // E

  double lowPrice = prices[0];                                          // F
  ptime lowDate = dates[0];

  for (size_t i=1; i<prices.size(); ++i)
    if (prices[i] < lowPrice) {
          lowPrice = prices[i];
          lowDate  = dates[i];
    }                                                                   // G

  return lowDate;                                                       // H
}

Without getting too deep in the details, we shall comment some important points of this example:

A:

Functions returning values to the spreadsheet are specializations of template class Calculator of which getValue() is the main method. The template type parameter LowTime is just a tag identifier to distinguish between different functions.

B:

Variable keyDates holds information about key Dates including the label "Dates" seen on the spreadsheet. Being an instantiation of key::MonotoneBoundedVector, it also knows that the expected type of value is a std::vector<ptime>[1]whose elements are in increasing order.

Many other generic keys like key::MonotoneBoundedVector are implemented. We can implement application specific keys when no generic key fits our needs or if this proves to be convenient. For instance, implementing a class named Dates can be convenient if key Dates is to be used very often. This class would hold all the information cited above. Then, line B could be replaced by

const Dates keyDates;
C:

The method DataSet::getValue() retrieves the std::vector<ptime> containing the dates. At this time, all the information contained in keyDates is used. In particular, the constraints on the input are verified and an exception is thrown if the check fails. Therefore, if execution gets to next line, we can safely assume that dates are in increasing order.

D:

Variable keyPrices holds information about key Prices: the label "Prices" and the expected type of value, that is, a std::vector<double> of size dates.size() and positive elements.

E:

Retrieves the std::vector<double> and, if execution gets to next line, we can be sure that prices and dates have the same size and all price elements are positive. Otherwise an exception will be thrown.

F - G:

This bit of code could be part of the library which KeyValue helps to make accessible through OpenOffice Calc or Excel instead of being here.

H:

While the type returned by Calculator<LowTime>::getValue() is value::Value the code above returns a ptime. For convenience, KeyValue implements a collection of implicit conversions to value::Value from several types including bool, double, string, ptime, std::vector<double>, etc.

More than just a nice interface, KeyValue provides memory management, dependency control, exception handling, caching (memoization) and other services.

The two main examples of front-ends (both provided with KeyValue) are OpenOffice Calc and Excel. A third example is a XML parser which can be useful, for instance, for regression tests. Other front-ends may be easily implemented thanks to KeyValue's modular design represented in Figure 2.

There are four layers. The main layer is occupied by KeyValue alone and is independent: It does not #include any header file from other layers.

Figure 2. KeyValue's design.

KeyValue's design.

The top layer is populated by front-ends. Components of this layer only #include header files from KeyValue. (Fact indicated by the down arrow.)

The bottom layer hosts the core library, that is, the C++ library which we want to use through front-ends with KeyValue's help. This layer is also independent.

The bridge layer connects KeyValue and core library. Bridge #includes files from both layers it is connected to.

Additionally to KeyValue layer, the library provides the front-end (excluding the XLM parser which will be available in a future release). KeyValue users, have to implement the bridge and core library. If they wish, they can also easily implement other front-ends.



[1] KeyValue uses time and date class ptime from Boost's Date_Time library.

Valid HTML 4.01 TransitionalValid CSS!