1 /* 2 NL reader 3 4 Copyright (C) 2013 - 2016 AMPL Optimization Inc 5 6 Permission to use, copy, modify, and distribute this software and its 7 documentation for any purpose and without fee is hereby granted, 8 provided that the above copyright notice appear in all copies and that 9 both that the copyright notice and this permission notice and warranty 10 disclaimer appear in supporting documentation. 11 12 The author and AMPL Optimization Inc disclaim all warranties with 13 regard to this software, including all implied warranties of 14 merchantability and fitness. In no event shall the author be liable 15 for any special, indirect or consequential damages or any damages 16 whatsoever resulting from loss of use, data or profits, whether in an 17 action of contract, negligence or other tortious action, arising out 18 of or in connection with the use or performance of this software. 19 20 Author: Victor Zverovich 21 */ 22 23 #ifndef MP_NL_ 24 #define MP_NL_ 25 26 #include "mp/error.h" // MP_ASSERT 27 #include "mp/format.h" // fmt::CStringRef 28 29 #include <cstring> // std::strlen, std::size_t 30 #include <string> // std::string 31 32 namespace mp { 33 34 /** A reference to a null-terminated string with size. */ 35 class NLStringRef { 36 private: 37 const char *data_; 38 std::size_t size_; 39 40 public: 41 /** 42 \rst 43 Constructs a string reference object from a C string computing 44 the size with ``std::strlen``. 45 \endrst 46 */ 47 NLStringRef(const char *s) : data_(s), size_(std::strlen(s)) {} 48 49 /** Constructs a string reference object from a C string and a size. */ 50 NLStringRef(const char *s, std::size_t size) : data_(s), size_(size) { 51 MP_ASSERT(!s[size], "string not null-terminated"); 52 } 53 54 /** 55 \rst 56 Constructs a string reference from an ``std::string`` object. 57 \endrst 58 */ 59 NLStringRef(const std::string &s) : data_(s.c_str()), size_(s.size()) {} 60 61 /** Returns the pointer to a C string. */ 62 const char *c_str() const { return data_; } 63 64 /** Returns the string size. */ 65 std::size_t size() const { return size_; } 66 }; 67 68 // Flags for ReadNLFile and ReadNLString. 69 enum { 70 /** Read variable bounds before anything else. */ 71 READ_BOUNDS_FIRST = 1 72 }; 73 74 /** 75 \rst 76 Reads an optimization problem in the NL format from the string *str* 77 and sends notifications of the problem components to the *handler* object. 78 The handler class can be one of the following 79 80 * derived from `mp::NLHandler` or `mp::NullNLHandler`, 81 * `mp::Problem`, 82 * provide an interface compatible with one of the above. 83 84 Both *str* and *name* can be C strings or ``std::string`` objects. 85 The *name* argument is used as the name of the input when reporting errors. 86 *flags* can be either 0, which is the default, to read all constructs in 87 the order they appear in the input, or `mp::READ_BOUNDS_FIRST` to read 88 variable bounds after the NL header and before other constructs such as 89 nonlinear expressions. 90 \endrst 91 */ 92 template <typename Handler> 93 void ReadNLString(NLStringRef str, Handler &handler, 94 fmt::CStringRef name = "(input)", int flags = 0); 95 96 /** 97 \rst 98 Reads an optimization problem in the NL format from the file *filename* 99 and sends notifications of the problem components to the *handler* object. 100 The handler class can be one of the following 101 102 * derived from `mp::NLHandler` or `mp::NullNLHandler`, 103 * `mp::Problem`, 104 * provide an interface compatible with one of the above. 105 106 The *filename* argument can be a C string or an ``std::string`` object. 107 *flags* can be either 0, which is the default, to read all constructs in 108 the order they appear in the input, or `mp::READ_BOUNDS_FIRST` to read 109 variable bounds after the NL header and before other constructs such as 110 nonlinear expressions. 111 112 **Example**:: 113 114 // Count the number of variable references in all nonlinear expressions. 115 struct VarCounter : mp::NullNLHandler<int> { 116 int num_vars; 117 VarCounter() : num_vars(0) {} 118 Reference OnVariableRef(int) { 119 ++num_vars; 120 return Reference(); 121 } 122 }; 123 VarCounter counter; 124 mp::ReadNLFile("test.nl", counter); 125 fmt::print("The number of variable references is {}.", counter.num_vars); 126 \endrst 127 */ 128 template <typename Handler> 129 void ReadNLFile(fmt::CStringRef filename, Handler &handler, int flags = 0); 130 } // namespace mp 131 132 #endif // MP_NL_ 133