About the Book
“Wilson’s menu of STL treatments will no doubt be good eating for generic programming adherents, ardent C programmers just now taking on STL and C++, Java programmers taking a second look at C++, and authors of libraries targeting multiple platforms and languages. Bon appetit!”
--George Frazier, Cadence Design Systems, Inc.
“A thorough treatment of the details and caveats of STL extension.”
--Pablo Aguilar, C++ Software Engineer
“This book is not just about extending STL, it’s also about extending my thinking in C++.”
--Serge Krynine, C++ Software Engineer, RailCorp Australia
“You might not agree 100% with everything Wilson has to say, but as a whole his book is the most valuable, in-depth study of practical STL-like programming.”
--Thorsten Ottosen, M.C.S., Boost Contributor
“Wilson is a master lion tamer, persuading multifarious third-party library beasts to jump through STL hoops. He carefully guides the reader through the design considerations, pointing out the pitfalls and making sure you don't get your head bitten off.”
--Adi Shavit, Chief Software Architect, EyeTech Co. Ltd
“Wilson’s book provides more than enough information to change the angst/uncertainty level of extending STL from `daunting’ to `doable.’ ”
--Garth Lancaster, EDI/Automation Manager, Business Systems Group, MBF Australia
“This book will open up your eyes and uncover just how powerful STL’s abstractions really are.”
--Nevin “:-)” Liber, 19-year veteran of C++
“In the canon of C++ there are very few books that extend the craft. Wilson’s work consistently pushes the limits, showing what can and cannot be done, and the tradeoffs involved.”
--John O’Halloran, Head of Software Development, Mediaproxy
“Essential concepts and practices to take the working programmer beyond the standard library.”
--Greg Peet
“Extended STL is not just a book about adapting the STL to fit in with your everyday work, it’s also an odyssey through software design and concepts, C++ power techniques, and the perils of real-world software development--in other words, it’s a Matthew Wilson book. If you're serious about C++, I think you should read it.”
--Björn Karlsson, Principle Architect, ReadSoft; author of Beyond the C++ Standard Library: An Introduction to Boost
In Extended STL, renowned C++ expert Matthew Wilson shows how to go beyond the C++ standard and extend the Standard Template Library into the wider C++ world of APIs and non-standard collections, to write software that is more efficient, expressive, flexible, and robust.
In Volume 1, Wilson’s innovative techniques help you master STL extension in two important areas: adapting technology-specific libraries and operating system APIs to STL-compliant collections, and defining sophisticated iterator adaptors with which the latent efficiency and expressive power of STL can be realized. Using real-world examples, Wilson illustrates several powerful concepts and techniques that enable you to extend STL in directions never envisioned by its creators, including collections, element reference categories, external iterator invalidation and inferred interface adaptation.
Extended STL, Volume 1, will be an invaluable resource for every C++ programmer who is at least minimally familiar with the STL.
Learn specific principles and techniques for STL extension
Learn more about the STL by looking inside the implementation of STL extensions
Learn general techniques for implementing wrappers over operating system APIs and technology-specific libraries
Learn how to write iterator adaptors and understand the reasons behind the restrictions on their implementations and use
Specific coverage includes
Making the most of collections, and understanding how they differ from containers
Mastering element reference categories: defining them, detecting them, and using them to design STL extension collections and iterators
Working with external iterator invalidation, and understanding its surprising impact on the design of STL-compatible collections
Adapting real-world APIs ranging from file
system enumeration to scatter/gather I/O
Using standalone iterator types, from simple std::ostream_iterator extensions to sophisticated adaptors that filter and transform types or values
The accompanying CD-ROM contains an extensive collection of open-source libraries created by the author. Also included: several test projects, and three bonus chapters.
Table of Contents:
Preface xviiAims xvii
Subject Matter xviii
Structure xix
Supplementary Material xxAcknowledgments xxiParachutes: Coda xxiiAbout the Author xxiiiPrologue xxivA Dichotomy of Character xxiv
Principles of UNIX Programming xxv
Seven Signs of Successful C++ Software Libraries xxvi
Balancing the Signs: Satisfiction, Dialecticism, and Idioms Old and New xxxii
Example Libraries xxxiiiPresentation Conventions xxxviiFonts xxxvii
. . . versus ... xxxvii
End Iterator Precomputation xxxviii
Nested Class Type Qualification xxxix
NULL xxxix
Template Parameter Names xl
Member and Namespace-Scope Type Names xl
Calling Conventions xl
Endpoint Iterators xl
Namespace for Standard C Names xl
Class Adaptors and Instance Adaptors xl
Header File Names liPART ONE: Foundations 1Chapter 1: The Standard Template Library 31.1 Core Concepts 3
1.2 Containers 4
1.3 Iterators 5
1.4 Algorithms 12
1.5 Function Objects 3
1.6 Allocators 13Chapter 2: Extended STL Concepts, or When STL Meets the Real World 142.1 Terminology 142.2 Collections 152.3 Iterators 18Chapter 3: Element Reference Categories 213.1 Introduction 21
3.2 C++ References 21
3.3 A Taxonomy of Element Reference Categories 23
3.4 Using Element Reference Categories 29
3.5 Defining operator ->() 31
3.6 Element Reference Categories: Coda 31Chapter 4: The Curious Untemporary Reference 32Chapter 5: The DRY SPOT Principle 345.1 DRY SPOTs in C++ 4
5.2 Not Quite DRY SPOTs in C++ 36
5.3 Closed Namespaces 38Chapter 6: The Law of Leaky Abstractions 40Chapter 7: Contract Programming 427.1 Enforcement Types 42
7.2 Enforcement Mechanisms 43Chapter 8: Constraints 458.1 Type System Leverage 45
8.2 Static Assertions 46Chapter 9: Shims 489.1 Introduction 48
9.2 Primary Shims 49
9.3 Composite Shims 52Chapter 10: Duck and Goose, or the Whimsical Bases of Partial Structural Conformance 5710.1 Conformance 57
10.2 Explicit Semantic Conformance 62
10.3 Intersecting Conformance 64Chapter 11: RAII 6511.1 Mutability 65
11.2 Resource Source 65Chapter 12: Template Tools 6712.1 Traits 67
12.2 Type Generators 75
12.3 True Typedefs 76Chapter 13: Inferred Interface Adaptation: Compile-Time Adaptation of Interface-Incomplete Types 7713.1 Introduction 77
13.2 Adapting Interface-Incomplete Types 78
13.3 Adapting Immutable Collections 79
13.4 Inferred Interface Adaptation 80
13.5 Applying IIA to the Range 85Chapter 14: Henney's Hypothesis, or When Templates Attack! 87Chapter 15: The Independent Autonomies of equal() Friends 8915.1 Beware Nonmember Friend Function Abuse 89
15.2 Collections and Their Iterators 91Chapter 16: Essential Components 9316.1 Introduction 93
16.2 auto_buffer 93
16.3 filesystem_traits 97
16.4 file_path_buffer 103
16.5 scoped_handle 107
16.6 dl_call() 109PART TWO: Collections 111Chapter 17: Adapting the glob API 11517.1 Introduction 115
17.2 Decomposition of the Longhand Version 119
17.3 unixstl::glob_sequence 121
17.4 Decomposition of the Shorthand Version 135
17.5 Summary 135Chapter 18: Intermezzo: Constructor Clashes and Design That Is, If Not Bad, At Least Ill-Conceived for Seamless Evolution 137Chapter 19: Adapting the opendir/readdir API 14019.1 Introduction 140
19.2 Decomposition of the Longhand Version 142v19.3 unixstl::readdir_sequence 144
19.4 Alternate Implementations 61
19.5 Summary 162Chapter 20: Adapting the FindFirstFile/FindNextFile API 16420.1 Introduction 164
20.2 Decomposition of Examples 169
20.3 Sequence Design 171
20.4 winstl::basic_findfile_sequence 172
20.5 winstl::basic_findfile_sequence_const_iterator 178
20.6 winstl::basic_findfile_sequence_value_type 191
20.7 Shims 193
20.8 What, No Shims and Constructor Templates? 94
20.9 Summary 194
20.10 File System Enumeration with recls: Coda 195Chapter 21: Intermezzo: When the Efficiency/Usability Balance Is Tipped: Enumerating FTP Server Directories 19621.1 inetstl::basic_findfile_sequence 197
21.2 inetstl::basic_ftpdir_sequence 199Chapter 22: Enumerating Processes and Modules 20122.1 Collection Characteristics 202
22.2 winstl::pid_sequence 202
22.3 winstl::process_module_sequence 206
22.4 Enumerating All Modules on a System 206
22.5 Avoiding the System Pseudo Processes 208
22.6 Handling Optional API Headers 210
22.7 Summary 211Chapter 23: The Fibonacci Sequence 21223.1 Introduction 212
23.2 The Fibonacci Sequence 12
23.3 Fibonacci as an STL Sequence 212
23.4 Discoverability Failure 218
23.5 Defining Finite Bounds 218
23.6 Summary 225Chapter 24: Adapting MFC's CArray Container Family 22724.1 Introduction 227
24.2 Motivation 227
24.3 Emulating std::vector 230
24.4 Design Considerations 232
24.5 mfcstl::CArray_adaptor_base Interface 237
24.6 mfcstl::CArray_cadaptor 239
24.7 mfcstl::CArray_iadaptor 244
24.8 Construction 245
24.9 Allocator 245
24.10 Element Access Methods 246
24.11 Iteration 246
24.12 Size 248
24.13 Capacity 252
24.14 Comparison 253
24.15 Modifiers 256
24.16 Assignment and swap() 261
24.17 Summary 264
24.18 On the CD 265Chapter 25: A Map of the Environment 26625.1 Introduction 266
25.2 Motivation 266
25.3 getenv(), putenv(), setenv()/unsetenv(), and environ 267
25.4 platformstl::environment_variable_traits 268
25.5 Planning the Interface 271
25.6 Lookup by Name 271
25.7 Inserting, Updating, and Deleting Values by Name 277
25.8 Iteration 278
25.9 Final Iteration Implementation 286
25.10 Heterogeneous Reference Categories? 297
25.11 size() and Subscript by Index 297
25.12 Summary 298
25.13 On the CD 298Chapter 26: Traveling Back and Forth on the Z-Plane 29926.1 Prologue 299
26.2 Introduction 299
26.3 Version 1: Forward Iteration 302
26.4 Version 2: Bidirectional Iteration 304
26.5 Handling External Change 306
26.6 winstl::child_window_sequence 309
26.7 Bidirectional Iterator Blues 309
26.8 winstl::zorder_iterator: A Reversal of Self 315
26.9 Finalizing the Window Peer Sequences 321
26.10 Summary 323
26.11 Z-Plane: Coda 323Chapter 27: String Tokenization 32427.1 Introduction 324
27.2 strtok() 325
27.3 SynesisSTL::StringTokeniser 327
27.4 Tokenization Use Cases 329
27.5 Other Tokenization Alternatives 330
27.6 stlsoft::string_tokeniser 331
27.7 Test Drive 340
27.8 The Policy Folly 345
27.9 Performance 348
27.10 Summary 352Chapter 28: Adapting COM Enumerators 35328.1 Introduction 353
28.2 Motivation 353
28.3 COM Enumerators 355
28.4 Decomposition of the Longhand Version 358
28.5 comstl::enumerator_sequence 359
28.6 comstl::enumerator_sequence::iterator 368
28.7 comstl::enumerator_sequence::iterator::enumeration_context 372
28.8 Iterator Cloning Policies 381
28.9 Choosing a Default Cloning Policy: Applying the Principle of Least Surprise 385
28.10 Summary 390
28.11 Coming Next 391Chapter 29: Intermezzo: Correcting Minor Design Omissions with Member Type Inference 392Chapter 30: Adapting COM Collections 39430.1 Introduction 394
30.2 Motivation 394
30.3 comstl::collection_sequence 398
30.4 Enumerator Acquisition Policies 403
30.5 Summary 406Chapter 31: Gathering Scattered I/O 40731.1 Introduction 407
31.2 Scatter/Gather I/O 407
31.3 Scatter/Gather I/O APIs 409
31.4 Adapting ACE_Message_Queue 414
31.5 Time for Some Cake 420
31.6 Summary 427Chapter 32: Argument-Dependent Return-Type Variance 42832.1 Introduction 428
32.2 Borrowing a Jewel from Ruby 428
32.3 Dual-Semantic Subscripting in C++ 430
32.4 Generalized Compatibility via String Access Shims 431
32.5 A Fly in the int-ment 432
32.6 Selecting Return Type and Overload 433
32.7 Summary 434Chapter 33: External Iterator Invalidation 43533.1 Element-Interface Coherence 435
33.2 Windows ListBox and ComboBox Controls 437
33.3 Enumerating Registry Keys and Values 444
33.4 Summary 463
33.5 On the CD 463PART THREE: Iterators 465Chapter 34: An Enhanced ostream_iterator 46734.1 Introduction 467
34.2 std::ostream_iterator 469
34.3 stlsoft::ostream_iterator 470
34.4 Defining Stream Insertion Operators 475
34.5 Summary 476Chapter 35: Intermezzo: Proscribing Fatuous Output Iterator Syntax Using the Dereference Proxy Pattern 47735.1 stlsoft::ostream_iterator::deref_proxy 478Chapter 36: Transform Iterator 48136.1 Introduction 481
36.2 Motivation 482
36.3 Defining Iterator Adaptors 485
36.4 stlsoft::transform_iterator 487
36.5 Composite Transformations 496
36.6 DRY SPOT Violations? 497
36.7 A Spoonful of Sequence Helps the Medicine . . . ? 501
36.8 Summary 501
36.9 On the CD 502Chapter 37: Intermezzo: Discretion Being the Better Part of Nomenclature . . . 503Chapter 38: Member Selector Iterator 50638.1 Introduction 506
38.2 Motivation 506
38.3 stlsoft::member_selector_iterator 509
38.4 Creator Function Woes 511
38.5 Summary 518
38.6 On the CD 518Chapter 39: C-Style String Concatenation 51939.1 Motivation 519
39.2 An Inflexible Version 520
39.3 stlsoft::cstring_concatenator_iterator 522
39.4 Creator Functions 524
39.5 Summary 525
39.6 On the CD 526Chapter 40: String Object Concatenation 52740.1 Introduction 527
40.2 stlsoft::string_concatenator_iterator 527
40.3 Heterogeneity of String Types 530
40.4 But . . . 530
40.5 Summary 532Chapter 41: Adapted Iterators Traits 53341.1 Introduction 533
41.2 stlsoft::adapted_iterator_traits 533
41.3 Summary 540
41.4 On the CD 541Chapter 42: Filtered Iteration 54242.1 Introduction 542
42.2 An Invalid Version 542
42.3 Member Iterators Define the Range 543
42.4 So . . . ? 544
42.5 stlsoft::filter_iterator 545
42.6 Constraining the Iterator Category 549
42.7 Summary 550
42.8 On the CD 550Chapter 43: Composite Iterator Adaptations 55143.1 Introduction 551
43.2 Transforming a Filtered Iterator 551
43.3 Filtering a Transformed Iterator 553
43.4 Hedging Our Bets 554
43.5 Summary 554Epilogue 555Bibliography 556
Index 559