Commit MetaInfo

Revision8257513d0169938f5e2bf0ef9ef72d5f92eb0fbf (tree)
Time2013-05-11 12:12:08
Author <exeal@user...>

Log Message

Distributed BOOST_NOEXCEPT into many codes.

Change Summary

Incremental Difference

diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/content-assist/default-completion-proposal.hpp
--- a/ascension/ascension/content-assist/default-completion-proposal.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/content-assist/default-completion-proposal.hpp Sat May 11 12:12:08 2013 +0900
@@ -24,10 +24,10 @@
2424 const String& displayString, const String& description = String(),
2525 CompletionProposal::Icon&& icon = Icon(), bool autoInsertable = true);
2626 public:
27- String description() const /*throw()*/;
28- String displayString() const /*throw()*/;
29- const Icon& icon() const /*throw()*/;
30- bool isAutoInsertable() const /*throw()*/;
27+ String description() const BOOST_NOEXCEPT;
28+ String displayString() const BOOST_NOEXCEPT;
29+ const Icon& icon() const BOOST_NOEXCEPT;
30+ bool isAutoInsertable() const BOOST_NOEXCEPT;
3131 void replace(kernel::Document& document,
3232 const kernel::Region& replacementRegion) const;
3333 private:
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/basic-exceptions.hpp
--- a/ascension/ascension/corelib/basic-exceptions.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/basic-exceptions.hpp Sat May 11 12:12:08 2013 +0900
@@ -104,7 +104,7 @@
104104 explicit IntegralError(Code code,
105105 const std::string& message = "") : Base(message), code_(code) {}
106106 /// Returns the error code.
107- Code code() const /*throw()*/;
107+ Code code() const BOOST_NOEXCEPT;
108108 private:
109109 const Code code_;
110110 };
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/basic-types.hpp
--- a/ascension/ascension/corelib/basic-types.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/basic-types.hpp Sat May 11 12:12:08 2013 +0900
@@ -4,7 +4,7 @@
44 * @date 2004-2010
55 * @date 2010-10-21 separated from common.hpp
66 * @date 2010-11-07 joined with common.hpp
7- * @date 2011-2012
7+ * @date 2011-2013
88 */
99
1010 #ifndef ASCENSION_BASIC_TYPES_HPP
@@ -119,7 +119,7 @@
119119 * (for example, received @c WM_SETTINGCHANGE window message on Win32 platform).
120120 * @deprecated 0.8
121121 */
122- void updateSystemSettings() /*throw()*/;
122+ void updateSystemSettings() BOOST_NOEXCEPT;
123123
124124 // see session.hpp
125125 namespace texteditor {
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/encoder.hpp
--- a/ascension/ascension/corelib/encoder.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/encoder.hpp Sat May 11 12:12:08 2013 +0900
@@ -1,7 +1,7 @@
11 /**
22 * @file encoder.hpp
33 * @author exeal
4- * @date 2004-2012
4+ * @date 2004-2013
55 */
66
77 #ifndef ASCENSION_ENCODER_HPP
@@ -210,11 +210,11 @@
210210 return (first2 == last2) ? 0 : -1;
211211 }
212212
213- MIBenum convertCCSIDtoMIB(unsigned int ccsid) /*noexcept*/;
214- unsigned int convertMIBtoCCSID(MIBenum mib) /*noexcept*/;
213+ MIBenum convertCCSIDtoMIB(unsigned int ccsid) BOOST_NOEXCEPT;
214+ unsigned int convertMIBtoCCSID(MIBenum mib) BOOST_NOEXCEPT;
215215 #ifdef ASCENSION_OS_WINDOWS
216- unsigned int convertMIBtoWinCP(MIBenum mib) /*noexcept*/;
217- MIBenum convertWinCPtoMIB(unsigned int codePage) /*noexcept*/;
216+ unsigned int convertMIBtoWinCP(MIBenum mib) BOOST_NOEXCEPT;
217+ MIBenum convertWinCPtoMIB(unsigned int codePage) BOOST_NOEXCEPT;
218218 #endif // ASCENSION_OS_WINDOWS
219219 String getEncodingDisplayName(MIBenum mib);
220220 std::string encodingNameFromUnicode(const String& source);
@@ -235,34 +235,34 @@
235235 * Returns the aliases of the encoding. Default implementation returns an empty.
236236 * @return a string contains aliases separated by vertical bar ('|')
237237 */
238- virtual std::string aliases() const /*noexcept*/ {return "";}
238+ virtual std::string aliases() const BOOST_NOEXCEPT {return "";}
239239 /**
240240 * Returns the human-readable name of the encoding. Default implementation calls
241241 * @c #name method.
242242 * @param locale The locale used to localize the name
243243 * @see #name
244244 */
245- virtual std::string displayName(const std::locale& locale) const /*noexcept*/ {return name();}
245+ virtual std::string displayName(const std::locale& locale) const BOOST_NOEXCEPT {return name();}
246246 /// Returns the number of bytes represents a UCS character.
247- virtual std::size_t maximumNativeBytes() const /*noexcept*/ = 0;
247+ virtual std::size_t maximumNativeBytes() const BOOST_NOEXCEPT = 0;
248248 /// Returns the number of UCS characters represents a native character. Default
249249 /// implementation returns 1.
250- virtual std::size_t maximumUCSLength() const /*noexcept*/ {return 1;}
250+ virtual std::size_t maximumUCSLength() const BOOST_NOEXCEPT {return 1;}
251251 /// Returns the MIBenum value of the encoding.
252- virtual MIBenum mibEnum() const /*noexcept*/ = 0;
252+ virtual MIBenum mibEnum() const BOOST_NOEXCEPT = 0;
253253 /**
254254 * Returns the name of the encoding. If the encoding is registered as a character set
255255 * in <a href="http://www.iana.org/assignments/character-sets">IANA character-sets
256256 * encoding file</a>, should return the preferred mime name.
257257 * @see #displayName
258258 */
259- virtual std::string name() const /*noexcept*/ = 0;
259+ virtual std::string name() const BOOST_NOEXCEPT = 0;
260260 /**
261261 * Returns an native character which indicates that the given Unicode character can't
262262 * map. If @c #policy returns @c REPLACE_UNMAPPABLE_CHARACTER, the encoder should use
263263 * this character. Default implementation returns 0x1A.
264264 */
265- virtual Byte substitutionCharacter() const /*noexcept*/ {return 0x1a;}
265+ virtual Byte substitutionCharacter() const BOOST_NOEXCEPT {return 0x1a;}
266266 };
267267
268268 class EncoderFactory;
@@ -337,15 +337,15 @@
337337 static const char ALIASES_SEPARATOR;
338338
339339 public:
340- virtual ~Encoder() /*noexcept*/;
340+ virtual ~Encoder() BOOST_NOEXCEPT;
341341 // attributes
342- int flags() const /*noexcept*/;
343- virtual const EncodingProperties& properties() const /*noexcept*/ = 0;
344- virtual Encoder& resetDecodingState() /*noexcept*/;
345- virtual Encoder& resetEncodingState() /*noexcept*/;
342+ int flags() const BOOST_NOEXCEPT;
343+ virtual const EncodingProperties& properties() const BOOST_NOEXCEPT = 0;
344+ virtual Encoder& resetDecodingState() BOOST_NOEXCEPT;
345+ virtual Encoder& resetEncodingState() BOOST_NOEXCEPT;
346346 Encoder& setFlags(const int newFlags);
347347 Encoder& setSubstitutionPolicy(SubstitutionPolicy newPolicy);
348- SubstitutionPolicy substitutionPolicy() const /*noexcept*/;
348+ SubstitutionPolicy substitutionPolicy() const BOOST_NOEXCEPT;
349349 // conversion
350350 bool canEncode(CodePoint c);
351351 bool canEncode(const StringPiece& s);
@@ -355,19 +355,19 @@
355355 String toUnicode(const std::string& from);
356356 // factory
357357 template<typename OutputIterator> static void availableEncodings(OutputIterator out);
358- static Encoder& defaultInstance() /*noexcept*/;
359- static std::unique_ptr<Encoder> forCCSID(int ccsid) /*noexcept*/;
360- static std::unique_ptr<Encoder> forCPGID(int cpgid) /*noexcept*/;
361- static std::unique_ptr<Encoder> forID(std::size_t id) /*noexcept*/;
362- static std::unique_ptr<Encoder> forMIB(MIBenum mib) /*noexcept*/;
363- static std::unique_ptr<Encoder> forName(const std::string& name) /*noexcept*/;
364- static std::unique_ptr<Encoder> forWindowsCodePage(unsigned int codePage) /*noexcept*/;
365- static bool supports(MIBenum mib) /*noexcept*/;
366- static bool supports(const std::string& name) /*noexcept*/;
358+ static Encoder& defaultInstance() BOOST_NOEXCEPT;
359+ static std::unique_ptr<Encoder> forCCSID(int ccsid) BOOST_NOEXCEPT;
360+ static std::unique_ptr<Encoder> forCPGID(int cpgid) BOOST_NOEXCEPT;
361+ static std::unique_ptr<Encoder> forID(std::size_t id) BOOST_NOEXCEPT;
362+ static std::unique_ptr<Encoder> forMIB(MIBenum mib) BOOST_NOEXCEPT;
363+ static std::unique_ptr<Encoder> forName(const std::string& name) BOOST_NOEXCEPT;
364+ static std::unique_ptr<Encoder> forWindowsCodePage(unsigned int codePage) BOOST_NOEXCEPT;
365+ static bool supports(MIBenum mib) BOOST_NOEXCEPT;
366+ static bool supports(const std::string& name) BOOST_NOEXCEPT;
367367 static void registerFactory(EncoderFactory& newFactory);
368368
369369 protected:
370- Encoder() /*noexcept*/;
370+ Encoder() BOOST_NOEXCEPT;
371371 private:
372372 /**
373373 * Converts the given string from UTF-16 into the native encoding.
@@ -395,8 +395,8 @@
395395 virtual Result doToUnicode(Char* to, Char* toEnd, Char*& toNext,
396396 const Byte* from, const Byte* fromEnd, const Byte*& fromNext) = 0;
397397 private:
398- static EncoderFactory* find(MIBenum mib) /*noexcept*/;
399- static EncoderFactory* find(const std::string& name) /*noexcept*/;
398+ static EncoderFactory* find(MIBenum mib) BOOST_NOEXCEPT;
399+ static EncoderFactory* find(const std::string& name) BOOST_NOEXCEPT;
400400 static std::vector<EncoderFactory*>& registry();
401401 SubstitutionPolicy substitutionPolicy_;
402402 int flags_; // see Flag enums
@@ -406,10 +406,10 @@
406406 class EncoderFactory : public EncodingProperties {
407407 public:
408408 /// Destructor.
409- virtual ~EncoderFactory() /*noexcept*/ {}
409+ virtual ~EncoderFactory() BOOST_NOEXCEPT {}
410410 protected:
411411 /// Returns the @c Encoder instance.
412- virtual std::unique_ptr<Encoder> create() const /*noexcept*/ = 0;
412+ virtual std::unique_ptr<Encoder> create() const BOOST_NOEXCEPT = 0;
413413 friend class Encoder;
414414 };
415415
@@ -417,16 +417,16 @@
417417 ASCENSION_NONCOPYABLE_TAG(EncodingDetector);
418418 public:
419419 // constructors
420- virtual ~EncodingDetector() /*noexcept*/;
420+ virtual ~EncodingDetector() BOOST_NOEXCEPT;
421421 // attributes
422422 /// Returns the name of the encoding detector.
423- std::string name() const /*noexcept*/ {return name_;}
423+ std::string name() const BOOST_NOEXCEPT {return name_;}
424424 // detection
425425 std::pair<MIBenum, std::string> detect(const Byte* first, const Byte* last, std::ptrdiff_t* convertibleBytes) const;
426426 // factory
427- static EncodingDetector* forName(const std::string& name) /*noexcept*/;
427+ static EncodingDetector* forName(const std::string& name) BOOST_NOEXCEPT;
428428 #ifdef ASCENSION_OS_WINDOWS
429- static EncodingDetector* forWindowsCodePage(unsigned int codePage) /*noexcept*/;
429+ static EncodingDetector* forWindowsCodePage(unsigned int codePage) BOOST_NOEXCEPT;
430430 #endif // ASCENSION_OS_WINDOWS
431431 template<typename OutputIterator> static void availableNames(OutputIterator out);
432432 static void registerDetector(std::unique_ptr<EncodingDetector> newDetector);
@@ -443,7 +443,7 @@
443443 * @return The MIBenum value and the name of the detected encoding
444444 */
445445 virtual std::pair<MIBenum, std::string> doDetect(
446- const Byte* first, const Byte* last, std::ptrdiff_t* convertibleBytes) const /*noexcept*/ = 0;
446+ const Byte* first, const Byte* last, std::ptrdiff_t* convertibleBytes) const BOOST_NOEXCEPT = 0;
447447 private:
448448 static std::vector<EncodingDetector*>& registry();
449449 const std::string name_;
@@ -463,7 +463,7 @@
463463 /// @c EncoderFactoryBase is a base implementation of @c EncoderFactory.
464464 class EncoderFactoryBase : public EncoderFactory {
465465 public:
466- virtual ~EncoderFactoryBase() /*noexcept*/;
466+ virtual ~EncoderFactoryBase() BOOST_NOEXCEPT;
467467 protected:
468468 EncoderFactoryBase(const std::string& name,
469469 MIBenum mib, const std::string& displayName = "",
@@ -471,13 +471,13 @@
471471 const std::string& aliases = "", Byte substitutionCharacter = 0x1a);
472472 protected:
473473 // EncodingProperties
474- virtual std::string aliases() const /*noexcept*/;
475- virtual std::string displayName(const std::locale& lc) const /*noexcept*/;
476- virtual std::size_t maximumNativeBytes() const /*noexcept*/;
477- virtual std::size_t maximumUCSLength() const /*noexcept*/;
478- virtual MIBenum mibEnum() const /*noexcept*/;
479- virtual std::string name() const /*noexcept*/;
480- virtual Byte substitutionCharacter() const /*noexcept*/;
474+ virtual std::string aliases() const BOOST_NOEXCEPT;
475+ virtual std::string displayName(const std::locale& lc) const BOOST_NOEXCEPT;
476+ virtual std::size_t maximumNativeBytes() const BOOST_NOEXCEPT;
477+ virtual std::size_t maximumUCSLength() const BOOST_NOEXCEPT;
478+ virtual MIBenum mibEnum() const BOOST_NOEXCEPT;
479+ virtual std::string name() const BOOST_NOEXCEPT;
480+ virtual Byte substitutionCharacter() const BOOST_NOEXCEPT;
481481 private:
482482 const std::string name_, displayName_, aliases_;
483483 const std::size_t maximumNativeBytes_, maximumUCSLength_;
@@ -517,7 +517,7 @@
517517
518518 /// Returns a code corresponds to a byte in the 16×16 wire.
519519 /// @see CodeWire
520- template<typename Code> inline Code wireAt(const Code** wire, Byte c) /*noexcept*/ {return wire[c >> 4][c & 0xf];}
520+ template<typename Code> inline Code wireAt(const Code** wire, Byte c) BOOST_NOEXCEPT {return wire[c >> 4][c & 0xf];}
521521
522522 /// Generates 16×16-character sequence.
523523 template<
@@ -536,10 +536,10 @@
536536 /// @see CharMap
537537 class BidirectionalMap {
538538 public:
539- BidirectionalMap(const Char** byteToCharacterWire) /*noexcept*/;
540- ~BidirectionalMap() /*noexcept*/;
541- Byte toByte(Char c) const /*noexcept*/;
542- Char toCharacter(Byte c) const /*noexcept*/;
539+ BidirectionalMap(const Char** byteToCharacterWire) BOOST_NOEXCEPT;
540+ ~BidirectionalMap() BOOST_NOEXCEPT;
541+ Byte toByte(Char c) const BOOST_NOEXCEPT;
542+ Char toCharacter(Byte c) const BOOST_NOEXCEPT;
543543 private:
544544 void buildUnicodeToByteTable();
545545 private:
@@ -602,9 +602,9 @@
602602 public:
603603 SingleByteEncoderFactory(const std::string& name, MIBenum mib,
604604 const std::string& displayName, const std::string& aliases, Byte substitutionCharacter);
605- virtual ~SingleByteEncoderFactory() /*noexcept*/;
605+ virtual ~SingleByteEncoderFactory() BOOST_NOEXCEPT;
606606 private:
607- std::unique_ptr<Encoder> create() const /*noexcept*/;
607+ std::unique_ptr<Encoder> create() const BOOST_NOEXCEPT;
608608 };
609609 } // namespace sbcs
610610
@@ -636,7 +636,7 @@
636636
637637 namespace detail {
638638 std::unique_ptr<encoding::Encoder> createSingleByteEncoder(
639- const Char** byteToCharacterWire, const encoding::EncodingProperties& properties) /*noexcept*/;
639+ const Char** byteToCharacterWire, const encoding::EncodingProperties& properties) BOOST_NOEXCEPT;
640640 }
641641
642642 namespace encoding {
@@ -655,10 +655,10 @@
655655 }
656656
657657 /// Returns the miscellaneous flags.
658- inline int Encoder::flags() const /*noexcept*/ {return flags_;}
658+ inline int Encoder::flags() const BOOST_NOEXCEPT {return flags_;}
659659
660660 /// Returns the substitution policy.
661- inline Encoder::SubstitutionPolicy Encoder::substitutionPolicy() const /*noexcept*/ {
661+ inline Encoder::SubstitutionPolicy Encoder::substitutionPolicy() const BOOST_NOEXCEPT {
662662 return substitutionPolicy_;
663663 }
664664
@@ -692,7 +692,7 @@
692692 * Returns the byte corresponds to the given character @c c or @c UNMAPPABLE_BYTE if
693693 * umappable.
694694 */
695- inline Byte implementation::sbcs::BidirectionalMap::toByte(Char c) const /*noexcept*/ {
695+ inline Byte implementation::sbcs::BidirectionalMap::toByte(Char c) const BOOST_NOEXCEPT {
696696 return unicodeToByte_[c >> 8][mask8Bit(c)];
697697 }
698698
@@ -700,7 +700,7 @@
700700 * Returns the character corresponds to the given byte @a c or @c REPLACEMENT_CHARACTER if
701701 * umappable.
702702 */
703- inline Char implementation::sbcs::BidirectionalMap::toCharacter(Byte c) const /*noexcept*/ {
703+ inline Char implementation::sbcs::BidirectionalMap::toCharacter(Byte c) const BOOST_NOEXCEPT {
704704 return wireAt(byteToUnicode_, c);
705705 }
706706
@@ -718,12 +718,12 @@
718718
719719 /// Destructor.
720720 template<typename MappingTable>
721- inline implementation::sbcs::SingleByteEncoderFactory<MappingTable>::~SingleByteEncoderFactory() /*noexcept*/ {
721+ inline implementation::sbcs::SingleByteEncoderFactory<MappingTable>::~SingleByteEncoderFactory() BOOST_NOEXCEPT {
722722 }
723723
724724 /// @see EncoderFactory#create
725725 template<typename MappingTable> std::unique_ptr<Encoder>
726- implementation::sbcs::SingleByteEncoderFactory<MappingTable>::create() const /*noexcept*/ {
726+ implementation::sbcs::SingleByteEncoderFactory<MappingTable>::create() const BOOST_NOEXCEPT {
727727 return detail::createSingleByteEncoder(MappingTable::VALUES, *this);
728728 }
729729 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/listeners.hpp
--- a/ascension/ascension/corelib/listeners.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/listeners.hpp Sat May 11 12:12:08 2013 +0900
@@ -14,11 +14,10 @@
1414 #include <boost/signals2.hpp>
1515
1616 namespace ascension {
17-
1817 template<typename Signal>
1918 class SignalConnector {
2019 public:
21- SignalConnector(Signal& signal) /*throw()*/ : signal_(signal) {
20+ SignalConnector(Signal& signal) BOOST_NOEXCEPT : signal_(signal) {
2221 }
2322 boost::signals2::connection connect(const typename Signal::slot_type& slot,
2423 boost::signals2::connect_position where = boost::signals2::at_back) {
@@ -35,14 +34,13 @@
3534 #define ASCENSION_DEFINE_SIGNAL(signalTypeName, signature, signalName) \
3635 public: \
3736 typedef boost::signals2::signal<signature> signalTypeName; \
38- SignalConnector<signalTypeName> signalName() const /*throw()*/ { \
37+ SignalConnector<signalTypeName> signalName() const BOOST_NOEXCEPT { \
3938 return const_cast<signalTypeName&>(signalName##_); \
4039 } \
4140 private: \
4241 signalTypeName signalName##_
4342
4443 namespace detail {
45-
4644 #if ASCENSION_ABANDONED_AT_VERSION_08
4745 /**
4846 * @internal Manages a strategy object.
@@ -53,13 +51,13 @@
5351 class StrategyPointer {
5452 ASCENSION_NONCOPYABLE_TAG(StrategyPointer);
5553 public:
56- StrategyPointer() /*throw()*/ : pointee_(nullptr), manages_(false) {}
57- StrategyPointer(Strategy* pointee, bool manage) /*throw()*/ : pointee_(pointee), manages_(manage) {}
58- ~StrategyPointer() /*throw()*/ {if(manages_) delete pointee_;}
59- Strategy& operator*() const /*throw()*/ {return *pointee_;}
60- Strategy* operator->() const /*throw()*/ {return get();}
61- Strategy* get() const /*throw()*/ {return pointee_;}
62- void reset(Strategy* newValue, bool manage) /*throw()*/ {
54+ StrategyPointer() BOOST_NOEXCEPT : pointee_(nullptr), manages_(false) {}
55+ StrategyPointer(Strategy* pointee, bool manage) BOOST_NOEXCEPT : pointee_(pointee), manages_(manage) {}
56+ ~StrategyPointer() BOOST_NOEXCEPT {if(manages_) delete pointee_;}
57+ Strategy& operator*() const BOOST_NOEXCEPT {return *pointee_;}
58+ Strategy* operator->() const BOOST_NOEXCEPT {return get();}
59+ Strategy* get() const BOOST_NOEXCEPT {return pointee_;}
60+ void reset(Strategy* newValue, bool manage) BOOST_NOEXCEPT {
6361 if(manages_ && newValue != pointee_)
6462 delete pointee_;
6563 pointee_ = newValue;
@@ -80,7 +78,7 @@
8078 class Listeners {
8179 ASCENSION_NONCOPYABLE_TAG(Listeners);
8280 public:
83- Listeners() /*throw()*/ {}
81+ Listeners() BOOST_NOEXCEPT {}
8482 void add(Listener& listener) {
8583 if(std::find(listeners_.begin(), listeners_.end(), &listener) != listeners_.end())
8684 throw std::invalid_argument("The listener already has been registered.");
@@ -92,8 +90,8 @@
9290 throw std::invalid_argument("The listener is not registered.");
9391 listeners_.erase(i);
9492 }
95- void clear() /*throw()*/ {listeners_.clear();}
96- bool isEmpty() const /*throw()*/ {return listeners_.empty();}
93+ void clear() BOOST_NOEXCEPT {listeners_.clear();}
94+ bool isEmpty() const BOOST_NOEXCEPT {return listeners_.empty();}
9795 void notify(void(Listener::*method)()) {
9896 for(Iterator i(listeners_.begin()), e(listeners_.end()), next; i != e; i = next) {
9997 next = i;
@@ -145,7 +143,6 @@
145143 std::list<Listener*> listeners_;
146144 typedef typename std::list<Listener*>::iterator Iterator;
147145 };
148-
149146 }
150147 }
151148
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/memory.hpp
--- a/ascension/ascension/corelib/memory.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/memory.hpp Sat May 11 12:12:08 2013 +0900
@@ -21,7 +21,6 @@
2121 #undef max
2222
2323 namespace ascension {
24-
2524 #ifdef ASCENSION_ABANDONED_AT_VERSION_08
2625 // std.auto_ptr for arrays.
2726 template<typename T> class AutoBuffer {
@@ -30,32 +29,32 @@
3029 typedef T element_type;
3130 public:
3231 // constructors
33- explicit AutoBuffer(element_type* p = nullptr) /*throw()*/ : buffer_(p) {}
34- AutoBuffer(AutoBuffer<element_type>& other) /*throw()*/ : buffer_(other.release()) {}
32+ explicit AutoBuffer(element_type* p = nullptr) BOOST_NOEXCEPT : buffer_(p) {}
33+ AutoBuffer(AutoBuffer<element_type>& other) BOOST_NOEXCEPT : buffer_(other.release()) {}
3534 template<typename Other>
36- AutoBuffer(AutoBuffer<Other>& other) /*throw()*/ : buffer_(other.release()) {}
35+ AutoBuffer(AutoBuffer<Other>& other) BOOST_NOEXCEPT : buffer_(other.release()) {}
3736 /// Destructor deallocates the buffer by using @c #reset.
38- ~AutoBuffer() /*throw()*/ {delete[] buffer_;}
37+ ~AutoBuffer() BOOST_NOEXCEPT {delete[] buffer_;}
3938 /// Assignment operator.
40- AutoBuffer& operator=(AutoBuffer& other) /*throw()*/ {
39+ AutoBuffer& operator=(AutoBuffer& other) BOOST_NOEXCEPT {
4140 reset(other.release());
4241 return *this;
4342 }
4443 /// Assignment operator.
4544 template<typename Other>
46- AutoBuffer& operator=(AutoBuffer<Other>& other) /*throw()*/ {
45+ AutoBuffer& operator=(AutoBuffer<Other>& other) BOOST_NOEXCEPT {
4746 reset(other.release());
4847 return *this;
4948 }
50- element_type& operator[](std::ptrdiff_t i) const /*throw()*/ {return buffer_[i];}
49+ element_type& operator[](std::ptrdiff_t i) const BOOST_NOEXCEPT {return buffer_[i];}
5150 /// Returns the pointer to the buffer or @c null.
52- element_type* get() const /*throw()*/ {return buffer_;}
51+ element_type* get() const BOOST_NOEXCEPT {return buffer_;}
5352 /**
5453 * Sets the internal pointer to @c null without deallocation the buffer currently pointed
5554 * by @c AutoBuffer.
5655 * @retval A pointer to the buffer pointed by @c AutoBuffer before.
5756 */
58- element_type* release() /*throw()*/ {
57+ element_type* release() BOOST_NOEXCEPT {
5958 element_type* const temp = buffer_;
6059 buffer_ = nullptr;
6160 return temp;
@@ -68,7 +67,7 @@
6867 */
6968 void reset(element_type* p = nullptr) {if(p != buffer_) {delete[] buffer_; buffer_ = p;}}
7069 /// Swaps two @c AutoBuffer objects.
71- void swap(AutoBuffer<element_type>& other) /*throw()*/ {std::swap(buffer_, other.buffer_);}
70+ void swap(AutoBuffer<element_type>& other) BOOST_NOEXCEPT {std::swap(buffer_, other.buffer_);}
7271 private:
7372 element_type* buffer_;
7473 };
@@ -81,8 +80,8 @@
8180 class MemoryPool {
8281 ASCENSION_NONCOPYABLE_TAG(MemoryPool);
8382 public:
84- MemoryPool(std::size_t chunkSize) /*throw()*/ : chunkSize_(std::max(chunkSize, sizeof(Chunk))), chunks_(nullptr) {}
85- ~MemoryPool() /*throw()*/ {release();}
83+ MemoryPool(std::size_t chunkSize) BOOST_NOEXCEPT : chunkSize_(std::max(chunkSize, sizeof(Chunk))), chunks_(nullptr) {}
84+ ~MemoryPool() BOOST_NOEXCEPT {release();}
8685 void* allocate() {
8786 if(void* const chunk = allocate(std::nothrow))
8887 return chunk;
@@ -97,20 +96,20 @@
9796 }
9897 return nullptr;
9998 }
100- void deallocate(void* doomed) /*throw()*/ {
99+ void deallocate(void* doomed) BOOST_NOEXCEPT {
101100 if(Chunk* p = static_cast<Chunk*>(doomed)) {
102101 p->next = chunks_;
103102 chunks_ = p;
104103 }
105104 }
106- void release() /*throw()*/ {
105+ void release() BOOST_NOEXCEPT {
107106 for(Chunk* next = chunks_; next != nullptr; next = chunks_) {
108107 chunks_ = chunks_->next;
109108 ::operator delete(next);
110109 }
111110 }
112111 private:
113- void expandChunks() /*throw()*/ {
112+ void expandChunks() BOOST_NOEXCEPT {
114113 assert(chunks_ == nullptr);
115114 Chunk* p = static_cast<Chunk*>(::operator new(chunkSize_, std::nothrow));
116115 if(p == nullptr)
@@ -155,15 +154,15 @@
155154 return p;
156155 throw std::bad_alloc();
157156 }
158- static void* operator new(std::size_t, const std::nothrow_t&) /*throw()*/ {
157+ static void* operator new(std::size_t, const std::nothrow_t&) BOOST_NOEXCEPT {
159158 if(pool_.get() == nullptr)
160159 pool_.reset(new(std::nothrow) MemoryPool(sizeof(T)));
161160 return (pool_.get() != nullptr) ? pool_->allocate(std::nothrow) : nullptr;
162161 }
163- static void* operator new(std::size_t bytes, void* where) /*throw()*/ {return ::operator new(bytes, where);}
164- static void operator delete(void* p) /*throw()*/ {if(pool_.get() != nullptr) pool_->deallocate(p);}
165- static void operator delete(void* p, const std::nothrow_t&) /*throw()*/ {return operator delete(p);}
166- static void operator delete(void* p, void* where) /*throw()*/ {return ::operator delete(p, where);}
162+ static void* operator new(std::size_t bytes, void* where) BOOST_NOEXCEPT {return ::operator new(bytes, where);}
163+ static void operator delete(void* p) BOOST_NOEXCEPT {if(pool_.get() != nullptr) pool_->deallocate(p);}
164+ static void operator delete(void* p, const std::nothrow_t&) BOOST_NOEXCEPT {return operator delete(p);}
165+ static void operator delete(void* p, void* where) BOOST_NOEXCEPT {return ::operator delete(p, where);}
167166 private:
168167 static std::unique_ptr<MemoryPool> pool_;
169168 };
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/regex.hpp
--- a/ascension/ascension/corelib/regex.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/regex.hpp Sat May 11 12:12:08 2013 +0900
@@ -2,7 +2,7 @@
22 * @file regex.hpp
33 * Defines wrappers of Boost.Regex library or std#tr1#regex.
44 * @author exeal
5- * @date 2006-2012
5+ * @date 2006-2013
66 */
77
88 #include <ascension/config.hpp> // ASCENSION_NO_REGEX, ASCENSION_NO_MIGEMO
@@ -49,7 +49,6 @@
4949 * This uses Boost.Regex to implement internally.
5050 */
5151 namespace regex {
52-
5352 /**
5453 * The result of a match operation.
5554 * <p>This interface contains query methods used to determine the results of a match
@@ -65,7 +64,7 @@
6564 class MatchResult {
6665 public:
6766 /// Destructor.
68- virtual ~MatchResult() /*throw()*/ {}
67+ virtual ~MatchResult() BOOST_NOEXCEPT {}
6968 /**
7069 * Returns the position after the last character matched.
7170 * @return The position after the last character matched
@@ -135,8 +134,8 @@
135134 const CodePointIterator& start() const {return start(0);}
136135 const CodePointIterator& start(int group) const {return get(group).first;}
137136 protected:
138- boost::match_results<CodePointIterator>& impl() /*throw()*/ {return impl_;}
139- const boost::match_results<CodePointIterator>& impl() const /*throw()*/ {return impl_;}
137+ boost::match_results<CodePointIterator>& impl() BOOST_NOEXCEPT {return impl_;}
138+ const boost::match_results<CodePointIterator>& impl() const BOOST_NOEXCEPT {return impl_;}
140139 private:
141140 const boost::sub_match<CodePointIterator>& get(int group) const {
142141 const boost::sub_match<CodePointIterator>& s = impl_[group];
@@ -223,7 +222,6 @@
223222 } // namespace detail
224223
225224 namespace regex {
226-
227225 /// Unchecked exception thrown to indicate a syntax error in a regular-expression pattern.
228226 class PatternSyntaxException : public std::invalid_argument {
229227 ASCENSION_UNASSIGNABLE_TAG(PatternSyntaxException);
@@ -257,7 +255,7 @@
257255 /// Retrieves the error index.
258256 std::ptrdiff_t getIndex() const {return impl_.position();}
259257 /// Retrieves the erroneous regular-expression pattern.
260- String getPattern() const /*throw()*/ {return pattern_;}
258+ String getPattern() const BOOST_NOEXCEPT {return pattern_;}
261259 private:
262260 const boost::regex_error impl_;
263261 const String pattern_;
@@ -280,13 +278,13 @@
280278 CANON_EQ = 0x80 ///< Enables canonical equivalence (not implemented).
281279 };
282280 public:
283- virtual ~Pattern() /*throw()*/;
281+ virtual ~Pattern() BOOST_NOEXCEPT;
284282
285283 /**
286284 * Returns this pattern's match flags.
287285 * @return The match flags specified when this pattern was compiled
288286 */
289- int flags() const /*throw()*/ {return flags_;}
287+ int flags() const BOOST_NOEXCEPT {return flags_;}
290288 /**
291289 * Returns the regular expression from which this pattern was compiled.
292290 * @return The source of this pattern
@@ -373,7 +371,7 @@
373371 * Returns the pattern that is interpreted by this matcher.
374372 * @return The pattern for which this matcher was created
375373 */
376- const Pattern& pattern() const /*throw()*/ {return *pattern_;}
374+ const Pattern& pattern() const BOOST_NOEXCEPT {return *pattern_;}
377375 /**
378376 * Changes the @c Pattern that this @c Matcher uses to find matches with.
379377 * This method causes this matcher to lose information about the groups of the last
@@ -414,14 +412,14 @@
414412 * and @c regionEnd (exclusive).
415413 * @return The ending point of this matcher's region
416414 */
417- const CodePointIterator& regionEnd() const /*throw()*/ {return region_.second;}
415+ const CodePointIterator& regionEnd() const BOOST_NOEXCEPT {return region_.second;}
418416 /**
419417 * Reports the start index of this matcher's region. The searches this matcher conducts
420418 * are limited to finding matches within @c regionStart (inclusive) and @c regionEnd
421419 * (exclusive).
422420 * @return The starting point of this matcher's region
423421 */
424- const CodePointIterator& regionStart() const /*throw()*/ {return region_.first;}
422+ const CodePointIterator& regionStart() const BOOST_NOEXCEPT {return region_.first;}
425423
426424 /**
427425 * Queries the anchoring of region bounds for this matcher.
@@ -432,7 +430,7 @@
432430 * @return true if this matcher is using anchoring bounds, false otherwise
433431 * @see useAnchoringBounds
434432 */
435- bool hasAnchoringBounds() const /*throw()*/ {return usesAnchoringBounds_;}
433+ bool hasAnchoringBounds() const BOOST_NOEXCEPT {return usesAnchoringBounds_;}
436434 /**
437435 * Queries the transparency of region bounds for this matcher.
438436 * @par This method returns @c true if this matcher uses <em>transparent</em> bounds,
@@ -442,7 +440,7 @@
442440 * @return true if this matcher is using transparent bounds, false otherwise
443441 * @see useTransparentBounds
444442 */
445- bool hasTransparentBounds() const /*throw()*/ {return usesTransparentBounds_;}
443+ bool hasTransparentBounds() const BOOST_NOEXCEPT {return usesTransparentBounds_;}
446444 /**
447445 * Sets the anchoring of region bounds for this matcher.
448446 * @par Invoking this method with an argument of @c true will set this matcher to use
@@ -457,7 +455,7 @@
457455 * @return This matcher
458456 * @see hasAnchoringBounds
459457 */
460- Matcher& useAnchoringBounds(bool b) /*throw()*/ {usesAnchoringBounds_ = b; return *this;}
458+ Matcher& useAnchoringBounds(bool b) BOOST_NOEXCEPT {usesAnchoringBounds_ = b; return *this;}
461459 /**
462460 * Sets the transparency of region bounds for this matcher.
463461 * @par Invoking this method with an argument of @c true will set this matcher to use
@@ -476,7 +474,7 @@
476474 * @return This matcher
477475 * @see hasTransparentBounds
478476 */
479- Matcher& useTransparentBounds(bool b) /*throw()*/ {usesTransparentBounds_ = b; return *this;}
477+ Matcher& useTransparentBounds(bool b) BOOST_NOEXCEPT {usesTransparentBounds_ = b; return *this;}
480478
481479 /**
482480 * Attempts to find the next subsequence of the input sequence that matches the
@@ -707,7 +705,7 @@
707705 throw IllegalStateException("the previous was not performed or failed.");
708706 }
709707 boost::match_flag_type nativeFlags(const CodePointIterator& first,
710- const CodePointIterator& last, bool continuous) const /*throw()*/ {
708+ const CodePointIterator& last, bool continuous) const BOOST_NOEXCEPT {
711709 boost::match_flag_type f(boost::regex_constants::match_default);
712710 if((pattern_->flags() & Pattern::DOTALL) == 0)
713711 f |= boost::regex_constants::match_not_dot_newline;
@@ -742,14 +740,13 @@
742740 public:
743741 static std::unique_ptr<const MigemoPattern> compile(const StringPiece& pattern, bool caseSensitive);
744742 static void initialize(const std::string& runtimePathName, const std::string& dictionaryPathName);
745- static bool isMigemoInstalled() /*throw()*/;
743+ static bool isMigemoInstalled() BOOST_NOEXCEPT;
746744 private:
747745 MigemoPattern(const StringPiece& pattern, bool caseSensitive);
748746 static void install();
749747 static std::string runtimePathName_, dictionaryPathName_;
750748 };
751749 #endif // !ASCENSION_NO_MIGEMO
752-
753750 }
754751 } // namespace ascension.regex
755752
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/shared-library.hpp
--- a/ascension/ascension/corelib/shared-library.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/shared-library.hpp Sat May 11 12:12:08 2013 +0900
@@ -38,7 +38,7 @@
3838 #endif
3939 std::fill(procedures_, procedures_ + ProcedureEntries::NUMBER_OF_ENTRIES, reinterpret_cast<NativeProcedure>(1));
4040 }
41- ~SharedLibrary() /*throw()*/ {
41+ ~SharedLibrary() BOOST_NOEXCEPT {
4242 #ifdef ASCENSION_OS_WINDOWS
4343 ::FreeLibrary(library_);
4444 #else
@@ -46,7 +46,7 @@
4646 #endif
4747 }
4848 template<std::size_t index>
49- typename ProcedureEntries::template Procedure<index>::signature get() const /*throw()*/ {
49+ typename ProcedureEntries::template Procedure<index>::signature get() const BOOST_NOEXCEPT {
5050 typedef typename ProcedureEntries::template Procedure<index> Procedure;
5151 if(procedures_[index] == reinterpret_cast<NativeProcedure>(1))
5252 procedures_[index] =
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/text/character-property.hpp
--- a/ascension/ascension/corelib/text/character-property.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/text/character-property.hpp Sat May 11 12:12:08 2013 +0900
@@ -18,13 +18,11 @@
1818
1919 namespace ascension {
2020 namespace text {
21-
2221 /**
2322 * Implements <a href="http://www.unicode.org/Public/UNIDATA/UCD.html">UCD (Unicode
2423 * Character Database)</a>.
2524 */
2625 namespace ucd {
27-
2826 /**
2927 * A function object compares Unicode property (value) names based on "Property and
3028 * Property Value Matching"
@@ -137,7 +135,7 @@
137135 static const char LONG_NAME[], SHORT_NAME[];
138136 template<typename CharType> static int forName(const CharType* name);
139137 template<int superCategory> static bool is(int subCategory);
140- static int of(CodePoint c) /*throw()*/;
138+ static int of(CodePoint c) BOOST_NOEXCEPT;
141139 private:
142140 static const detail::CharacterPropertyPartition VALUES_[];
143141 static const std::size_t NUMBER_;
@@ -157,7 +155,7 @@
157155 static const int DEFAULT_VALUE;
158156 static const char LONG_NAME[], SHORT_NAME[];
159157 template<typename CharType> static int forName(const CharType* name);
160- static int of(CodePoint c) /*throw()*/;
158+ static int of(CodePoint c) BOOST_NOEXCEPT;
161159 private:
162160 static const detail::CharacterPropertyPartition VALUES_[];
163161 static const std::size_t NUMBER_;
@@ -202,7 +200,7 @@
202200 static const int DEFAULT_VALUE;
203201 static const char LONG_NAME[], SHORT_NAME[];
204202 template<typename CharType> static int forName(const CharType* name);
205- static int of(CodePoint cp) /*throw()*/;
203+ static int of(CodePoint cp) BOOST_NOEXCEPT;
206204 private:
207205 static const CodePoint CHARACTERS_[];
208206 static const std::uint8_t VALUES_[];
@@ -242,7 +240,7 @@
242240 static const int DEFAULT_VALUE;
243241 static const char LONG_NAME[], SHORT_NAME[];
244242 template<typename CharType> static int forName(const CharType* name);
245- static int of(CodePoint c) /*throw()*/;
243+ static int of(CodePoint c) BOOST_NOEXCEPT;
246244 private:
247245 static const detail::CharacterPropertyPartition VALUES_[];
248246 static const std::size_t NUMBER_;
@@ -268,7 +266,7 @@
268266 static const int DEFAULT_VALUE;
269267 static const char LONG_NAME[], SHORT_NAME[];
270268 template<typename CharType> static int forName(const CharType* name);
271- static int of(CodePoint cp) /*throw()*/;
269+ static int of(CodePoint cp) BOOST_NOEXCEPT;
272270 private:
273271 static const detail::CharacterPropertyValueName NAMES_[];
274272 };
@@ -297,7 +295,7 @@
297295 template<typename CharType> static int forName(const CharType* name);
298296 static bool is(CodePoint cp, int property);
299297 template<int property>
300- static bool is(CodePoint cp) /*throw()*/;
298+ static bool is(CodePoint cp) BOOST_NOEXCEPT;
301299 private:
302300 static const detail::CharacterPropertyValueName NAMES_[];
303301 #include "src/generated/uprops-binary-property-values-definition"
@@ -319,7 +317,7 @@
319317 static const int DEFAULT_VALUE;
320318 static const char LONG_NAME[], SHORT_NAME[];
321319 template<typename CharType> static int forName(const CharType* name);
322- static int of(CodePoint c) /*throw()*/;
320+ static int of(CodePoint c) BOOST_NOEXCEPT;
323321 private:
324322 static const detail::CharacterPropertyPartition VALUES_[];
325323 static const std::size_t NUMBER_;
@@ -381,7 +379,7 @@
381379 static const int DEFAULT_VALUE;
382380 static const char LONG_NAME[], SHORT_NAME[];
383381 template<typename CharType> static int forName(const CharType* name);
384- static int of(CodePoint c) /*throw()*/;
382+ static int of(CodePoint c) BOOST_NOEXCEPT;
385383 private:
386384 static const detail::CharacterPropertyPartition VALUES_[];
387385 static const std::size_t NUMBER_;
@@ -400,7 +398,7 @@
400398 };
401399 static const int DEFAULT_VALUE;
402400 static const char LONG_NAME[], SHORT_NAME[];
403- static int of(CodePoint cp) /*throw()*/;
401+ static int of(CodePoint cp) BOOST_NOEXCEPT;
404402 private:
405403 static const detail::CharacterPropertyValueName NAMES_[];
406404 };
@@ -417,7 +415,7 @@
417415 static const char LONG_NAME[], SHORT_NAME[];
418416 static int of(CodePoint cp,
419417 const IdentifierSyntax& syntax = IdentifierSyntax(IdentifierSyntax::UNICODE_DEFAULT),
420- const std::locale& lc = std::locale::classic()) /*throw()*/;
418+ const std::locale& lc = std::locale::classic()) BOOST_NOEXCEPT;
421419 private:
422420 static const detail::CharacterPropertyValueName NAMES_[];
423421 };
@@ -432,7 +430,7 @@
432430 };
433431 static const int DEFAULT_VALUE;
434432 static const char LONG_NAME[], SHORT_NAME[];
435- static int of(CodePoint cp) /*throw()*/;
433+ static int of(CodePoint cp) BOOST_NOEXCEPT;
436434 private:
437435 static const detail::CharacterPropertyValueName NAMES_[];
438436 };
@@ -581,7 +579,7 @@
581579 return GeneralCategory::of(cp) == GeneralCategory::UPPERCASE_LETTER || is<OTHER_UPPERCASE>(cp);}
582580
583581 /// Returns the Hangul_Syllable_Type property value of @a cp.
584-inline int HangulSyllableType::of(CodePoint c) /*throw()*/ {
582+inline int HangulSyllableType::of(CodePoint c) BOOST_NOEXCEPT {
585583 if((c >= 0x1100u && c <= 0x1159u) || c == 0x115fu)
586584 return LEADING_JAMO;
587585 else if(c >= 0x1160u && c <= 0x11a2u)
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/text/identifier-syntax.hpp
--- a/ascension/ascension/corelib/text/identifier-syntax.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/text/identifier-syntax.hpp Sat May 11 12:12:08 2013 +0900
@@ -18,9 +18,7 @@
1818 #endif
1919
2020 namespace ascension {
21-
2221 namespace text {
23-
2422 class IdentifierSyntax {
2523 public:
2624 /// Types of character classification used by @c IdentifierSyntax.
@@ -34,23 +32,30 @@
3432 /// Conforms to the alternative identifier syntax of UAX #31.
3533 UNICODE_ALTERNATIVE
3634 };
37- // constructors
38- IdentifierSyntax() /*throw()*/;
35+ public:
36+ IdentifierSyntax() BOOST_NOEXCEPT;
3937 explicit IdentifierSyntax(CharacterClassification type, bool ignoreCase = false
4038 #ifndef ASCENSION_NO_UNICODE_NORMALIZATION
4139 , Decomposition equivalenceType = NO_DECOMPOSITION
4240 #endif // !ASCENSION_NO_UNICODE_NORMALIZATION
43- ) /*throw()*/;
44- IdentifierSyntax(const IdentifierSyntax& other) /*throw()*/;
45- IdentifierSyntax& operator=(const IdentifierSyntax& other) /*throw()*/;
46- // singleton
47- static const IdentifierSyntax& defaultInstance() /*throw()*/;
48- // classification for character
49- bool isIdentifierStartCharacter(CodePoint c) const /*throw()*/;
50- bool isIdentifierContinueCharacter(CodePoint c) const /*throw()*/;
51- bool isWhiteSpace(CodePoint c, bool includeTab) const /*throw()*/;
41+ ) BOOST_NOEXCEPT;
42+ IdentifierSyntax(const IdentifierSyntax& other) BOOST_NOEXCEPT;
43+ IdentifierSyntax& operator=(const IdentifierSyntax& other) BOOST_NOEXCEPT;
5244
53- // classification for sequence
45+ /// @name Singleton
46+ /// @{
47+ static const IdentifierSyntax& defaultInstance() BOOST_NOEXCEPT;
48+ /// @}
49+
50+ /// @name Classification for Character
51+ /// @{
52+ bool isIdentifierStartCharacter(CodePoint c) const BOOST_NOEXCEPT;
53+ bool isIdentifierContinueCharacter(CodePoint c) const BOOST_NOEXCEPT;
54+ bool isWhiteSpace(CodePoint c, bool includeTab) const BOOST_NOEXCEPT;
55+ /// @}
56+
57+ /// @name Classification for Sequence
58+ /// @{
5459 /**
5560 * Checks whether the specified character sequence starts with an identifier.
5661 * The type @a CharacterSequence the bidirectional iterator expresses a UTF-n
@@ -90,8 +95,10 @@
9095 ++i;
9196 return i.tell();
9297 }
98+ /// @}
9399
94- // attributes
100+ /// @name Syntax Overrides
101+ /// @{
95102 void overrideIdentifierStartCharacters(
96103 const String& adding, const String& subtracting);
97104 void overrideIdentifierStartCharacters(
@@ -100,6 +107,8 @@
100107 const String& adding, const String& subtracting);
101108 void overrideIdentifierNonStartCharacters(
102109 const std::set<CodePoint>& adding, const std::set<CodePoint>& subtracting);
110+ /// @}
111+
103112 private:
104113 CharacterClassification type_;
105114 bool caseSensitive_;
@@ -110,7 +119,6 @@
110119 addedIDStartCharacters_, addedIDNonStartCharacters_,
111120 subtractedIDStartCharacters_, subtractedIDNonStartCharacters_;
112121 };
113-
114122 }
115123 } // namespace ascension.text
116124
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/text/utf-iterator.hpp
--- a/ascension/ascension/corelib/text/utf-iterator.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/text/utf-iterator.hpp Sat May 11 12:12:08 2013 +0900
@@ -69,11 +69,11 @@
6969 return *this;
7070 }
7171 /// Returns beginning of the range this iterator can address.
72- const BaseIterator& first() const /*noexcept*/ {return first_;}
72+ const BaseIterator& first() const BOOST_NOEXCEPT {return first_;}
7373 /// Returns end of the range this iterator can address.
74- const BaseIterator& last() const /*noexcept*/ {return first_;}
74+ const BaseIterator& last() const BOOST_NOEXCEPT {return first_;}
7575 /// Sets if this iterator replaces the ill-formed code unit (sub)sequence.
76- CharacterDecodeIterator& replaceMalformedInput(bool replace) /*noexcept*/ {
76+ CharacterDecodeIterator& replaceMalformedInput(bool replace) BOOST_NOEXCEPT {
7777 replacesMalformedInput_ = replace;
7878 return *this;
7979 }
@@ -81,7 +81,7 @@
8181 * Returns @c true if this iterator replaces the ill-formed code unit
8282 * (sub)sequence. The default value is @c false.
8383 */
84- bool replacesMalformedInput() const /*noexcept*/ {return replacesMalformedInput_;}
84+ bool replacesMalformedInput() const BOOST_NOEXCEPT {return replacesMalformedInput_;}
8585 /// Returns the current position.
8686 BaseIterator tell() const {return base_;}
8787 private:
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/text/utf.hpp
--- a/ascension/ascension/corelib/text/utf.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/text/utf.hpp Sat May 11 12:12:08 2013 +0900
@@ -23,7 +23,6 @@
2323 #endif
2424
2525 namespace ascension {
26-
2726 namespace detail {
2827 /*
2928 UTF-8 code unit value distribution (based on Unicode 6.0 Table 3.7)
@@ -169,9 +168,8 @@
169168
170169 namespace text {
171170 namespace utf {
172-
173- // common trivials ////////////////////////////////////////////////////////////////////
174-
171+ /// @defgroup utf_common_trivials UTF Common Trivial Functions
172+ /// @{
175173 /**
176174 * Returns the number of bytes in
177175 * @tparam codeUnitSize The size of the code unit. Either 1, 2 or 4
@@ -206,9 +204,10 @@
206204 else
207205 return 1;
208206 }
207+ /// @}
209208
210- // UTF-8 trivials /////////////////////////////////////////////////////////////////////
211-
209+ /// @defgroup utf8_trivials UTF-8 Trivial Functions
210+ /// @{
212211 /**
213212 * Returns @c true if the given code unit is UTF-8 valid byte (which can be any
214213 * component of valid UTF-8 byte sequence).
@@ -236,7 +235,7 @@
236235 * @param byte The code unit to test
237236 * @return true if @a byte is leading byte
238237 */
239- inline bool isLeadingByte(std::uint8_t byte) /*throw()*/ {
238+ inline bool isLeadingByte(std::uint8_t byte) BOOST_NOEXCEPT {
240239 return (detail::UTF8_CODE_UNIT_VALUES[byte] & 0xf0) != 0;
241240 }
242241
@@ -257,9 +256,10 @@
257256 inline std::size_t numberOfTrailingBytes(std::uint8_t leadingByte) {
258257 return length(leadingByte) - 1;
259258 }
259+ /// @}
260260
261- // UTF-8 //////////////////////////////////////////////////////////////////////////////
262-
261+ /// @defgroup utf8_encode_decode UTF-8 Encoding and Decoding
262+ /// @{
263263 /**
264264 * Converts the first character in the given UTF-8 code unit sequence to the
265265 * corresponding code point.
@@ -324,9 +324,10 @@
324324 typename std::enable_if<CodeUnitSizeOf<OutputIterator>::value == 1>::type* = nullptr) {
325325 return detail::encodeUTF8<true>(c, out);
326326 }
327+ /// @}
327328
328- // UTF-16 /////////////////////////////////////////////////////////////////////////////
329-
329+ /// @defgroup utf16_encode_decode UTF-16 Encoding and Decoding
330+ /// @{
330331 /**
331332 * Converts the first character in the given UTF-16 code unit sequence to the
332333 * corresponding code point.
@@ -451,9 +452,10 @@
451452 typename std::enable_if<CodeUnitSizeOf<OutputIterator>::value == 2>::type* = nullptr) {
452453 return detail::encodeUTF16<true>(c, out);
453454 }
455+ /// @}
454456
455- // UTF-32 /////////////////////////////////////////////////////////////////////////////
456-
457+ /// @defgroup utf32_encode_decode UTF-32 Encoding and Decoding
458+ /// @{
457459 /**
458460 * Converts the first character in the given UTF-32 code unit sequence to the
459461 * corresponding code point.
@@ -559,9 +561,8 @@
559561 throw InvalidScalarValueException(c);
560562 return encode(c, out);
561563 }
562-
564+ /// @}
563565 }
564-
565566 }
566567 }
567568
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/corelib/timer.hpp
--- a/ascension/ascension/corelib/timer.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/corelib/timer.hpp Sat May 11 12:12:08 2013 +0900
@@ -46,7 +46,7 @@
4646 return identifier_;
4747 }
4848 /// Returns @c true if this timer is running.
49- bool isActive() const /*throw()*/ {return object_ != nullptr;}
49+ bool isActive() const BOOST_NOEXCEPT {return object_ != nullptr;}
5050 /**
5151 * Starts or restarts this timer.
5252 * @param milliseconds The interval in milliseconds
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/graphics/color.hpp
--- a/ascension/ascension/graphics/color.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/graphics/color.hpp Sat May 11 12:12:08 2013 +0900
@@ -17,7 +17,6 @@
1717
1818 namespace ascension {
1919 namespace graphics {
20-
2120 /**
2221 * @c Color provides colors based on RGB values.
2322 * @see "CSS Color Module Level 3" (http://www.w3.org/TR/css3-color/)
@@ -27,28 +26,28 @@
2726 static const Color TRANSPARENT_BLACK;
2827 public:
2928 /// Creates a color value based on RGB values.
30- Color(Byte red, Byte green, Byte blue, Byte alpha = 255) /*noexcept*/
29+ Color(Byte red, Byte green, Byte blue, Byte alpha = 255) BOOST_NOEXCEPT
3130 : red_(red * 0x0101), green_(green * 0x0101), blue_(blue * 0x0101), alpha_(alpha * 0x0101) {}
3231 /// Converts into a native value.
3332 template<typename NativeType> NativeType as() const;
3433 /// Creates a @c Color object from native value.
35- template<typename NativeType> static Color from(const NativeType& value) /*noexcept*/;
34+ template<typename NativeType> static Color from(const NativeType& value) BOOST_NOEXCEPT;
3635 /// Returns the blue color component of this color.
37- Byte blue() const /*noexcept*/ {return blue_ >> 8;}
36+ Byte blue() const BOOST_NOEXCEPT {return blue_ >> 8;}
3837 /// Returns the green color component of this color.
39- Byte green() const /*noexcept*/ {return green_ >> 8;}
38+ Byte green() const BOOST_NOEXCEPT {return green_ >> 8;}
4039 /// Returns the red color component of this color.
41- Byte red() const /*noexcept*/ {return red_ >> 8;}
40+ Byte red() const BOOST_NOEXCEPT {return red_ >> 8;}
4241 /// Returns the alpha value of this color.
43- Byte alpha() const /*noexcept*/ {return alpha_ >> 8;}
42+ Byte alpha() const BOOST_NOEXCEPT {return alpha_ >> 8;}
4443 /// Returns @c true if this color is fully opaque.
45- bool isFullyOpaque() const /*noexcept*/ {return alpha() == 255;}
44+ bool isFullyOpaque() const BOOST_NOEXCEPT {return alpha() == 255;}
4645 /// Returns @c true if this color is fully transparent.
47- bool isFullyTransparent() const /*noexcept*/ {return alpha() == 0;}
46+ bool isFullyTransparent() const BOOST_NOEXCEPT {return alpha() == 0;}
4847 /// Returns @c true if this color is transparent.
49- bool isTransparent() const /*noexcept*/ {return !isFullyOpaque();}
48+ bool isTransparent() const BOOST_NOEXCEPT {return !isFullyOpaque();}
5049 /// Equality operator.
51- bool operator==(const Color& other) const /*noexcept*/ {
50+ bool operator==(const Color& other) const BOOST_NOEXCEPT {
5251 return red() == other.red() && green() == other.green()
5352 && blue() == other.blue() && alpha() == other.alpha();
5453 }
@@ -72,13 +71,13 @@
7271 temp.rgbReserved = alpha();
7372 return temp;
7473 }
75- template<> inline Color Color::from<COLORREF>(const COLORREF& value) /*noexcept*/ {
74+ template<> inline Color Color::from<COLORREF>(const COLORREF& value) BOOST_NOEXCEPT {
7675 return Color(
7776 static_cast<Byte>(value & 0xff),
7877 static_cast<Byte>((value >> 8) & 0xff),
7978 static_cast<Byte>((value >> 16) & 0xff));
8079 }
81- template<> inline Color Color::from<RGBQUAD>(const RGBQUAD& value) /*noexcept*/ {
80+ template<> inline Color Color::from<RGBQUAD>(const RGBQUAD& value) BOOST_NOEXCEPT {
8281 return Color(value.rgbRed, value.rgbGreen, value.rgbBlue, value.rgbReserved);
8382 }
8483 #elif defined(ASCENSION_GRAPHICS_SYSTEM_WIN32_GDIPLUS)
@@ -123,7 +122,6 @@
123122 };
124123 static Color get(Value value);
125124 };
126-
127125 }
128126 }
129127
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/graphics/font/font-family.hpp
--- a/ascension/ascension/graphics/font/font-family.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/graphics/font/font-family.hpp Sat May 11 12:12:08 2013 +0900
@@ -92,8 +92,8 @@
9292 explicit FontFamily(std::unique_ptr<Gdiplus::FontFamily>&& nativeObject);
9393 explicit FontFamily(std::shared_ptr<Gdiplus::FontFamily> nativeObject);
9494 explicit FontFamily(Gdiplus::FontFamily& nativeObject); // weak ref.
95- std::shared_ptr<Gdiplus::FontFamily> asNativeObject() /*noexcept*/;
96- std::shared_ptr<const Gdiplus::FontFamily> asNativeObject() const /*noexcept*/;
95+ std::shared_ptr<Gdiplus::FontFamily> asNativeObject() BOOST_NOEXCEPT;
96+ std::shared_ptr<const Gdiplus::FontFamily> asNativeObject() const BOOST_NOEXCEPT;
9797 #else
9898 /**
9999 * Constructor takes a family name.
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/graphics/font/line-layout-vector.hpp
--- a/ascension/ascension/graphics/font/line-layout-vector.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/graphics/font/line-layout-vector.hpp Sat May 11 12:12:08 2013 +0900
@@ -127,7 +127,7 @@
127127 ASCENSION_NONCOPYABLE_TAG(NumberedLayout);
128128 };
129129 void clearCaches(const boost::integer_range<Index>& lines, bool repair);
130- void deleteLineLayout(Index line, TextLayout* newLayout = nullptr) /*throw()*/;
130+ void deleteLineLayout(Index line, TextLayout* newLayout = nullptr) BOOST_NOEXCEPT;
131131 void fireVisualLinesDeleted(const boost::integer_range<Index>& lines, Index sublines);
132132 void fireVisualLinesInserted(const boost::integer_range<Index>& lines);
133133 void fireVisualLinesModified(const boost::integer_range<Index>& lines,
@@ -143,7 +143,7 @@
143143 void documentPartitioningChanged(const kernel::Region& changedRegion);
144144 private:
145145 struct GeneratorBase {
146- virtual ~GeneratorBase() /*throw()*/ {}
146+ virtual ~GeneratorBase() BOOST_NOEXCEPT {}
147147 virtual std::unique_ptr<const TextLayout> generate(Index line) const = 0;
148148 };
149149 template<typename Function>
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/graphics/font/text-layout.hpp
--- a/ascension/ascension/graphics/font/text-layout.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/graphics/font/text-layout.hpp Sat May 11 12:12:08 2013 +0900
@@ -147,7 +147,7 @@
147147 std::uint8_t characterLevel(Index offset) const;
148148 bool isBidirectional() const BOOST_NOEXCEPT;
149149 Index numberOfCharacters() const BOOST_NOEXCEPT;
150- const presentation::TextLineStyle& style() const /*throw()*/;
150+ const presentation::TextLineStyle& style() const BOOST_NOEXCEPT;
151151 const presentation::WritingMode& writingMode() const BOOST_NOEXCEPT;
152152 /// @}
153153
@@ -224,7 +224,7 @@
224224 void draw(PaintContext& context, const Point& origin,
225225 const TextPaintOverride* paintOverride = nullptr,
226226 const InlineObject* endOfLine = nullptr,
227- const InlineObject* lineWrappingMark = nullptr) const /*throw()*/;
227+ const InlineObject* lineWrappingMark = nullptr) const BOOST_NOEXCEPT;
228228 /// @}
229229
230230 /// @name Miscellaneous
@@ -242,21 +242,21 @@
242242 TextHit<>&& internalHitTestCharacter(const presentation::AbstractTwoAxes<Scalar>& point,
243243 const presentation::FlowRelativeFourSides<Scalar>* bounds, bool* outOfBounds) const;
244244 // void buildLineMetrics(Index line);
245- void expandTabsWithoutWrapping() /*throw()*/;
245+ void expandTabsWithoutWrapping() BOOST_NOEXCEPT;
246246 typedef std::vector<std::unique_ptr<const TextRun>> RunVector;
247- RunVector::const_iterator runForPosition(Index offset) const /*throw()*/;
247+ RunVector::const_iterator runForPosition(Index offset) const BOOST_NOEXCEPT;
248248 boost::iterator_range<RunVector::const_iterator> runsForLine(Index line) const;
249249 RunVector::const_iterator firstRunInLine(Index line) const BOOST_NOEXCEPT;
250250 bool isEmpty() const BOOST_NOEXCEPT {return runs_.empty();}
251- void justify(Scalar lineMeasure, presentation::TextJustification method) /*throw()*/;
251+ void justify(Scalar lineMeasure, presentation::TextJustification method) BOOST_NOEXCEPT;
252252 Point lineLeft(Index line) const;
253253 typedef std::tuple<Scalar, Scalar, Scalar/*, Scalar*/> LineMetrics; // ascent, descent, leading/*, advance*/
254254 #ifdef ASCENSION_ABANDONED_AT_VERSION_08
255255 const LineMetrics& lineMetrics(Index line) const;
256256 #endif // ASCENSION_ABANDONED_AT_VERSION_08
257257 std::pair<Index, Index> locateOffsets(
258- Index line, Scalar ipd, bool& outside) const /*throw()*/;
259- int nextTabStopBasedLeftEdge(Scalar x, bool right) const /*throw()*/;
258+ Index line, Scalar ipd, bool& outside) const BOOST_NOEXCEPT;
259+ int nextTabStopBasedLeftEdge(Scalar x, bool right) const BOOST_NOEXCEPT;
260260 void reorder();
261261 // void rewrap();
262262 void stackLines(
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/graphics/paint.hpp
--- a/ascension/ascension/graphics/paint.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/graphics/paint.hpp Sat May 11 12:12:08 2013 +0900
@@ -89,7 +89,7 @@
8989 class Gradient : public Paint {
9090 public:
9191 /// Destructor.
92- virtual ~Gradient() /*noexcept()*/ {}
92+ virtual ~Gradient() BOOST_NOEXCEPT {}
9393 /**
9494 * Adds a color stop with the given color to the gradient at the given offset.
9595 * @param offset The offset. 0.0 is the offset at one end of the gradient, 1.0 is the
@@ -126,7 +126,7 @@
126126 */
127127 class Pattern : public Paint {
128128 public:
129- virtual ~Pattern() /*throw()*/ {}
129+ virtual ~Pattern() BOOST_NOEXCEPT {}
130130 };
131131
132132 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/graphics/rendering-device.hpp
--- a/ascension/ascension/graphics/rendering-device.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/graphics/rendering-device.hpp Sat May 11 12:12:08 2013 +0900
@@ -19,7 +19,7 @@
1919 class RenderingDevice {
2020 public:
2121 /// Destructor.
22- virtual ~RenderingDevice() /*throw()*/ {}
22+ virtual ~RenderingDevice() BOOST_NOEXCEPT {}
2323
2424 /// Creates and returns the rendering context.
2525 virtual std::unique_ptr<RenderingContext2D> createRenderingContext() const = 0;
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/presentation/presentation-reconstructor.hpp
--- a/ascension/ascension/presentation/presentation-reconstructor.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/presentation/presentation-reconstructor.hpp Sat May 11 12:12:08 2013 +0900
@@ -46,7 +46,7 @@
4646 class SingleStyledPartitionPresentationReconstructor : public PartitionPresentationReconstructor {
4747 ASCENSION_UNASSIGNABLE_TAG(SingleStyledPartitionPresentationReconstructor);
4848 public:
49- explicit SingleStyledPartitionPresentationReconstructor(std::shared_ptr<const TextRunStyle> style) /*noexcept*/;
49+ explicit SingleStyledPartitionPresentationReconstructor(std::shared_ptr<const TextRunStyle> style) BOOST_NOEXCEPT;
5050 private:
5151 // PartitionPresentationReconstructor
5252 std::unique_ptr<StyledTextRunIterator>
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/viewer/caret-observers.hpp
--- a/ascension/ascension/viewer/caret-observers.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/viewer/caret-observers.hpp Sat May 11 12:12:08 2013 +0900
@@ -2,7 +2,7 @@
22 * @file caret-observers.hpp
33 * @author exeal
44 * @date 2011-03-30 separated from caret.hpp
5- * @date 2011-2012
5+ * @date 2011-2013
66 */
77
88 #ifndef ASCENSION_CARET_OBSERVERS_HPP
@@ -86,9 +86,9 @@
8686 * The text viewer's input locale had been changed (ex. @c WM_INPUTLANGCHANGE of
8787 * Win32).
8888 */
89- virtual void inputLocaleChanged() /*throw()*/ = 0;
89+ virtual void inputLocaleChanged() BOOST_NOEXCEPT = 0;
9090 /// The text viewer's input method open status had been changed.
91- virtual void inputMethodOpenStatusChanged() /*throw()*/ = 0;
91+ virtual void inputMethodOpenStatusChanged() BOOST_NOEXCEPT = 0;
9292 friend class Caret;
9393 };
9494 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/viewer/caret.hpp
--- a/ascension/ascension/viewer/caret.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/viewer/caret.hpp Sat May 11 12:12:08 2013 +0900
@@ -166,6 +166,7 @@
166166
167167 private:
168168 void adjustInputMethodCompositionWindow();
169+ bool canPastePlatformData() const;
169170 void checkMatchBrackets();
170171 void fireCaretMoved(const kernel::Region& oldRegion);
171172 void internalExtendSelection(void (*algorithm)(void));
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/viewer/viewer-observers.hpp
--- a/ascension/ascension/viewer/viewer-observers.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/viewer/viewer-observers.hpp Sat May 11 12:12:08 2013 +0900
@@ -69,7 +69,7 @@
6969 class MouseInputStrategy {
7070 public:
7171 /// Destructor.
72- virtual ~MouseInputStrategy() /*throw()*/ {}
72+ virtual ~MouseInputStrategy() BOOST_NOEXCEPT {}
7373 protected:
7474 /// Actions of the mouse input.
7575 enum Action {
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/viewer/widgetapi/drag-and-drop.hpp
--- a/ascension/ascension/viewer/widgetapi/drag-and-drop.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/viewer/widgetapi/drag-and-drop.hpp Sat May 11 12:12:08 2013 +0900
@@ -48,10 +48,10 @@
4848 MouseButtonInput(mouse), possibleActions_(possibleActions),
4949 defaultAction_(resolveDefaultDropAction(possibleActions, mouse.modifiers())), mimeData_(data) {}
5050 void acceptProposedAction();
51- DropAction dropAction() const /*noexcept*/ {return action_;}
52- const NativeMimeData& mimeData() const /*noexcept*/ {return mimeData_;}
53- DropAction possibleActions() const /*noexcept*/ {return possibleActions_;}
54- DropAction proposedAction() const /*noexcept*/ {return defaultAction_;}
51+ DropAction dropAction() const BOOST_NOEXCEPT {return action_;}
52+ const NativeMimeData& mimeData() const BOOST_NOEXCEPT {return mimeData_;}
53+ DropAction possibleActions() const BOOST_NOEXCEPT {return possibleActions_;}
54+ DropAction proposedAction() const BOOST_NOEXCEPT {return defaultAction_;}
5555 void setDropAction(DropAction action);
5656 private:
5757 const DropAction possibleActions_;
@@ -80,7 +80,7 @@
8080 class DropTarget {
8181 public:
8282 /// Destructor.
83- virtual ~DropTarget() /*throw()*/ {}
83+ virtual ~DropTarget() BOOST_NOEXCEPT {}
8484 virtual void dragEntered(DragEnterInput& input) = 0;
8585 virtual void dragLeft(DragLeaveInput& input) = 0;
8686 virtual void dragMoved(DragMoveInput& input) = 0;
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/viewer/widgetapi/widget.hpp
--- a/ascension/ascension/viewer/widgetapi/widget.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/viewer/widgetapi/widget.hpp Sat May 11 12:12:08 2013 +0900
@@ -307,7 +307,7 @@
307307 class WidgetNotInitializedException : public IllegalStateException {
308308 public:
309309 /// Default constructor.
310- WidgetNotInitializedException() /*throw()*/
310+ WidgetNotInitializedException() BOOST_NOEXCEPT
311311 : IllegalStateException("this widget is not initialized.") {}
312312 };
313313
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/win32/com/smart-pointer.hpp
--- a/ascension/ascension/win32/com/smart-pointer.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/win32/com/smart-pointer.hpp Sat May 11 12:12:08 2013 +0900
@@ -23,7 +23,7 @@
2323 private:
2424 STDMETHOD_(ULONG, AddRef)() = 0;
2525 STDMETHOD_(ULONG, Release)() = 0;
26- T** operator &() const /*throw()*/; // prohibits &*p
26+ T** operator &() const BOOST_NOEXCEPT; // prohibits &*p
2727 };
2828
2929 /**
@@ -38,46 +38,46 @@
3838 typedef T element_type; ///< The interface type.
3939 public:
4040 /// Default constructor.
41- SmartPointer() /*noexcept*/ : pointee_(nullptr) {}
41+ SmartPointer() BOOST_NOEXCEPT : pointee_(nullptr) {}
4242 /// Null pointer constructor.
43- SmartPointer(std::nullptr_t) /*noexcept*/ : pointee_(nullptr) {}
43+ SmartPointer(std::nullptr_t) BOOST_NOEXCEPT : pointee_(nullptr) {}
4444 /// Constructor with an interface pointer.
4545 template<typename U>
46- explicit SmartPointer(U* p) /*noexcept*/ : pointee_(nullptr) {
46+ explicit SmartPointer(U* p) BOOST_NOEXCEPT : pointee_(nullptr) {
4747 if(p != nullptr)
4848 p->QueryInterface(__uuidof(element_type), initializePPV());
4949 }
5050 /// Constructor with an interface pointer.
5151 template<typename U>
52- explicit SmartPointer(U* p, const IID& iid) /*noexcept*/ : pointee_(nullptr) {
52+ explicit SmartPointer(U* p, const IID& iid) BOOST_NOEXCEPT : pointee_(nullptr) {
5353 if(p != nullptr)
5454 p->QueryInterface(iid, initializePPV());
5555 }
5656 /// Constructor with an interface pointer.
5757 template<>
58- explicit SmartPointer<element_type>(element_type* p) /*noexcept*/ : pointee_(p) {
58+ explicit SmartPointer<element_type>(element_type* p) BOOST_NOEXCEPT : pointee_(p) {
5959 if(pointee_ != nullptr)
6060 pointee_->AddRef();
6161 }
6262 /// Copy-constructor.
63- SmartPointer(const SmartPointer<element_type>& other) /*noexcept*/ : pointee_(other.pointee_) {
63+ SmartPointer(const SmartPointer<element_type>& other) BOOST_NOEXCEPT : pointee_(other.pointee_) {
6464 if(pointee_ != nullptr)
6565 pointee_->AddRef();
6666 }
6767 /// Copy-constructor.
6868 template<typename U>
69- SmartPointer(const SmartPointer<U>& other) /*noexcept*/ : pointee_(nullptr) {
69+ SmartPointer(const SmartPointer<U>& other) BOOST_NOEXCEPT : pointee_(nullptr) {
7070 if(other.pointee_ != nullptr)
7171 other.pointee_->QueryInterface(__uuidof(element_type), initializePPV());
7272 }
7373 /// Copy-constructor with an interface identifier.
7474 template<typename U>
75- SmartPointer(const SmartPointer<U>& other, const IID& iid) /*noexcept*/ : pointee_(nullptr) {
75+ SmartPointer(const SmartPointer<U>& other, const IID& iid) BOOST_NOEXCEPT : pointee_(nullptr) {
7676 if(other.pointee_ != nullptr)
7777 other.pointee_->QueryInterface(iid, initializePPV());
7878 }
7979 /// Move-constructor.
80- SmartPointer(SmartPointer<element_type>&& other) /*noexcept*/ : pointee_(other.pointee_) {
80+ SmartPointer(SmartPointer<element_type>&& other) BOOST_NOEXCEPT : pointee_(other.pointee_) {
8181 if(pointee_ != nullptr) {
8282 pointee_->AddRef();
8383 other.reset();
@@ -85,7 +85,7 @@
8585 }
8686 /// Move-constructor.
8787 template<typename U>
88- SmartPointer(SmartPointer<U>&& other) /*noexcept*/ : pointee_(nullptr) {
88+ SmartPointer(SmartPointer<U>&& other) BOOST_NOEXCEPT : pointee_(nullptr) {
8989 if(pointee_ != nullptr) {
9090 if(SUCCEEDED(other.pointee_->QueryInterface(__uuidof(element_type), initializePPV())))
9191 other.reset();
@@ -93,7 +93,7 @@
9393 }
9494 /// Move-constructor with an interface identifier.
9595 template<typename U>
96- SmartPointer(SmartPointer<U>&& other, const IID& iid) /*noexcept*/ : pointee_(nullptr) {
96+ SmartPointer(SmartPointer<U>&& other, const IID& iid) BOOST_NOEXCEPT : pointee_(nullptr) {
9797 if(pointee_ != nullptr) {
9898 if(SUCCEEDED(other.pointee_->QueryInterface(iid, initializePPV())))
9999 other.reset();
@@ -101,23 +101,23 @@
101101 }
102102 /// Copy-assignment operator.
103103 template<typename U>
104- SmartPointer<element_type>& operator=(const SmartPointer<U>& other) /*noexcept*/ {
104+ SmartPointer<element_type>& operator=(const SmartPointer<U>& other) BOOST_NOEXCEPT {
105105 SmartPointer<element_type>(other).swap(*this);
106106 return *this;
107107 }
108108 /// Move-assignment operator.
109109 template<typename U>
110- SmartPointer<element_type>& operator=(SmartPointer<U>&& other) /*noexcept*/ {
110+ SmartPointer<element_type>& operator=(SmartPointer<U>&& other) BOOST_NOEXCEPT {
111111 SmartPointer<element_type>(other).swap(*this);
112112 return *this;
113113 }
114114 /// Destructor.
115- ~SmartPointer() /*noexcept*/ {
115+ ~SmartPointer() BOOST_NOEXCEPT {
116116 if(pointee_ != nullptr)
117117 pointee_->Release();
118118 }
119119 ///
120- operator bool() const /*noexcept*/ {return get() != nullptr;}
120+ operator bool() const BOOST_NOEXCEPT {return get() != nullptr;}
121121 /// Constructor creates instance by using @c CoCreateInstance.
122122 static SmartPointer<element_type> create(REFCLSID clsid, REFIID iid /* = __uuidof(Interface) */,
123123 DWORD context = CLSCTX_ALL, IUnknown* outer = nullptr, HRESULT* hr = nullptr) {
@@ -128,20 +128,20 @@
128128 return p;
129129 }
130130 /// Returns the interface pointer.
131- SmartPointerProxy<element_type>* get() const /*noexcept*/ {
131+ SmartPointerProxy<element_type>* get() const BOOST_NOEXCEPT {
132132 return static_cast<SmartPointerProxy<element_type>*>(pointee_);
133133 }
134134 /// Returns the output pointer for initialization.
135- element_type** initialize() /*noexcept*/ {
135+ element_type** initialize() BOOST_NOEXCEPT {
136136 reset();
137137 return &pointee_;
138138 }
139139 /// Returns the output pointer for initialization with type @c void**.
140- void** initializePPV() /*noexcept*/ {
140+ void** initializePPV() BOOST_NOEXCEPT {
141141 return reinterpret_cast<void**>(initialize());
142142 }
143143 /// Returns true if the pointer addresses the same object.
144- bool equals(IUnknown* p) const /*noexcept*/ {
144+ bool equals(IUnknown* p) const BOOST_NOEXCEPT {
145145 if(pointee_ == nullptr && p == nullptr)
146146 return true;
147147 else if(pointee_ == nullptr || p == nullptr)
@@ -152,61 +152,61 @@
152152 return ps[1].get() == ps[2].get();
153153 }
154154 /// Resets the pointer.
155- void reset() /*noexcept*/ {
155+ void reset() BOOST_NOEXCEPT {
156156 SmartPointer<element_type>().swap(*this);
157157 }
158158 /// Resets the pointer.
159159 template<typename U>
160- void reset(U* p) /*noexcept*/ {
160+ void reset(U* p) BOOST_NOEXCEPT {
161161 if(p != pointee_)
162162 SmartPointer<element_type>(p).swap(*this);
163163 }
164164 /// Resets the pointer with an interface identifier.
165165 template<typename U>
166- void reset(U* p, const IID& iid) /*noexcept*/ {
166+ void reset(U* p, const IID& iid) BOOST_NOEXCEPT {
167167 if(p != pointee_)
168168 SmartPointer<element_type>(p, iid).swap(*this);
169169 }
170170 /// Swaps the two objects.
171- void swap(SmartPointer<element_type>& other) /*noexcept*/ {
171+ void swap(SmartPointer<element_type>& other) BOOST_NOEXCEPT {
172172 std::swap(pointee_, other.pointee_);
173173 }
174174 /// Swaps the two objects.
175- void swap(SmartPointerProxy<element_type>& other) /*noexcept*/ {
175+ void swap(SmartPointerProxy<element_type>& other) BOOST_NOEXCEPT {
176176 std::swap(pointee_, other.pointee_);
177177 }
178178 /// Member-access operator.
179- SmartPointerProxy<element_type>* operator->() const /*noexcept*/ {
179+ SmartPointerProxy<element_type>* operator->() const BOOST_NOEXCEPT {
180180 assert(get() != nullptr);
181181 return get();
182182 }
183183 /// Dereference operator.
184- SmartPointerProxy<element_type>& operator*() const /*noexcept*/ {
184+ SmartPointerProxy<element_type>& operator*() const BOOST_NOEXCEPT {
185185 assert(get() != nullptr);
186186 return *get();
187187 }
188188 /// Equality operator.
189- friend bool operator==(const element_type* lhs, const SmartPointer<element_type>& rhs) /*noexcept*/ {
189+ friend bool operator==(const element_type* lhs, const SmartPointer<element_type>& rhs) BOOST_NOEXCEPT {
190190 return lhs == rhs.pointee_;
191191 }
192192 /// Equality operator.
193- friend bool operator==(const SmartPointer<element_type>& lhs, const SmartPointer<element_type>& rhs) /*noexcept*/ {
193+ friend bool operator==(const SmartPointer<element_type>& lhs, const SmartPointer<element_type>& rhs) BOOST_NOEXCEPT {
194194 return lhs.pointee_ == rhs.pointee_;
195195 }
196196 /// Less than operator.
197- friend bool operator<(const element_type* lhs, const SmartPointer<element_type>& rhs) /*noexcept*/ {
197+ friend bool operator<(const element_type* lhs, const SmartPointer<element_type>& rhs) BOOST_NOEXCEPT {
198198 return lhs < rhs.pointee_;
199199 }
200200 /// Less than operator.
201- friend bool operator<(const SmartPointer<element_type> lhs, const SmartPointer<element_type>& rhs) /*noexcept*/ {
201+ friend bool operator<(const SmartPointer<element_type> lhs, const SmartPointer<element_type>& rhs) BOOST_NOEXCEPT {
202202 return lhs.pointee_ < rhs.pointee_;
203203 }
204204 /// Greater than operator.
205- friend bool operator>(const element_type* lhs, const SmartPointer<element_type>& rhs) /*noexcept*/ {
205+ friend bool operator>(const element_type* lhs, const SmartPointer<element_type>& rhs) BOOST_NOEXCEPT {
206206 return lhs > rhs.pointee_;
207207 }
208208 /// Greater than operator.
209- friend bool operator>(const SmartPointer<element_type>& lhs, const SmartPointer<element_type>& rhs) /*noexcept*/ {
209+ friend bool operator>(const SmartPointer<element_type>& lhs, const SmartPointer<element_type>& rhs) BOOST_NOEXCEPT {
210210 return lhs.pointee_ > rhs.pointee_;
211211 }
212212 private:
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/ascension/win32/com/unknown-impl.hpp
--- a/ascension/ascension/win32/com/unknown-impl.hpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/ascension/win32/com/unknown-impl.hpp Sat May 11 12:12:08 2013 +0900
@@ -94,17 +94,17 @@
9494 };
9595 template<> class ReferenceCounter<win32::com::SingleThreaded> {
9696 public:
97- ReferenceCounter() /*noexcept*/ : c_(0) {}
98- ULONG increment() /*noexcept*/ {return ++c_;}
99- ULONG decrement() /*noexcept*/{return --c_;}
97+ ReferenceCounter() BOOST_NOEXCEPT : c_(0) {}
98+ ULONG increment() BOOST_NOEXCEPT {return ++c_;}
99+ ULONG decrement() BOOST_NOEXCEPT{return --c_;}
100100 private:
101101 ULONG c_;
102102 };
103103 template<> class ReferenceCounter<win32::com::MultiThreaded> {
104104 public:
105- ReferenceCounter() /*noexcept*/ : c_(0) {}
106- ULONG increment() /*noexcept*/ {return ::InterlockedIncrement(&c_);}
107- ULONG decrement() /*noexcept*/{return ::InterlockedDecrement(&c_);}
105+ ReferenceCounter() BOOST_NOEXCEPT : c_(0) {}
106+ ULONG increment() BOOST_NOEXCEPT {return ::InterlockedIncrement(&c_);}
107+ ULONG decrement() BOOST_NOEXCEPT{return ::InterlockedDecrement(&c_);}
108108 private:
109109 long c_;
110110 };
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/graphics/font/text-layout-uniscribe.cpp
--- a/ascension/src/graphics/font/text-layout-uniscribe.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/graphics/font/text-layout-uniscribe.cpp Sat May 11 12:12:08 2013 +0900
@@ -26,6 +26,7 @@
2626 #include <tuple>
2727 #include <boost/flyweight.hpp>
2828 #include <boost/foreach.hpp>
29+#include <boost/range/algorithm/find.hpp>
2930 #include <boost/range/numeric.hpp> // boost.accumulate
3031 #include <usp10.h>
3132
@@ -46,19 +47,35 @@
4647 // SystemColors caches the system colors.
4748 class SystemColors {
4849 public:
49- SystemColors() /*throw()*/ {update();}
50- COLORREF get(int index) const {assert(index >= 0 && index < ASCENSION_COUNTOF(c_)); return c_[index];}
51- COLORREF serve(const boost::optional<Color>& color, int index) const {return color ? color->as<COLORREF>() : get(index);}
52- void update() /*throw()*/ {for(int i = 0; i < ASCENSION_COUNTOF(c_); ++i) c_[i] = ::GetSysColor(i);}
50+ SystemColors() BOOST_NOEXCEPT {
51+ update();
52+ }
53+ COLORREF get(size_t index) const {
54+ assert(index >= 0 && index < tuple_size<decltype(values_)>::value);
55+ return values_[index];
56+ }
57+ COLORREF serve(const boost::optional<Color>& color, int index) const {
58+ return color ? color->as<COLORREF>() : get(index);
59+ }
60+ void update() BOOST_NOEXCEPT {
61+ for(size_t i = 0; i < tuple_size<decltype(values_)>::value; ++i)
62+ values_[i] = ::GetSysColor(i);
63+ }
5364 private:
54- COLORREF c_[128];
65+ array<COLORREF, 128> values_;
5566 } systemColors;
5667
5768 const class ScriptProperties {
5869 public:
59- ScriptProperties() /*throw()*/ : p_(nullptr), c_(0) {::ScriptGetProperties(&p_, &c_);}
60- const SCRIPT_PROPERTIES& get(int script) const {if(script >= c_) throw out_of_range("script"); return *p_[script];}
61- int numberOfOfScripts() const /*throw()*/ {return c_;}
70+ ScriptProperties() BOOST_NOEXCEPT : p_(nullptr), c_(0) {
71+ ::ScriptGetProperties(&p_, &c_);
72+ }
73+ const SCRIPT_PROPERTIES& get(int script) const {
74+ if(script >= c_)
75+ throw out_of_range("script");
76+ return *p_[script];
77+ }
78+ int numberOfOfScripts() const BOOST_NOEXCEPT {return c_;}
6279 private:
6380 const SCRIPT_PROPERTIES** p_;
6481 int c_;
@@ -66,12 +83,12 @@
6683
6784 class UserSettings {
6885 public:
69- UserSettings() /*throw()*/ {update();}
70- LANGID defaultLanguage() const /*throw()*/ {return languageID_;}
71- const SCRIPT_DIGITSUBSTITUTE& digitSubstitution(bool ignoreUserOverride) const /*throw()*/ {
86+ UserSettings() BOOST_NOEXCEPT {update();}
87+ LANGID defaultLanguage() const BOOST_NOEXCEPT {return languageID_;}
88+ const SCRIPT_DIGITSUBSTITUTE& digitSubstitution(bool ignoreUserOverride) const BOOST_NOEXCEPT {
7289 return ignoreUserOverride ? digitSubstitutionNoUserOverride_ : digitSubstitution_;
7390 }
74- void update() /*throw()*/ {
91+ void update() BOOST_NOEXCEPT {
7592 languageID_ = ::GetUserDefaultLangID();
7693 ::ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT, &digitSubstitution_);
7794 ::ScriptRecordDigitSubstitution(LOCALE_USER_DEFAULT | LOCALE_NOUSEROVERRIDE, &digitSubstitutionNoUserOverride_);
@@ -148,7 +165,7 @@
148165 return static_cast<int>(length) * 3 / 2 + 16;
149166 }
150167
151- LANGID userCJKLanguage() /*throw()*/;
168+ LANGID userCJKLanguage() BOOST_NOEXCEPT;
152169
153170 String fallback(int script) {
154171 if(script <= Script::FIRST_VALUE || script == Script::INHERITED
@@ -248,7 +265,7 @@
248265 * @return Succeeded or not
249266 */
250267 bool getDecorationLineMetrics(const win32::Handle<HDC>::Type& dc, int* baselineOffset,
251- int* underlineOffset, int* underlineThickness, int* strikethroughOffset, int* strikethroughThickness) /*throw()*/ {
268+ int* underlineOffset, int* underlineThickness, int* strikethroughOffset, int* strikethroughThickness) BOOST_NOEXCEPT {
252269 OUTLINETEXTMETRICW* otm = nullptr;
253270 TEXTMETRICW tm;
254271 if(const UINT c = ::GetOutlineTextMetricsW(dc.get(), 0, nullptr)) {
@@ -272,7 +289,7 @@
272289 return true;
273290 }
274291
275- inline bool isC0orC1Control(CodePoint c) /*throw()*/ {
292+ inline bool isC0orC1Control(CodePoint c) BOOST_NOEXCEPT {
276293 return c < 0x20 || c == 0x7f || (c >= 0x80 && c < 0xa0);
277294 }
278295
@@ -360,11 +377,11 @@
360377 inline bool uniscribeSupportsIVS() BOOST_NOEXCEPT {
361378 static bool checked = false, supports = false;
362379 if(!checked) {
363- static const WCHAR text[] = L"\x82a6\xdb40\xdd00"; // <芦, U+E0100>
364- SCRIPT_ITEM items[4];
380+ static const basic_string<WCHAR> text(L"\x82a6\xdb40\xdd00"); // <芦, U+E0100>
381+ array<SCRIPT_ITEM, 4> items;
365382 int numberOfItems;
366- if(SUCCEEDED(::ScriptItemize(text, ASCENSION_COUNTOF(text) - 1,
367- ASCENSION_COUNTOF(items), nullptr, nullptr, items, &numberOfItems)) && numberOfItems == 1)
383+ if(SUCCEEDED(::ScriptItemize(text.c_str(), static_cast<int>(text.length()),
384+ items.size(), nullptr, nullptr, items.data(), &numberOfItems)) && numberOfItems == 1)
368385 supports = true;
369386 checked = true;
370387 }
@@ -373,15 +390,15 @@
373390
374391 LANGID userCJKLanguage() {
375392 // this code is preliminary...
376- static const WORD CJK_LANGUAGES[] = {LANG_CHINESE, LANG_JAPANESE, LANG_KOREAN}; // sorted by numeric values
393+ static const array<WORD, 3> CJK_LANGUAGES = {LANG_CHINESE, LANG_JAPANESE, LANG_KOREAN}; // sorted by numeric values
377394 LANGID result = win32::userDefaultUILanguage();
378- if(find(CJK_LANGUAGES, ASCENSION_ENDOF(CJK_LANGUAGES), PRIMARYLANGID(result)) != ASCENSION_ENDOF(CJK_LANGUAGES))
395+ if(boost::find(CJK_LANGUAGES, PRIMARYLANGID(result)) != boost::end(CJK_LANGUAGES))
379396 return result;
380397 result = ::GetUserDefaultLangID();
381- if(find(CJK_LANGUAGES, ASCENSION_ENDOF(CJK_LANGUAGES), PRIMARYLANGID(result)) != ASCENSION_ENDOF(CJK_LANGUAGES))
398+ if(boost::find(CJK_LANGUAGES, PRIMARYLANGID(result)) != boost::end(CJK_LANGUAGES))
382399 return result;
383400 result = ::GetSystemDefaultLangID();
384- if(find(CJK_LANGUAGES, ASCENSION_ENDOF(CJK_LANGUAGES), PRIMARYLANGID(result)) != ASCENSION_ENDOF(CJK_LANGUAGES))
401+ if(boost::find(CJK_LANGUAGES, PRIMARYLANGID(result)) != boost::end(CJK_LANGUAGES))
385402 return result;
386403 switch(::GetACP()) {
387404 case 932:
@@ -1778,7 +1795,7 @@
17781795 * @param id the language identifier
17791796 * @return the script or @c NOT_PROPERTY
17801797 */
1781- inline int convertWin32LangIDtoUnicodeScript(LANGID id) /*throw()*/ {
1798+ inline int convertWin32LangIDtoUnicodeScript(LANGID id) BOOST_NOEXCEPT {
17821799 switch(id) {
17831800 case LANG_ARABIC: return Script::ARABIC;
17841801 case LANG_ASSAMESE: return Script::BENGALI;
@@ -3000,7 +3017,7 @@
30003017 }
30013018 #if 0
30023019 /// Expands the all tabs and resolves each width.
3003-inline void TextLayout::expandTabsWithoutWrapping() /*throw()*/ {
3020+inline void TextLayout::expandTabsWithoutWrapping() BOOST_NOEXCEPT {
30043021 const String& s = text();
30053022 const int fullTabWidth = lip_.textMetrics().averageCharacterWidth() * lip_.layoutSettings().tabWidth;
30063023 int x = 0;
@@ -3071,7 +3088,7 @@
30713088 }
30723089
30733090 /// Justifies the wrapped visual lines.
3074-inline void TextLayout::justify(Scalar lineMeasure, TextJustification) /*throw()*/ {
3091+inline void TextLayout::justify(Scalar lineMeasure, TextJustification) BOOST_NOEXCEPT {
30753092 for(Index line = 0; line < numberOfLines(); ++line) {
30763093 const Scalar ipd = measure(line);
30773094 for(auto i(firstRunInLine(line)), e(firstRunInLine(line + 1)); i != e; ++i) {
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/graphics/font/text-layout.cpp
--- a/ascension/src/graphics/font/text-layout.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/graphics/font/text-layout.cpp Sat May 11 12:12:08 2013 +0900
@@ -234,7 +234,7 @@
234234 * @c presentation#ALIGN_START or @c presentation#ALIGN_END.
235235 * @see #readingDirection, presentation#resolveTextAlignment
236236 */
237-TextAlignment TextLayout::alignment() const /*throw()*/ {
237+TextAlignment TextLayout::alignment() const BOOST_NOEXCEPT {
238238 if(style_.get() != nullptr && style_->readingDirection != INHERIT_TEXT_ALIGNMENT)
239239 style_->readingDirection;
240240 shared_ptr<const TextLineStyle> defaultStyle(lip_.presentation().defaultTextLineStyle());
@@ -478,7 +478,7 @@
478478
479479 #if 0
480480 /// Returns an iterator addresses the first styled segment.
481-TextLayout::StyledSegmentIterator TextLayout::firstStyledSegment() const /*throw()*/ {
481+TextLayout::StyledSegmentIterator TextLayout::firstStyledSegment() const BOOST_NOEXCEPT {
482482 const TextRun* temp = *runs_;
483483 return StyledSegmentIterator(temp);
484484 }
@@ -499,7 +499,7 @@
499499 }
500500 #if 0
501501 /// Returns an iterator addresses the last styled segment.
502-TextLayout::StyledSegmentIterator TextLayout::lastStyledSegment() const /*throw()*/ {
502+TextLayout::StyledSegmentIterator TextLayout::lastStyledSegment() const BOOST_NOEXCEPT {
503503 const TextRun* temp = runs_[numberOfRuns_];
504504 return StyledSegmentIterator(temp);
505505 }
@@ -912,7 +912,7 @@
912912 * @param direction the direction
913913 * @return the distance from leading edge of the line to the next tab position
914914 */
915-inline int TextLayout::nextTabStop(int x, Direction direction) const /*throw()*/ {
915+inline int TextLayout::nextTabStop(int x, Direction direction) const BOOST_NOEXCEPT {
916916 assert(x >= 0);
917917 const int tabWidth = lip_.textMetrics().averageCharacterWidth() * lip_.layoutSettings().tabWidth;
918918 return (direction == Direction::FORWARD) ? x + tabWidth - x % tabWidth : x - x % tabWidth;
@@ -924,7 +924,7 @@
924924 * @param right @c true to find the next right position
925925 * @return the tab stop position in pixel
926926 */
927-int TextLayout::nextTabStopBasedLeftEdge(int x, bool right) const /*throw()*/ {
927+int TextLayout::nextTabStopBasedLeftEdge(int x, bool right) const BOOST_NOEXCEPT {
928928 assert(x >= 0);
929929 const LayoutSettings& c = lip_.layoutSettings();
930930 const int tabWidth = lip_.textMetrics().averageCharacterWidth() * c.tabWidth;
@@ -940,7 +940,7 @@
940940 * Returns the computed reading direction of the line.
941941 * @see #alignment
942942 */
943-ReadingDirection TextLayout::readingDirection() const /*throw()*/ {
943+ReadingDirection TextLayout::readingDirection() const BOOST_NOEXCEPT {
944944 ReadingDirection result = INHERIT_READING_DIRECTION;
945945 // try the requested line style
946946 if(style_.get() != nullptr)
@@ -1081,15 +1081,15 @@
10811081 * Private constructor.
10821082 * @param start
10831083 */
1084-TextLayout::StyledSegmentIterator::StyledSegmentIterator(const TextRun*& start) /*throw()*/ : p_(&start) {
1084+TextLayout::StyledSegmentIterator::StyledSegmentIterator(const TextRun*& start) BOOST_NOEXCEPT : p_(&start) {
10851085 }
10861086
10871087 /// Copy-constructor.
1088-TextLayout::StyledSegmentIterator::StyledSegmentIterator(const StyledSegmentIterator& rhs) /*throw()*/ : p_(rhs.p_) {
1088+TextLayout::StyledSegmentIterator::StyledSegmentIterator(const StyledSegmentIterator& rhs) BOOST_NOEXCEPT : p_(rhs.p_) {
10891089 }
10901090
10911091 /// Returns the current segment.
1092-StyledRun TextLayout::StyledSegmentIterator::current() const /*throw()*/ {
1092+StyledRun TextLayout::StyledSegmentIterator::current() const BOOST_NOEXCEPT {
10931093 const TextRun& run = **p_;
10941094 return StyledRun(run.offsetInLine, run.style);
10951095 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/graphics/font/text-renderer.cpp
--- a/ascension/src/graphics/font/text-renderer.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/graphics/font/text-renderer.cpp Sat May 11 12:12:08 2013 +0900
@@ -74,7 +74,7 @@
7474 }
7575 } // namespace @0
7676
77-void FontSelector::linkPrimaryFont() /*throw()*/ {
77+void FontSelector::linkPrimaryFont() BOOST_NOEXCEPT {
7878 // TODO: this does not support nested font linking.
7979 assert(linkedFonts_ != nullptr);
8080 for(vector<Fontset*>::iterator i(linkedFonts_->begin()), e(linkedFonts_->end()); i != e; ++i)
@@ -114,7 +114,7 @@
114114 // TextRenderer ///////////////////////////////////////////////////////////////////////////////////
115115
116116 namespace {
117- inline int calculateMemoryBitmapSize(int src) /*throw()*/ {
117+ inline int calculateMemoryBitmapSize(int src) BOOST_NOEXCEPT {
118118 const int UNIT = 32;
119119 return (src % UNIT != 0) ? src + UNIT - src % UNIT : src;
120120 }
@@ -252,7 +252,7 @@
252252 * @param context The graphics context
253253 * @param alignmentPoint The alignment point of the text layout of the line to draw
254254 */
255-void TextRenderer::paint(Index line, PaintContext& context, const Point& alignmentPoint) const /*throw()*/ {
255+void TextRenderer::paint(Index line, PaintContext& context, const Point& alignmentPoint) const BOOST_NOEXCEPT {
256256 // if(!enablesDoubleBuffering_) {
257257 layouts().at(line).draw(context, alignmentPoint,
258258 (lineRenderingOptions_.get() != nullptr) ? lineRenderingOptions_->textPaintOverride(line) : nullptr,
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/graphics/font/text-viewport.cpp
--- a/ascension/src/graphics/font/text-viewport.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/graphics/font/text-viewport.cpp Sat May 11 12:12:08 2013 +0900
@@ -276,7 +276,7 @@
276276 * @return The logical and visual line numbers
277277 * @see #BaselineIterator, TextViewer#mapLocalBpdToLine
278278 */
279- VisualLine mapBpdToLine(const TextViewport& viewport, Scalar bpd, bool* snapped = nullptr) /*throw()*/ {
279+ VisualLine mapBpdToLine(const TextViewport& viewport, Scalar bpd, bool* snapped = nullptr) BOOST_NOEXCEPT {
280280 const BlockFlowDirection blockFlowDirection = viewport.textRenderer().computedBlockFlowDirection();
281281 const PhysicalFourSides<Scalar>& physicalSpaces = viewport.textRenderer().spaceWidths();
282282 Scalar spaceBefore, spaceAfter;
@@ -345,7 +345,7 @@
345345 boost::bind(&TextViewport::documentAccessibleRegionChanged, this, _1));
346346 }
347347
348-inline void TextViewport::adjustBpdScrollPositions() /*throw()*/ {
348+inline void TextViewport::adjustBpdScrollPositions() BOOST_NOEXCEPT {
349349 const LineLayoutVector& layouts = textRenderer().layouts();
350350 firstVisibleLine_.line = min(firstVisibleLine_.line, textRenderer().presentation().document().numberOfLines() - 1);
351351 firstVisibleLine_.subline = min(layouts.numberOfSublinesOfLine(firstVisibleLine_.line) - 1, firstVisibleLine_.subline);
@@ -531,7 +531,7 @@
531531 }
532532
533533 /// @see VisualLinesListener#visualLinesDeleted
534-void TextViewport::visualLinesDeleted(const boost::integer_range<Index>& lines, Index sublines, bool longestLineChanged) /*throw()*/ {
534+void TextViewport::visualLinesDeleted(const boost::integer_range<Index>& lines, Index sublines, bool longestLineChanged) BOOST_NOEXCEPT {
535535 // scrolls_.changed = true;
536536 if(*lines.end() < firstVisibleLine_.line) { // deleted before visible area
537537 firstVisibleLine_.line -= lines.size();
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/graphics/paint-gdi.cpp
--- a/ascension/src/graphics/paint-gdi.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/graphics/paint-gdi.cpp Sat May 11 12:12:08 2013 +0900
@@ -10,7 +10,7 @@
1010 using namespace ascension::graphics;
1111 using namespace std;
1212
13-Paint::~Paint() /*noexcept*/ {
13+Paint::~Paint() BOOST_NOEXCEPT {
1414 switch(nativeObject_.lbStyle) {
1515 case BS_DIBPATTERN:
1616 case BS_DIBPATTERN8X8:
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/kernel/document.cpp
--- a/ascension/src/kernel/document.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/kernel/document.cpp Sat May 11 12:12:08 2013 +0900
@@ -1,41 +1,41 @@
1-/**
2- * @file document.cpp
3- * @author exeal
4- * @date 2003-2006 (was EditDoc.h)
5- * @date 2006-2013
6- */
7-
8-#include <ascension/kernel/document.hpp>
9-#include <ascension/kernel/document-character-iterator.hpp>
10-#include <ascension/kernel/point.hpp>
11-#include <ascension/corelib/text/identifier-syntax.hpp>
12-#include <boost/foreach.hpp>
13-#include <boost/range/algorithm/find.hpp>
14-#include <boost/range/algorithm/lower_bound.hpp>
15-#include <algorithm>
16-#include <limits> // std.numeric_limits
17-
18-using namespace ascension;
19-using namespace ascension::kernel;
20-using namespace ascension::text;
21-using namespace std;
22-using detail::GapVector;
23-
24-
25-namespace {
26- inline Newline resolveNewline(const Document& document, const Newline& newline) {
27- if(newline == Newline::USE_DOCUMENT_INPUT) {
28- // fallback
29- shared_ptr<DocumentInput> input(document.input().lock());
30- const Newline resolved((input.get() != nullptr) ? input->newline() : ASCENSION_DEFAULT_NEWLINE);
31- assert(resolved.isLiteral());
32- return resolved;
33- }
34- return newline;
35- }
36-} // namespace @0
37-
38-
1+/**
2+ * @file document.cpp
3+ * @author exeal
4+ * @date 2003-2006 (was EditDoc.h)
5+ * @date 2006-2013
6+ */
7+
8+#include <ascension/kernel/document.hpp>
9+#include <ascension/kernel/document-character-iterator.hpp>
10+#include <ascension/kernel/point.hpp>
11+#include <ascension/corelib/text/identifier-syntax.hpp>
12+#include <boost/foreach.hpp>
13+#include <boost/range/algorithm/find.hpp>
14+#include <boost/range/algorithm/lower_bound.hpp>
15+#include <algorithm>
16+#include <limits> // std.numeric_limits
17+
18+using namespace ascension;
19+using namespace ascension::kernel;
20+using namespace ascension::text;
21+using namespace std;
22+using detail::GapVector;
23+
24+
25+namespace {
26+ inline Newline resolveNewline(const Document& document, const Newline& newline) {
27+ if(newline == Newline::USE_DOCUMENT_INPUT) {
28+ // fallback
29+ shared_ptr<DocumentInput> input(document.input().lock());
30+ const Newline resolved((input.get() != nullptr) ? input->newline() : ASCENSION_DEFAULT_NEWLINE);
31+ assert(resolved.isLiteral());
32+ return resolved;
33+ }
34+ return newline;
35+ }
36+} // namespace @0
37+
38+
3939 // text.Newline ///////////////////////////////////////////////////////////////////////////////////
4040
4141 /// Line feed. Standard of Unix (Lf, U+000A).
@@ -60,1136 +60,1136 @@
6060 const Newline Newline::USE_INTRINSIC_VALUE(0x80000000u);
6161
6262 /// Represents any NLF as the value of @c kernel#DocumentInput#newline().
63-const Newline Newline::USE_DOCUMENT_INPUT(0x80000001u);
64-
65-
66-// kernel free functions //////////////////////////////////////////////////////////////////////////
67-
68-/**
69- * Writes the content of the document to the specified output stream.
70- * <p>This method does not write Unicode byte order mark.</p>
71- * <p>This method explicitly flushes the output stream.</p>
72- * @param out The output stream
73- * @param document The document
74- * @param region The region to be written (This region is not restricted with narrowing)
75- * @param newline The newline representation
76- * @return @a out
77- * @throw ... Any exceptions out.operator bool, out.write and out.flush throw
78- * @see Newline#asString, Document#insert
79- */
80-basic_ostream<Char>& kernel::writeDocumentToStream(basic_ostream<Char>& out,
81- const Document& document, const Region& region, const Newline& newline /* = Newline::USE_INTRINSIC_VALUE */) {
82- const Position& beginning = region.beginning();
83- const Position end = min(region.end(), document.region().second);
84- if(beginning.line == end.line) { // shortcut for single-line
85- if(out) {
86- // TODO: this cast may be danger.
87- out.write(document.line(end.line).data() + beginning.offsetInLine, static_cast<streamsize>(end.offsetInLine - beginning.offsetInLine));
88- }
89- } else {
90- const Newline resolvedNewline(resolveNewline(document, newline));
91- const String eol(resolvedNewline.isLiteral() ? resolvedNewline.asString() : String());
92- assert(!eol.empty() || resolvedNewline == Newline::USE_INTRINSIC_VALUE);
93- for(Index i = beginning.line; out; ++i) {
94- const Document::Line& line = document.getLineInformation(i);
95- const Index first = (i == beginning.line) ? beginning.offsetInLine : 0;
96- const Index last = (i == end.line) ? end.offsetInLine : line.text().length();
97- out.write(line.text().data() + first, static_cast<streamsize>(last - first));
98- if(i == end.line)
99- break;
100- if(resolvedNewline == Newline::USE_INTRINSIC_VALUE) {
101- const String intrinsicEol(line.newline().asString());
102- out.write(intrinsicEol.data(), static_cast<streamsize>(intrinsicEol.length()));
103- } else
104- out.write(eol.data(), static_cast<streamsize>(eol.length()));
105- }
106- }
107- return out.flush();
108-}
109-
110-
111-// kernel.positions free functions ////////////////////////////////////////////////////////////////
112-
113-/**
114- * Returns absolute character offset of the specified position from the start of the document.
115- * @param document The document
116- * @param at The position
117- * @param fromAccessibleStart
118- * @throw BadPositionException @a at is outside of the document
119- */
120-Index positions::absoluteOffset(const Document& document, const Position& at, bool fromAccessibleStart) {
121- if(at > document.region().second)
122- throw BadPositionException(at);
123- Index offset = 0;
124- const Position start((fromAccessibleStart ? document.accessibleRegion() : document.region()).first);
125- for(Index line = start.line; ; ++line) {
126- if(line == at.line) {
127- offset += at.offsetInLine;
128- break;
129- } else {
130- offset += document.lineLength(line) + 1; // +1 is for a newline character
131- if(line == start.line)
132- offset -= start.offsetInLine;
133- }
134- }
135- return offset;
136-}
137-
138-/**
139- * Adapts the specified position to the document change.
140- * @param position The original position
141- * @param change The content of the document change
142- * @param gravity The gravity which determines the direction to which the position should move if
143- * a text was inserted at the position. If @c FORWARD is specified, the position
144- * will move to the start of the inserted text (no movement occur). Otherwise, move
145- * to the end of the inserted text
146- * @return The result position
147- */
148-Position positions::updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT {
149- Position newPosition(position);
150- if(!change.erasedRegion().isEmpty()) { // deletion
151- if(position < change.erasedRegion().second) { // the end is behind the current line
152- if(position <= change.erasedRegion().first)
153- return newPosition;
154- else // in the region
155- newPosition = change.erasedRegion().first;
156- } else if(position.line > change.erasedRegion().second.line) // in front of the current line
157- newPosition.line -= change.erasedRegion().second.line - change.erasedRegion().first.line;
158- else { // the end is the current line
159- if(position.line == change.erasedRegion().first.line) // the region is single-line
160- newPosition.offsetInLine -= change.erasedRegion().second.offsetInLine - change.erasedRegion().first.offsetInLine;
161- else { // the region is multiline
162- newPosition.line -= change.erasedRegion().second.line - change.erasedRegion().first.line;
163- newPosition.offsetInLine -= change.erasedRegion().second.offsetInLine - change.erasedRegion().first.offsetInLine;
164- }
165- }
166- }
167- if(!change.insertedRegion().isEmpty()) { // insertion
168- if(position < change.insertedRegion().first) // behind the current position
169- return newPosition;
170- else if(position == change.insertedRegion().first && gravity == Direction::BACKWARD) // the current position + backward gravity
171- return newPosition;
172- else if(position.line > change.insertedRegion().first.line) // in front of the current line
173- newPosition.line += change.insertedRegion().second.line - change.insertedRegion().first.line;
174- else { // in the current line
175- newPosition.line += change.insertedRegion().second.line - change.insertedRegion().first.line;
176- newPosition.offsetInLine += change.insertedRegion().second.offsetInLine - change.insertedRegion().first.offsetInLine;
177- }
178- }
179- return newPosition;
180-}
181-
182-
183-namespace {
184-#ifdef _DEBUG
185- // for Document.length_ diagnostic
186- Index calculateDocumentLength(const Document& document) {
187- Index c = 0;
188- const Index lines = document.numberOfLines();
189- for(Index i = 0; i < lines; ++i)
190- c += document.lineLength(i);
191- return c;
192- }
193-#endif // _DEBUG
194-} // namespace @0
195-
196-
197-// exception classes //////////////////////////////////////////////////////////////////////////////
198-
199-/// Protected default constructor.
200-DocumentCantChangeException::DocumentCantChangeException() {
201-}
202-
203-/// Destructor.
204-DocumentCantChangeException::~DocumentCantChangeException() {
205-}
206-
207-/// Default constructor.
208-ReadOnlyDocumentException::ReadOnlyDocumentException() :
209- IllegalStateException("The document is readonly. Any edit process is denied.") {
210-}
211-
212-/// Destructor.
213-ReadOnlyDocumentException::~ReadOnlyDocumentException() BOOST_NOEXCEPT {
214-}
215-
216-/// Default constructor.
217-DocumentAccessViolationException::DocumentAccessViolationException() :
218- invalid_argument("The specified position or region is inaccessible.") {
219-}
220-
221-/// Destructor.
222-DocumentAccessViolationException::~DocumentAccessViolationException() BOOST_NOEXCEPT {
223-}
224-
225-/// Constructor.
226-DocumentInput::ChangeRejectedException::ChangeRejectedException() {
227-}
228-
229-
230-// DocumentChange /////////////////////////////////////////////////////////////////////////////////
231-
232-/**
233- * Private constructor.
234- * @param erasedRegion The erased region in the change
235- * @param insertedRegion The inserted region in the change
236- */
237-DocumentChange::DocumentChange(const Region& erasedRegion, const Region& insertedRegion)
238- BOOST_NOEXCEPT : erasedRegion_(erasedRegion), insertedRegion_(insertedRegion) {
239- const_cast<Region&>(erasedRegion_).normalize();
240- const_cast<Region&>(erasedRegion_).normalize();
241-}
242-
243-/// Private destructor.
244-DocumentChange::~DocumentChange() BOOST_NOEXCEPT {
245-}
246-
247-
248-// Bookmarker /////////////////////////////////////////////////////////////////////////////////////
249-
250-/**
251- * Private constructor.
252- * @param document The document
253- */
254-Bookmarker::Bookmarker(Document& document) BOOST_NOEXCEPT : document_(document) {
255- document.addListener(*this);
256-}
257-
258-/// Destructor.
259-Bookmarker::~Bookmarker() BOOST_NOEXCEPT {
260- document_.removeListener(*this);
261-}
262-
263-/**
264- * Registers the listener.
265- * @param listener The listener to be registered
266- * @throw std#invalid_argument @a listener is already registered
267- */
268-void Bookmarker::addListener(BookmarkListener& listener) {
269- listeners_.add(listener);
270-}
271-
272-/**
273- * Returns a bidirectional iterator to addresses the first marked line.
274- * @see #end, #next
275- */
276-Bookmarker::Iterator Bookmarker::begin() const {
277- return Iterator(std::begin(markedLines_));
278-}
279-
280-/// Deletes all bookmarks.
281-void Bookmarker::clear() BOOST_NOEXCEPT {
282- if(!markedLines_.empty()) {
283- markedLines_.clear();
284- listeners_.notify(&BookmarkListener::bookmarkCleared);
285- }
286-}
287-
288-/// @see IDocumentListener#documentAboutToBeChanged
289-void Bookmarker::documentAboutToBeChanged(const Document&) {
290- // do nothing
291-}
292-
293-/// @see IDocumentListener#documentChanged
294-void Bookmarker::documentChanged(const Document& document, const DocumentChange& change) {
295- // update markedLines_ based on the change
296- if(&document_ != &document || markedLines_.empty())
297- return;
298- if(change.erasedRegion().first.line != change.erasedRegion().second.line) {
299- // remove the marks on the deleted lines
300- const Index lines = change.erasedRegion().second.line - change.erasedRegion().first.line;
301- const GapVector<Index>::iterator e(std::end(markedLines_));
302- GapVector<Index>::iterator top(find(change.erasedRegion().first.line));
303- if(top != e) {
304- if(*top == change.erasedRegion().first.line)
305- ++top;
306- GapVector<Index>::iterator bottom(find(change.erasedRegion().second.line));
307- if(bottom != e && *bottom == change.erasedRegion().second.line)
308- ++bottom;
309- // slide the following lines before removing
310- if(bottom != e) {
311- for(GapVector<Index>::iterator i(bottom); i != e; ++i)
312- *i -= lines; // ??? C4267@MSVC9
313- }
314- markedLines_.erase(top, bottom); // GapVector<>.erase does not return an iterator
315- }
316- }
317- if(change.insertedRegion().first.line != change.insertedRegion().second.line) {
318- const Index lines = change.insertedRegion().second.line - change.insertedRegion().first.line;
319- GapVector<Index>::iterator i(find(change.insertedRegion().first.line));
320- if(i != std::end(markedLines_)) {
321- if(*i == change.insertedRegion().first.line && change.insertedRegion().first.offsetInLine != 0)
322- ++i;
323- for(const GapVector<Index>::iterator e(std::end(markedLines_)); i != e; ++i)
324- *i += lines; // ??? - C4267@MSVC9
325- }
326- }
327-}
328-
329-/**
330- * Returns a bidirectional iterator to addresses just beyond the last marked line.
331- * @see #begin, #next
332- */
333-Bookmarker::Iterator Bookmarker::end() const {
334- return Iterator(std::end(markedLines_));
335-}
336-
337-inline GapVector<Index>::iterator Bookmarker::find(Index line) const BOOST_NOEXCEPT {
338- // TODO: can write faster implementation (and design) by internal.searchBound().
339- Bookmarker& self = const_cast<Bookmarker&>(*this);
340- return boost::lower_bound(self.markedLines_, line);
341-}
342-
343-/**
344- * Returns @c true if the specified line is bookmarked.
345- * @param line The line
346- * @throw BadPositionException @a line is outside of the document
347- */
348-bool Bookmarker::isMarked(Index line) const {
349- if(line >= document_.numberOfLines())
350- throw BadPositionException(Position(line, 0));
351- const GapVector<Index>::const_iterator i(find(line));
352- return i != std::end(markedLines_) && *i == line;
353-}
354-
355-/**
356- * Sets or clears the bookmark of the specified line.
357- * @param line The line
358- * @param set @c true to set bookmark, @c false to clear
359- * @throw BadPositionException @a line is outside of the document
360- */
361-void Bookmarker::mark(Index line, bool set) {
362- if(line >= document_.numberOfLines())
363- throw BadPositionException(Position(line, 0));
364- const GapVector<Index>::iterator i(find(line));
365- if(i != std::end(markedLines_) && *i == line) {
366- if(!set) {
367- markedLines_.erase(i);
368- listeners_.notify<Index>(&BookmarkListener::bookmarkChanged, line);
369- }
370- } else {
371- if(set) {
372- markedLines_.insert(i, line);
373- listeners_.notify<Index>(&BookmarkListener::bookmarkChanged, line);
374- }
375- }
376-}
377-
378-/**
379- * Returns the line number of the next/previous bookmarked line.
380- * @param from The start line number to search
381- * @param direction The direction to search
382- * @param wrapAround Set @c true to enable "wrapping around". If set, this method starts again from
383- * the end (in forward case) or beginning (in backward case) of the document when
384- * the reached the end or beginning of the document
385- * @param marks
386- * @return The next bookmarked line or @c boost#none if not found
387- * @throw BadPositionException @a line is outside of the document
388- * @see #begin, #end
389- */
390-boost::optional<Index> Bookmarker::next(Index from, Direction direction, bool wrapAround /* = true */, size_t marks /* = 1 */) const {
391- // this code is tested by 'test/document-test.cpp'
392- if(from >= document_.numberOfLines())
393- throw BadPositionException(Position(from, 0));
394- else if(marks == 0 || markedLines_.empty())
395- return boost::none;
396- else if(marks > markedLines_.size()) {
397- if(!wrapAround)
398- return boost::none;
399- marks = marks % markedLines_.size();
400- if(marks == 0)
401- marks = markedLines_.size();
402- }
403-
404- size_t i = static_cast<GapVector<Index>::const_iterator>(find(from)) - std::begin(markedLines_);
405- if(direction == Direction::FORWARD) {
406- if(i == markedLines_.size()) {
407- if(!wrapAround)
408- return boost::none;
409- i = 0;
410- --marks;
411- } else if(markedLines_[i] != from)
412- --marks;
413- if((i += marks) >= markedLines_.size()) {
414- if(wrapAround)
415- i -= markedLines_.size();
416- else
417- return boost::none;
418- }
419- } else {
420- if(i < marks) {
421- if(wrapAround)
422- i += markedLines_.size();
423- else
424- return boost::none;
425- }
426- i -= marks;
427- }
428- return markedLines_[i];
429-}
430-
431-/// Returns the number of the lines bookmarked.
432-size_t Bookmarker::numberOfMarks() const BOOST_NOEXCEPT {
433- return markedLines_.size();
434-}
435-
436-/**
437- * Removes the listener.
438- * @param listener The listener to be removed
439- * @throw std#invalid_argument @a listener is not registered
440- */
441-void Bookmarker::removeListener(BookmarkListener& listener) {
442- listeners_.remove(listener);
443-}
444-
445-/**
446- * Toggles the bookmark of the spcified line.
447- * @param line The line
448- * @throw BadPositionException @a line is outside of the document
449- */
450-void Bookmarker::toggle(Index line) {
451- if(line >= document_.numberOfLines())
452- throw BadPositionException(Position(line, 0));
453- const GapVector<Index>::iterator i(find(line));
454- if(i == std::end(markedLines_) || *i != line)
455- markedLines_.insert(i, line);
456- else
457- markedLines_.erase(i);
458- listeners_.notify<Index>(&BookmarkListener::bookmarkChanged, line);
459-}
460-
461-
462-// DocumentPartitioner ////////////////////////////////////////////////////////////////////////////
463-
464-/// Constructor.
465-DocumentPartitioner::DocumentPartitioner() /*throw()*/ : document_(nullptr) {
466-}
467-
468-/// Destructor.
469-DocumentPartitioner::~DocumentPartitioner() /*throw()*/ {
470-}
471-
472-
473-// Document ///////////////////////////////////////////////////////////////////////////////////////
474-
475-/**
476- * @class ascension::kernel::Document
477- * A document manages a text content and supports text manipulations.
478- *
479- * All text content is represented in UTF-16. To treat this as UTF-32, use
480- * @c DocumentCharacterIterator.
481- *
482- * A document manages also its operation history, encoding, and newlines and writes to or reads the
483- * content from files or streams.
484- *
485- * @c #insert inserts a text string into any position. @c #erase deletes any text region.
486- * Other classes also provide text manipulation for the document.
487- *
488- * @c #insert and @c #erase methods throw @c DocumentCantChangeException when the change was
489- * rejected. This occurs if the the document was not marked modified and the document input's
490- * @c IDocumentInput#isChangeable returned @c false.
491- *
492- * <h3>Revision and Modification Signature</h3>
493- *
494- * A document manages the revision number indicates how many times the document was changed. This
495- * value is initially zero. @c #replace, @c #redo and @c #resetContent methods increment and
496- * @c #undo method decrements the revision number. The current revision number can be obtained
497- * by @c #revisionNumber method. It is guarenteed that the contents of a document correspond to
498- * same revision number are equivalent.
499- *
500- * Clients of @c Document can query if "the document has been changed" by @c #isModified method.
501- * The modification signature (state) is determined based on the revision of the document. In a
502- * word, the document is treated as "modified" if the revision number is different from the one at
503- * "unmodified". For example (parenthesized numbers are the revisions),
504- *
505- * @code
506- * Document d; // a document is unmodified initially (0)
507- * insert(d, text); // increment the revision (1)
508- * d.isModified(); // true
509- * d.undo(); // decrement the revision (0)
510- * d.isModified(); // false
511- * @endcode
512- *
513- * Use @c #markUnmodified method to set the current revision as unmodified.
514- *
515- * To set the modification state as modified explicitly, use @c #setModified method. Called this
516- * method, the document never becomes unmodified unless @c #markUnmodified called.
517- *
518- * @code
519- * Document d;
520- * insert(d, text);
521- * d.markUnmodified(); // the revision 1 is as unmodified
522- * d.undo(); // modified (0)
523- * d.redo(); // unmodified (1)
524- * d.setModified(); // modified (1)
525- * d.undo(); // modified (0)
526- * @endcode
527- *
528- * <h3>Partitions</h3>
529- *
530- * A document can be devides into a sequence of semantic segments called partition.
531- * Document partitioners expressed by @c DocumentPartitioner class define these
532- * partitioning. Each partitions have its content type and region (see @c DocumentPartition).
533- * To set the new partitioner, use @c #setPartitioner method. The partitioner's ownership
534- * will be transferred to the document.
535- *
536- * @see DocumentPartitioner, Point, EditPoint
537- */
538-
539-const DocumentPropertyKey Document::TITLE_PROPERTY;
540-
541-/**
542- * Returns the accessible region of the document. The returned region is normalized.
543- * @see #region, DocumentAccessViolationException
544- */
545-Region Document::accessibleRegion() const BOOST_NOEXCEPT {
546- return (accessibleRegion_.get() != nullptr) ? Region(accessibleRegion_->first, *accessibleRegion_->second) : region();
547-}
548-
549-#if 0
550-/**
551- * Registers the compound change listener.
552- * @param listener the listener to be registered
553- * @throw std#invalid_argument @a listener is already registered
554- */
555-void Document::addCompoundChangeListener(ICompoundChangeListener& listener) {
556- compoundChangeListeners_.add(listener);
557-}
558-#endif
559-
560-/**
561- * Registers the document listener with the document. After registration @a listener is notified
562- * about each modification of this document.
563- * @param listener The listener to be registered
564- * @throw std#invalid_argument @a listener is already registered
565- */
566-void Document::addListener(DocumentListener& listener) {
567- if(boost::range::find(listeners_, &listener) != boost::end(listeners_))
568- throw invalid_argument("the listener already has been registered.");
569- listeners_.push_back(&listener);
570-}
571-
572-/**
573- * Registers the document partitioning listener with the document.
574- * @param listener The listener to be registered
575- * @throw std#invalid_argument @a listener is already registered
576- */
577-void Document::addPartitioningListener(DocumentPartitioningListener& listener) {
578- partitioningListeners_.add(listener);
579-}
580-
581-/**
582- * Registers the document listener as one which is notified before those document listeners
583- * registered with @c #addListener are notified.
584- * @internal This method is not for public use.
585- * @param listener The listener to be registered
586- * @throw std#invalid_argument @a listener is already registered
587- */
588-void Document::addPrenotifiedListener(DocumentListener& listener) {
589- if(boost::range::find(prenotifiedListeners_, &listener) != boost::end(prenotifiedListeners_))
590- throw invalid_argument("the listener already has been registered.");
591- prenotifiedListeners_.push_back(&listener);
592-}
593-
594-/**
595- * Registers the rollback listener.
596- * @param listener The listener to be registered
597- * @throw std#invalid_argument @a listener is already registered
598- */
599-void Document::addRollbackListener(DocumentRollbackListener& listener) {
600- rollbackListeners_.add(listener);
601-}
602-
603-/// @c #resetContent invokes this method finally. Default implementation does nothing.
604-void Document::doResetContent() {
605-}
606-
607-void Document::fireDocumentAboutToBeChanged() BOOST_NOEXCEPT {
608- if(partitioner_.get() != nullptr)
609- partitioner_->documentAboutToBeChanged();
610- BOOST_FOREACH(DocumentListener* listener, prenotifiedListeners_)
611- listener->documentAboutToBeChanged(*this);
612- BOOST_FOREACH(DocumentListener* listener, listeners_)
613- listener->documentAboutToBeChanged(*this);
614-}
615-
616-void Document::fireDocumentChanged(const DocumentChange& c, bool updateAllPoints /* = true */) BOOST_NOEXCEPT {
617- if(partitioner_.get() != nullptr)
618- partitioner_->documentChanged(c);
619- if(updateAllPoints)
620- updatePoints(c);
621- BOOST_FOREACH(DocumentListener* listener, prenotifiedListeners_)
622- listener->documentChanged(*this, c);
623- BOOST_FOREACH(DocumentListener* listener, listeners_)
624- listener->documentChanged(*this, c);
625-}
626-
627-/**
628- * Returns the number of characters (UTF-16 code units) in the document.
629- * @param newline The method to count newlines
630- * @return The number of characters
631- */
632-Index Document::length(const Newline& newline /* = Newline::USE_INTRINSIC_VALUE */) const BOOST_NOEXCEPT {
633- const Newline resolvedNewline(resolveNewline(*this, newline));
634- if(resolvedNewline.isLiteral())
635- return length_ + (numberOfLines() - 1) * ((resolvedNewline != Newline::CARRIAGE_RETURN_FOLLOWED_BY_LINE_FEED) ? 1 : 2);
636- assert(resolvedNewline == Newline::USE_INTRINSIC_VALUE);
637- Index len = length_;
638- const Index lines = numberOfLines();
639- assert(lines > 0);
640- for(Index i = 0; i < lines - 1; ++i)
641- len += lines_[i]->newline_.asString().length();
642- return len;
643-}
644-
645-/**
646- * Returns the offset of the line.
647- * @param line The line
648- * @param newline The line representation policy for character counting
649- * @throw BadPostionException @a line is outside of the document
650- */
651-Index Document::lineOffset(Index line, const Newline& newline) const {
652- if(line >= numberOfLines())
653- throw BadPositionException(Position(line, 0));
654-
655- const Newline resolvedNewline(resolveNewline(*this, newline));
656- Index offset = 0, eolLength = resolvedNewline.isLiteral() ? resolvedNewline.asString().length() : 0;
657- assert(eolLength != 0 || resolvedNewline == Newline::USE_INTRINSIC_VALUE);
658- for(Index i = 0; i < line; ++i) {
659- const Line& ln = *lines_[i];
660- offset += ln.text_.length();
661- if(newline == Newline::USE_INTRINSIC_VALUE)
662- offset += ln.newline_.asString().length();
663- else
664- offset += eolLength;
665- }
666- return offset;
667-}
668-#if 0
669-/**
670- * Locks the document.
671- * @param locker the object locks the document. this object is used with later @c #unlock call
672- * @retval @c true Succeeded to lock
673- * @retval @c false Failed to lock because the other object already had locked, or the document's
674- * input rejected the lock (only when the document was not marked as modified)
675- * @throw ReadOnlyDocumentException The document is read only
676- * @throw NullPointerException @a locker is @c null
677- * @see #unlock
678- */
679-bool Document::lock(const void* locker) {
680- // TODO: should support exclusive operation.
681- if(isReadOnly())
682- throw ReadOnlyDocumentException();
683- else if(locker == nullptr)
684- throw NullPointerException("locker");
685- else if(locker_ != nullptr || (isModified() && input_.get() != nullptr && !input_->isChangeable()))
686- return false;
687- locker_ = locker;
688- return true;
689-}
690-#endif
691-/**
692- * Marks the document unmodified at the current revision.
693- * For details about modification signature, see the documentation of @c Document class.
694- * @see #isModified, #setModified, #ModificationSignChangedSignal
695- */
696-void Document::markUnmodified() BOOST_NOEXCEPT {
697- if(isModified()) {
698- lastUnmodifiedRevisionNumber_ = revisionNumber();
699- modificationSignChangedSignal_(*this);
700- }
701-}
702-
703-/**
704- * Narrows the accessible area to the specified region.
705- * If the document is already narrowed, the accessible region will just change to @a region. In
706- * this case, @a region can be wider than the current accessible region.
707- * @param region The region
708- * @throw BadRegionException @a region intersects with the outside of the document
709- * @see #isNarrowed, #widen, #AccessibleRegionChangedSignal
710- */
711-void Document::narrowToRegion(const Region& region) {
712- if(region.end() > this->region().end())
713- throw BadRegionException(region);
714- else if(region == accessibleRegion())
715- return;
716- if(accessibleRegion_.get() == 0) {
717- accessibleRegion_.reset(new pair<Position, unique_ptr<Point>>);
718- accessibleRegion_->second.reset(new Point(*this, region.end()));
719- } else
720- accessibleRegion_->second->moveTo(region.end());
721- accessibleRegion_->first = region.beginning();
722-// BOOST_FOREACH(Point* p, points_) {
723-// if(p->isExcludedFromRestriction())
724-// p->normalize();
725-// }
726- accessibleRegionChangedSignal_(*this);
727-}
728-
729-/**
730- * Removes the document listener from the document.
731- * @param listener The listener to be removed
732- * @throw std#invalid_argument @a listener is not registered
733- */
734-void Document::removeListener(DocumentListener& listener) {
735- const list<DocumentListener*>::iterator i(boost::range::find(listeners_, &listener));
736- if(i == boost::end(listeners_))
737- throw invalid_argument("the listener is not registered.");
738- listeners_.erase(i);
739-}
740-
741-/**
742- * Removes the document partitioning listener from the document.
743- * @param listener The listener to be removed
744- * @throw std#invalid_argument @a listener is not registered
745- */
746-void Document::removePartitioningListener(DocumentPartitioningListener& listener) {
747- partitioningListeners_.remove(listener);
748-}
749-
750-/**
751- * Removes the pre-notified document listener from the document.
752- * @internal This method is not for public use.
753- * @param listener The listener to be removed
754- * @throw std#invalid_argument @a listener is not registered
755- */
756-void Document::removePrenotifiedListener(DocumentListener& listener) {
757- const list<DocumentListener*>::iterator i(boost::range::find(prenotifiedListeners_, &listener));
758- if(i == boost::end(prenotifiedListeners_))
759- throw invalid_argument("the listener is not registered.");
760- prenotifiedListeners_.erase(i);
761-}
762-
763-/**
764- * Removes the rollback listener.
765- * @param listener The listener to be removed
766- * @throw std#invalid_argument @a listener is not registered
767- */
768-void Document::removeRollbackListener(DocumentRollbackListener& listener) {
769- rollbackListeners_.remove(listener);
770-}
771-
772-/**
773- * Resets and initializes the content of the document. Does the following:
774- * - Clears the text buffer, invokes the two methods of @c IDocumentListener and increments the
775- * revision number even if the document was empty.
776- * - Moves the all point to the beginning of the document.
777- * - Clears the undo/redo buffers.
778- * - Resets the modification flag to @c false.
779- * - Resets the read-only flag to @c false.
780- * - Revokes the narrowing.
781- * - Removes the all bookmarks.
782- * @note This method does not call @c IDocumentInput#isChangeable for rejection.
783- * @see #doResetContent
784- */
785-void Document::resetContent() {
786- if(lines_.empty()) // called by constructor
787- lines_.insert(begin(lines_), new Line(0));
788- else {
789- widen();
790- BOOST_FOREACH(Point* p, points_)
791- p->moveTo(Position(0, 0));
792- bookmarker_->clear();
793-
794- fireDocumentAboutToBeChanged();
795- if(length_ != 0) {
796- assert(!lines_.empty());
797- for(size_t i = 0, c = lines_.size(); i < c; ++i)
798- delete lines_[i];
799- lines_.clear();
800- lines_.insert(begin(lines_), new Line(revisionNumber_ + 1));
801- length_ = 0;
802- ++revisionNumber_;
803- }
804- const DocumentChange ca(region(), Region(region().beginning()));
805- fireDocumentChanged(ca, false);
806- }
807-
808- setReadOnly(false);
809- markUnmodified();
810- clearUndoBuffer();
811- onceUndoBufferCleared_ = false;
812- doResetContent();
813-}
814-
815-/**
816- * Sets the new document input.
817- * @param newInput The new document input. Can be @c null
818- */
819-void Document::setInput(weak_ptr<DocumentInput> newInput) BOOST_NOEXCEPT {
820- input_ = newInput;
821-}
822-
823-/**
824- * Marks the document modified.
825- * For details about modification signature, see the documentation of @c Document class.
826- * @see #isModified, #markUnmodified, #dModificationSignChangedSignal
827- */
828-void Document::setModified() BOOST_NOEXCEPT {
829- const bool modified = isModified();
830- lastUnmodifiedRevisionNumber_ = numeric_limits<size_t>::max();
831- if(!modified)
832- modificationSignChangedSignal_(*this);
833-}
834-
835-/**
836- * Sets the new document partitioner.
837- * @param newPartitioner The new partitioner. The ownership will be transferred to the callee
838- */
839-void Document::setPartitioner(unique_ptr<DocumentPartitioner> newPartitioner) BOOST_NOEXCEPT {
840- partitioner_ = move(newPartitioner);
841- if(partitioner_.get() != nullptr)
842- partitioner_->install(*this);
843- partitioningChanged(region());
844-}
845-
846-/**
847- * Associates the given property with the document.
848- * @param key The key of the property
849- * @param property The property value
850- * @see #property, #PropertyChangedSignal
851- */
852-void Document::setProperty(const DocumentPropertyKey& key, const String& property) {
853- map<const DocumentPropertyKey*, unique_ptr<String>>::iterator i(properties_.find(&key));
854- if(i == end(properties_))
855- properties_.insert(make_pair(&key, new String(property)));
856- else
857- i->second->assign(property);
858- propertyChangedSignal_(*this, key);
859-}
860-
861-/**
862- * Makes the document read only or not.
863- * @see ReadOnlyDocumentException, #isReadOnly, #ReadOnlySignChangedSignal
864- */
865-void Document::setReadOnly(bool readOnly /* = true */) BOOST_NOEXCEPT {
866- if(readOnly != isReadOnly()) {
867- readOnly_ = readOnly;
868- readOnlySignChangedSignal_(*this);
869- }
870-}
871-#if 0
872-/**
873- * Unlocks the document.
874- * @param locker The object used with previous @c #lock call
875- * @throw IllegalStateException The document is not locked
876- * @throw NullPointerException @a locker is @c null
877- * @throw std#invalid_argument @a locker is not the object used with @c #lock call
878- * @see #lock
879- */
880-void Document::unlock(const void* locker) {
881- // TODO: support exclusive operation.
882- if(locker_ == nullptr)
883- throw IllegalStateException("the document's input is not locked.");
884- else if(locker == nullptr)
885- throw NullPointerException("locker");
886- else if(locker != locker_)
887- throw invalid_argument("locker");
888- locker_ = nullptr;
889-}
890-#endif
891-/**
892- * Informs the document change to the adapting points.
893- * @param change The document change
894- */
895-
896-inline void Document::updatePoints(const DocumentChange& change) BOOST_NOEXCEPT {
897- BOOST_FOREACH(Point* p, points_) {
898- if(p->adaptsToDocument())
899- p->update(change);
900- }
901-}
902-
903-/**
904- * Revokes the narrowing.
905- * @see #isNarrowed, #narrow, #AccessibleRegionChangedSignal
906- */
907-void Document::widen() BOOST_NOEXCEPT {
908- if(accessibleRegion_.get() != nullptr) {
909- accessibleRegion_.reset();
910- accessibleRegionChangedSignal_(*this);
911- }
912-}
913-
914-
915-// Document.Line //////////////////////////////////////////////////////////////////////////////////
916-
917-Document::Line::Line(size_t revisionNumber) BOOST_NOEXCEPT : newline_(ASCENSION_DEFAULT_NEWLINE), revisionNumber_(revisionNumber) {
918-}
919-
920-Document::Line::Line(size_t revisionNumber, const String& text,
921- const Newline& newline /* = ASCENSION_DEFAULT_NEWLINE */) : text_(text), newline_(newline), revisionNumber_(revisionNumber) {
922-}
923-
924-
925-// Document.DefaultContentTypeInformationProvider /////////////////////////////////////////////////
926-
927-Document::DefaultContentTypeInformationProvider::DefaultContentTypeInformationProvider() : syntax_(new IdentifierSyntax()) {
928-}
929-
930-Document::DefaultContentTypeInformationProvider::~DefaultContentTypeInformationProvider() BOOST_NOEXCEPT {
931- delete syntax_;
932-}
933-
934-
935-// CompoundChangeSaver ////////////////////////////////////////////////////////////////////////////
936-
937-/**
938- * @class ascension::kernel::CompoundChangeSaver
939- *
940- * Calls automatically @c Document#beginCompoundChange and @c Document#endCompoundChange.
941- *
942- * @code
943- * extern Document* target;
944- * CompoundChangeSaver saver(target);
945- * target-&gt;mayThrow();
946- * // target-&gt;endCompoundChange() will be called automatically
947- * @endcode
948- *
949- * @note This class is not intended to be subclassed.
950- */
951-
952-/**
953- * Constructor calls @c Document#beginCompoundChange.
954- * @param document The document this object manages. if this is @c null, the object does nothing
955- * @throw ... Any exceptions @c Document#beginCompoundChange throws
956- */
957-CompoundChangeSaver::CompoundChangeSaver(Document* document) : document_(document) {
958- if(document_ != nullptr)
959- document_->beginCompoundChange();
960-}
961-
962-/**
963- * Destructor calls @c Document#endCompoundChange.
964- * @throw ... Any exceptions @c Document#endCompoundChange throws
965- */
966-CompoundChangeSaver::~CompoundChangeSaver() {
967- if(document_ != nullptr)
968- document_->endCompoundChange();
969-}
970-
971-#if 0
972-// DocumentLocker /////////////////////////////////////////////////////////////////////////////////
973-
974-/**
975- * @class ascension::kernel::DocumentLocker
976- *
977- * Calls @c Document#lock and @c Document#unlock automatically.
978- *
979- * @note This class is not intended to be subclassed.
980- */
981-
982-/**
983- * Constructor calls @c Document#lock.
984- * @param document The document to lock
985- * @throw ReadOnlyDocumentException The document is read only
986- * @throw DocumentCantChangeException Failed to lock the document
987- */
988-DocumentLocker::DocumentLocker(Document& document) : document_((document.locker() == nullptr) ? &document : nullptr) {
989- if(document_ != nullptr && !document_->lock(this)) // manage lock if there is not an active lock
990- throw DocumentCantChangeException();
991-}
992-
993-/// Destructor calls @c Document#unlock.
994-DocumentLocker::~DocumentLocker() /*throw()*/ {
995- if(document_ != nullptr)
996- document_->unlock(this);
997-}
998-#endif
999-
1000-// DocumentCharacterIterator //////////////////////////////////////////////////////////////////////
1001-
1002-/**
1003- * @class ascension::kernel::DocumentCharacterIterator
1004- * Bidirectional iterator scans characters in the specified document.
1005- *
1006- * @c #current implementation of this class returns a character at which the iterator addresses. A
1007- * returned character is as a UTF-32 code unit (not UTF-16). In the following cases, returns a
1008- * special value depending on the context:
1009- *
1010- * - @c CharacterIterator#DONE at the end of the region of the iterator
1011- * - @c LINE_SEPARATOR at the end of the line
1012- * - a raw code unit value at any unpaired surrogate
1013- *
1014- * This class can't detect any change of the document. When the document changed, the existing
1015- * iterators may be invalid.
1016- *
1017- * @note This class is not intended to be subclassed.
1018- */
1019-
1020-const CharacterIterator::ConcreteTypeTag
1021- DocumentCharacterIterator::CONCRETE_TYPE_TAG_ = CharacterIterator::ConcreteTypeTag();
1022-
1023-/// Default constructor makes an invalid iterator object.
1024-DocumentCharacterIterator::DocumentCharacterIterator() BOOST_NOEXCEPT
1025- : CharacterIterator(CONCRETE_TYPE_TAG_), document_(nullptr), line_(0) {
1026-}
1027-
1028-/**
1029- * Constructor. The iteration region is the accessible area of the document.
1030- * @param document The document to iterate
1031- * @param position The position at which the iteration starts
1032- * @throw BadPositionException @a position is outside of the accessible area of the document
1033- */
1034-DocumentCharacterIterator::DocumentCharacterIterator(const Document& document, const Position& position) :
1035- CharacterIterator(CONCRETE_TYPE_TAG_), document_(&document),
1036- region_(document.region()), line_(&document.line(position.line)), p_(position) {
1037- if(!region_.includes(p_))
1038- throw BadPositionException(p_);
1039-}
1040-
1041-/**
1042- * Constructor. The iteration is started at @a region.beginning().
1043- * @param document The document to iterate
1044- * @param region The region to iterate
1045- * @throw BadRegionException @a region intersects outside of the document
1046- */
1047-DocumentCharacterIterator::DocumentCharacterIterator(const Document& document, const Region& region) :
1048- CharacterIterator(CONCRETE_TYPE_TAG_), document_(&document), region_(region),
1049- line_(&document.line(region.beginning().line)), p_(region.beginning()) {
1050- region_.normalize();
1051- if(!document.region().encompasses(region_))
1052- throw BadRegionException(region_);
1053-}
1054-
1055-/**
1056- * Constructor.
1057- * @param document The document to iterate
1058- * @param region The region to iterate
1059- * @param position The position at which the iteration starts
1060- * @throw BadRegionException @a region intersects outside of the document
1061- * @throw BadPositionException @a position is outside of @a region
1062- */
1063-DocumentCharacterIterator::DocumentCharacterIterator(const Document& document, const Region& region, const Position& position) :
1064- CharacterIterator(CONCRETE_TYPE_TAG_), document_(&document), region_(region), line_(&document.line(position.line)), p_(position) {
1065- region_.normalize();
1066- if(!document.region().encompasses(region_))
1067- throw BadRegionException(region_);
1068- else if(!region_.includes(p_))
1069- throw BadPositionException(p_);
1070-}
1071-
1072-/// Copy-constructor.
1073-DocumentCharacterIterator::DocumentCharacterIterator(const DocumentCharacterIterator& other) BOOST_NOEXCEPT :
1074- text::CharacterIterator(other), document_(other.document_), region_(other.region_), line_(other.line_), p_(other.p_) {
1075-}
1076-
1077-/// @see text#CharacterIterator#current
1078-CodePoint DocumentCharacterIterator::current() const BOOST_NOEXCEPT {
1079- if(document() == nullptr || tell() == region().second)
1080- return DONE;
1081- else if(tell().offsetInLine == line().length())
1082- return LINE_SEPARATOR;
1083- else
1084- return (surrogates::isHighSurrogate((*line_)[tell().offsetInLine])
1085- && tell().offsetInLine + 1 < line_->length() && surrogates::isLowSurrogate((*line_)[tell().offsetInLine + 1])) ?
1086- surrogates::decode((*line_)[tell().offsetInLine], (*line_)[tell().offsetInLine + 1]) : (*line_)[tell().offsetInLine];
1087-}
1088-
1089-/// @see text#CharacterIterator#doAssign
1090-void DocumentCharacterIterator::doAssign(const CharacterIterator& other) {
1091- CharacterIterator::operator=(other);
1092- const DocumentCharacterIterator& r = static_cast<const DocumentCharacterIterator&>(other);
1093- document_ = r.document_;
1094- line_ = r.line_;
1095- p_ = r.p_;
1096- region_ = r.region_;
1097-}
1098-
1099-/// @see text#CharacterIterator#doClone
1100-unique_ptr<CharacterIterator> DocumentCharacterIterator::doClone() const {
1101- return unique_ptr<CharacterIterator>(new DocumentCharacterIterator(*this));
1102-}
1103-
1104-/// @see text#CharacterIterator#doFirst
1105-void DocumentCharacterIterator::doFirst() {
1106- seek(region_.first);
1107-}
1108-
1109-/// @see text#CharacterIterator#doLast
1110-void DocumentCharacterIterator::doLast() {
1111- seek(region_.second);
1112-}
1113-
1114-/// @see text#CharacterIterator#doEquals
1115-bool DocumentCharacterIterator::doEquals(const CharacterIterator& other) const {
1116- const DocumentCharacterIterator& o = static_cast<const DocumentCharacterIterator&>(other);
1117- if(document() != o.document())
1118- return false;
1119- return document() == nullptr || tell() == o.tell();
1120-}
1121-
1122-/// @see text#CharacterIterator#doLess
1123-bool DocumentCharacterIterator::doLess(const CharacterIterator& other) const {
1124- return tell() < static_cast<const DocumentCharacterIterator&>(other).tell();
1125-}
1126-
1127-/// @see text#CharacterIterator#doNext
1128-void DocumentCharacterIterator::doNext() {
1129- if(!hasNext())
1130-// throw out_of_range("the iterator is at the last.");
1131- return;
1132- else if(tell().offsetInLine == line_->length()) {
1133- line_ = &document_->line(++p_.line);
1134- p_.offsetInLine = 0;
1135- } else if(++p_.offsetInLine < line_->length()
1136- && surrogates::isLowSurrogate((*line_)[tell().offsetInLine])
1137- && surrogates::isHighSurrogate((*line_)[tell().offsetInLine - 1]))
1138- ++p_.offsetInLine;
1139-}
1140-
1141-/// @see text#CharacterIterator#doPrevious
1142-void DocumentCharacterIterator::doPrevious() {
1143- if(!hasPrevious())
1144-// throw out_of_range("the iterator is at the first.");
1145- return;
1146- else if(tell().offsetInLine == 0)
1147- p_.offsetInLine = (line_ = &document_->line(--p_.line))->length();
1148- else if(--p_.offsetInLine > 0
1149- && surrogates::isLowSurrogate((*line_)[tell().offsetInLine])
1150- && surrogates::isHighSurrogate((*line_)[tell().offsetInLine - 1]))
1151- --p_.offsetInLine;
1152-}
1153-
1154-/**
1155- * Sets the region of the iterator. The current position will adjusted.
1156- * @param newRegion The new region to set
1157- * @throw BadRegionException @a newRegion intersects outside of the document
1158- */
1159-void DocumentCharacterIterator::setRegion(const Region& newRegion) {
1160- const Position e(document_->region().second);
1161- if(newRegion.first > e || newRegion.second > e)
1162- throw BadRegionException(newRegion);
1163- if(!(region_ = newRegion).includes(tell()))
1164- seek(tell());
1165-}
1166-
1167-
1168-// NullPartitioner ////////////////////////////////////////////////////////////////////////////////
1169-
1170-/// Constructor.
1171-NullPartitioner::NullPartitioner() BOOST_NOEXCEPT : p_(DEFAULT_CONTENT_TYPE, Region(Position(0, 0), Position(0, 0))), changed_(true) {
1172-}
1173-
1174-/// @see DocumentPartitioner#documentAboutToBeChanged
1175-void NullPartitioner::documentAboutToBeChanged() BOOST_NOEXCEPT {
1176-}
1177-
1178-/// @see DocumentPartitioner#documentChanged
1179-void NullPartitioner::documentChanged(const DocumentChange&) BOOST_NOEXCEPT {
1180- changed_ = true;
1181-}
1182-
1183-/// @see DocumentPartitioner#doGetPartition
1184-void NullPartitioner::doGetPartition(const Position&, DocumentPartition& partition) const BOOST_NOEXCEPT {
1185- if(changed_) {
1186- const_cast<NullPartitioner*>(this)->p_.region.second = document()->region().second;
1187- changed_ = false;
1188- }
1189- partition = p_;
1190-}
1191-
1192-/// @see DocumentPartitioner#doInstall
1193-void NullPartitioner::doInstall() BOOST_NOEXCEPT {
1194- changed_ = true;
1195-}
63+const Newline Newline::USE_DOCUMENT_INPUT(0x80000001u);
64+
65+
66+// kernel free functions //////////////////////////////////////////////////////////////////////////
67+
68+/**
69+ * Writes the content of the document to the specified output stream.
70+ * <p>This method does not write Unicode byte order mark.</p>
71+ * <p>This method explicitly flushes the output stream.</p>
72+ * @param out The output stream
73+ * @param document The document
74+ * @param region The region to be written (This region is not restricted with narrowing)
75+ * @param newline The newline representation
76+ * @return @a out
77+ * @throw ... Any exceptions out.operator bool, out.write and out.flush throw
78+ * @see Newline#asString, Document#insert
79+ */
80+basic_ostream<Char>& kernel::writeDocumentToStream(basic_ostream<Char>& out,
81+ const Document& document, const Region& region, const Newline& newline /* = Newline::USE_INTRINSIC_VALUE */) {
82+ const Position& beginning = region.beginning();
83+ const Position end = min(region.end(), document.region().second);
84+ if(beginning.line == end.line) { // shortcut for single-line
85+ if(out) {
86+ // TODO: this cast may be danger.
87+ out.write(document.line(end.line).data() + beginning.offsetInLine, static_cast<streamsize>(end.offsetInLine - beginning.offsetInLine));
88+ }
89+ } else {
90+ const Newline resolvedNewline(resolveNewline(document, newline));
91+ const String eol(resolvedNewline.isLiteral() ? resolvedNewline.asString() : String());
92+ assert(!eol.empty() || resolvedNewline == Newline::USE_INTRINSIC_VALUE);
93+ for(Index i = beginning.line; out; ++i) {
94+ const Document::Line& line = document.getLineInformation(i);
95+ const Index first = (i == beginning.line) ? beginning.offsetInLine : 0;
96+ const Index last = (i == end.line) ? end.offsetInLine : line.text().length();
97+ out.write(line.text().data() + first, static_cast<streamsize>(last - first));
98+ if(i == end.line)
99+ break;
100+ if(resolvedNewline == Newline::USE_INTRINSIC_VALUE) {
101+ const String intrinsicEol(line.newline().asString());
102+ out.write(intrinsicEol.data(), static_cast<streamsize>(intrinsicEol.length()));
103+ } else
104+ out.write(eol.data(), static_cast<streamsize>(eol.length()));
105+ }
106+ }
107+ return out.flush();
108+}
109+
110+
111+// kernel.positions free functions ////////////////////////////////////////////////////////////////
112+
113+/**
114+ * Returns absolute character offset of the specified position from the start of the document.
115+ * @param document The document
116+ * @param at The position
117+ * @param fromAccessibleStart
118+ * @throw BadPositionException @a at is outside of the document
119+ */
120+Index positions::absoluteOffset(const Document& document, const Position& at, bool fromAccessibleStart) {
121+ if(at > document.region().second)
122+ throw BadPositionException(at);
123+ Index offset = 0;
124+ const Position start((fromAccessibleStart ? document.accessibleRegion() : document.region()).first);
125+ for(Index line = start.line; ; ++line) {
126+ if(line == at.line) {
127+ offset += at.offsetInLine;
128+ break;
129+ } else {
130+ offset += document.lineLength(line) + 1; // +1 is for a newline character
131+ if(line == start.line)
132+ offset -= start.offsetInLine;
133+ }
134+ }
135+ return offset;
136+}
137+
138+/**
139+ * Adapts the specified position to the document change.
140+ * @param position The original position
141+ * @param change The content of the document change
142+ * @param gravity The gravity which determines the direction to which the position should move if
143+ * a text was inserted at the position. If @c FORWARD is specified, the position
144+ * will move to the start of the inserted text (no movement occur). Otherwise, move
145+ * to the end of the inserted text
146+ * @return The result position
147+ */
148+Position positions::updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT {
149+ Position newPosition(position);
150+ if(!change.erasedRegion().isEmpty()) { // deletion
151+ if(position < change.erasedRegion().second) { // the end is behind the current line
152+ if(position <= change.erasedRegion().first)
153+ return newPosition;
154+ else // in the region
155+ newPosition = change.erasedRegion().first;
156+ } else if(position.line > change.erasedRegion().second.line) // in front of the current line
157+ newPosition.line -= change.erasedRegion().second.line - change.erasedRegion().first.line;
158+ else { // the end is the current line
159+ if(position.line == change.erasedRegion().first.line) // the region is single-line
160+ newPosition.offsetInLine -= change.erasedRegion().second.offsetInLine - change.erasedRegion().first.offsetInLine;
161+ else { // the region is multiline
162+ newPosition.line -= change.erasedRegion().second.line - change.erasedRegion().first.line;
163+ newPosition.offsetInLine -= change.erasedRegion().second.offsetInLine - change.erasedRegion().first.offsetInLine;
164+ }
165+ }
166+ }
167+ if(!change.insertedRegion().isEmpty()) { // insertion
168+ if(position < change.insertedRegion().first) // behind the current position
169+ return newPosition;
170+ else if(position == change.insertedRegion().first && gravity == Direction::BACKWARD) // the current position + backward gravity
171+ return newPosition;
172+ else if(position.line > change.insertedRegion().first.line) // in front of the current line
173+ newPosition.line += change.insertedRegion().second.line - change.insertedRegion().first.line;
174+ else { // in the current line
175+ newPosition.line += change.insertedRegion().second.line - change.insertedRegion().first.line;
176+ newPosition.offsetInLine += change.insertedRegion().second.offsetInLine - change.insertedRegion().first.offsetInLine;
177+ }
178+ }
179+ return newPosition;
180+}
181+
182+
183+namespace {
184+#ifdef _DEBUG
185+ // for Document.length_ diagnostic
186+ Index calculateDocumentLength(const Document& document) {
187+ Index c = 0;
188+ const Index lines = document.numberOfLines();
189+ for(Index i = 0; i < lines; ++i)
190+ c += document.lineLength(i);
191+ return c;
192+ }
193+#endif // _DEBUG
194+} // namespace @0
195+
196+
197+// exception classes //////////////////////////////////////////////////////////////////////////////
198+
199+/// Protected default constructor.
200+DocumentCantChangeException::DocumentCantChangeException() {
201+}
202+
203+/// Destructor.
204+DocumentCantChangeException::~DocumentCantChangeException() {
205+}
206+
207+/// Default constructor.
208+ReadOnlyDocumentException::ReadOnlyDocumentException() :
209+ IllegalStateException("The document is readonly. Any edit process is denied.") {
210+}
211+
212+/// Destructor.
213+ReadOnlyDocumentException::~ReadOnlyDocumentException() BOOST_NOEXCEPT {
214+}
215+
216+/// Default constructor.
217+DocumentAccessViolationException::DocumentAccessViolationException() :
218+ invalid_argument("The specified position or region is inaccessible.") {
219+}
220+
221+/// Destructor.
222+DocumentAccessViolationException::~DocumentAccessViolationException() BOOST_NOEXCEPT {
223+}
224+
225+/// Constructor.
226+DocumentInput::ChangeRejectedException::ChangeRejectedException() {
227+}
228+
229+
230+// DocumentChange /////////////////////////////////////////////////////////////////////////////////
231+
232+/**
233+ * Private constructor.
234+ * @param erasedRegion The erased region in the change
235+ * @param insertedRegion The inserted region in the change
236+ */
237+DocumentChange::DocumentChange(const Region& erasedRegion, const Region& insertedRegion)
238+ BOOST_NOEXCEPT : erasedRegion_(erasedRegion), insertedRegion_(insertedRegion) {
239+ const_cast<Region&>(erasedRegion_).normalize();
240+ const_cast<Region&>(erasedRegion_).normalize();
241+}
242+
243+/// Private destructor.
244+DocumentChange::~DocumentChange() BOOST_NOEXCEPT {
245+}
246+
247+
248+// Bookmarker /////////////////////////////////////////////////////////////////////////////////////
249+
250+/**
251+ * Private constructor.
252+ * @param document The document
253+ */
254+Bookmarker::Bookmarker(Document& document) BOOST_NOEXCEPT : document_(document) {
255+ document.addListener(*this);
256+}
257+
258+/// Destructor.
259+Bookmarker::~Bookmarker() BOOST_NOEXCEPT {
260+ document_.removeListener(*this);
261+}
262+
263+/**
264+ * Registers the listener.
265+ * @param listener The listener to be registered
266+ * @throw std#invalid_argument @a listener is already registered
267+ */
268+void Bookmarker::addListener(BookmarkListener& listener) {
269+ listeners_.add(listener);
270+}
271+
272+/**
273+ * Returns a bidirectional iterator to addresses the first marked line.
274+ * @see #end, #next
275+ */
276+Bookmarker::Iterator Bookmarker::begin() const {
277+ return Iterator(std::begin(markedLines_));
278+}
279+
280+/// Deletes all bookmarks.
281+void Bookmarker::clear() BOOST_NOEXCEPT {
282+ if(!markedLines_.empty()) {
283+ markedLines_.clear();
284+ listeners_.notify(&BookmarkListener::bookmarkCleared);
285+ }
286+}
287+
288+/// @see IDocumentListener#documentAboutToBeChanged
289+void Bookmarker::documentAboutToBeChanged(const Document&) {
290+ // do nothing
291+}
292+
293+/// @see IDocumentListener#documentChanged
294+void Bookmarker::documentChanged(const Document& document, const DocumentChange& change) {
295+ // update markedLines_ based on the change
296+ if(&document_ != &document || markedLines_.empty())
297+ return;
298+ if(change.erasedRegion().first.line != change.erasedRegion().second.line) {
299+ // remove the marks on the deleted lines
300+ const Index lines = change.erasedRegion().second.line - change.erasedRegion().first.line;
301+ const GapVector<Index>::iterator e(std::end(markedLines_));
302+ GapVector<Index>::iterator top(find(change.erasedRegion().first.line));
303+ if(top != e) {
304+ if(*top == change.erasedRegion().first.line)
305+ ++top;
306+ GapVector<Index>::iterator bottom(find(change.erasedRegion().second.line));
307+ if(bottom != e && *bottom == change.erasedRegion().second.line)
308+ ++bottom;
309+ // slide the following lines before removing
310+ if(bottom != e) {
311+ for(GapVector<Index>::iterator i(bottom); i != e; ++i)
312+ *i -= lines; // ??? C4267@MSVC9
313+ }
314+ markedLines_.erase(top, bottom); // GapVector<>.erase does not return an iterator
315+ }
316+ }
317+ if(change.insertedRegion().first.line != change.insertedRegion().second.line) {
318+ const Index lines = change.insertedRegion().second.line - change.insertedRegion().first.line;
319+ GapVector<Index>::iterator i(find(change.insertedRegion().first.line));
320+ if(i != std::end(markedLines_)) {
321+ if(*i == change.insertedRegion().first.line && change.insertedRegion().first.offsetInLine != 0)
322+ ++i;
323+ for(const GapVector<Index>::iterator e(std::end(markedLines_)); i != e; ++i)
324+ *i += lines; // ??? - C4267@MSVC9
325+ }
326+ }
327+}
328+
329+/**
330+ * Returns a bidirectional iterator to addresses just beyond the last marked line.
331+ * @see #begin, #next
332+ */
333+Bookmarker::Iterator Bookmarker::end() const {
334+ return Iterator(std::end(markedLines_));
335+}
336+
337+inline GapVector<Index>::iterator Bookmarker::find(Index line) const BOOST_NOEXCEPT {
338+ // TODO: can write faster implementation (and design) by internal.searchBound().
339+ Bookmarker& self = const_cast<Bookmarker&>(*this);
340+ return boost::lower_bound(self.markedLines_, line);
341+}
342+
343+/**
344+ * Returns @c true if the specified line is bookmarked.
345+ * @param line The line
346+ * @throw BadPositionException @a line is outside of the document
347+ */
348+bool Bookmarker::isMarked(Index line) const {
349+ if(line >= document_.numberOfLines())
350+ throw BadPositionException(Position(line, 0));
351+ const GapVector<Index>::const_iterator i(find(line));
352+ return i != std::end(markedLines_) && *i == line;
353+}
354+
355+/**
356+ * Sets or clears the bookmark of the specified line.
357+ * @param line The line
358+ * @param set @c true to set bookmark, @c false to clear
359+ * @throw BadPositionException @a line is outside of the document
360+ */
361+void Bookmarker::mark(Index line, bool set) {
362+ if(line >= document_.numberOfLines())
363+ throw BadPositionException(Position(line, 0));
364+ const GapVector<Index>::iterator i(find(line));
365+ if(i != std::end(markedLines_) && *i == line) {
366+ if(!set) {
367+ markedLines_.erase(i);
368+ listeners_.notify<Index>(&BookmarkListener::bookmarkChanged, line);
369+ }
370+ } else {
371+ if(set) {
372+ markedLines_.insert(i, line);
373+ listeners_.notify<Index>(&BookmarkListener::bookmarkChanged, line);
374+ }
375+ }
376+}
377+
378+/**
379+ * Returns the line number of the next/previous bookmarked line.
380+ * @param from The start line number to search
381+ * @param direction The direction to search
382+ * @param wrapAround Set @c true to enable "wrapping around". If set, this method starts again from
383+ * the end (in forward case) or beginning (in backward case) of the document when
384+ * the reached the end or beginning of the document
385+ * @param marks
386+ * @return The next bookmarked line or @c boost#none if not found
387+ * @throw BadPositionException @a line is outside of the document
388+ * @see #begin, #end
389+ */
390+boost::optional<Index> Bookmarker::next(Index from, Direction direction, bool wrapAround /* = true */, size_t marks /* = 1 */) const {
391+ // this code is tested by 'test/document-test.cpp'
392+ if(from >= document_.numberOfLines())
393+ throw BadPositionException(Position(from, 0));
394+ else if(marks == 0 || markedLines_.empty())
395+ return boost::none;
396+ else if(marks > markedLines_.size()) {
397+ if(!wrapAround)
398+ return boost::none;
399+ marks = marks % markedLines_.size();
400+ if(marks == 0)
401+ marks = markedLines_.size();
402+ }
403+
404+ size_t i = static_cast<GapVector<Index>::const_iterator>(find(from)) - std::begin(markedLines_);
405+ if(direction == Direction::FORWARD) {
406+ if(i == markedLines_.size()) {
407+ if(!wrapAround)
408+ return boost::none;
409+ i = 0;
410+ --marks;
411+ } else if(markedLines_[i] != from)
412+ --marks;
413+ if((i += marks) >= markedLines_.size()) {
414+ if(wrapAround)
415+ i -= markedLines_.size();
416+ else
417+ return boost::none;
418+ }
419+ } else {
420+ if(i < marks) {
421+ if(wrapAround)
422+ i += markedLines_.size();
423+ else
424+ return boost::none;
425+ }
426+ i -= marks;
427+ }
428+ return markedLines_[i];
429+}
430+
431+/// Returns the number of the lines bookmarked.
432+size_t Bookmarker::numberOfMarks() const BOOST_NOEXCEPT {
433+ return markedLines_.size();
434+}
435+
436+/**
437+ * Removes the listener.
438+ * @param listener The listener to be removed
439+ * @throw std#invalid_argument @a listener is not registered
440+ */
441+void Bookmarker::removeListener(BookmarkListener& listener) {
442+ listeners_.remove(listener);
443+}
444+
445+/**
446+ * Toggles the bookmark of the spcified line.
447+ * @param line The line
448+ * @throw BadPositionException @a line is outside of the document
449+ */
450+void Bookmarker::toggle(Index line) {
451+ if(line >= document_.numberOfLines())
452+ throw BadPositionException(Position(line, 0));
453+ const GapVector<Index>::iterator i(find(line));
454+ if(i == std::end(markedLines_) || *i != line)
455+ markedLines_.insert(i, line);
456+ else
457+ markedLines_.erase(i);
458+ listeners_.notify<Index>(&BookmarkListener::bookmarkChanged, line);
459+}
460+
461+
462+// DocumentPartitioner ////////////////////////////////////////////////////////////////////////////
463+
464+/// Constructor.
465+DocumentPartitioner::DocumentPartitioner() BOOST_NOEXCEPT : document_(nullptr) {
466+}
467+
468+/// Destructor.
469+DocumentPartitioner::~DocumentPartitioner() BOOST_NOEXCEPT {
470+}
471+
472+
473+// Document ///////////////////////////////////////////////////////////////////////////////////////
474+
475+/**
476+ * @class ascension::kernel::Document
477+ * A document manages a text content and supports text manipulations.
478+ *
479+ * All text content is represented in UTF-16. To treat this as UTF-32, use
480+ * @c DocumentCharacterIterator.
481+ *
482+ * A document manages also its operation history, encoding, and newlines and writes to or reads the
483+ * content from files or streams.
484+ *
485+ * @c #insert inserts a text string into any position. @c #erase deletes any text region.
486+ * Other classes also provide text manipulation for the document.
487+ *
488+ * @c #insert and @c #erase methods throw @c DocumentCantChangeException when the change was
489+ * rejected. This occurs if the the document was not marked modified and the document input's
490+ * @c IDocumentInput#isChangeable returned @c false.
491+ *
492+ * <h3>Revision and Modification Signature</h3>
493+ *
494+ * A document manages the revision number indicates how many times the document was changed. This
495+ * value is initially zero. @c #replace, @c #redo and @c #resetContent methods increment and
496+ * @c #undo method decrements the revision number. The current revision number can be obtained
497+ * by @c #revisionNumber method. It is guarenteed that the contents of a document correspond to
498+ * same revision number are equivalent.
499+ *
500+ * Clients of @c Document can query if "the document has been changed" by @c #isModified method.
501+ * The modification signature (state) is determined based on the revision of the document. In a
502+ * word, the document is treated as "modified" if the revision number is different from the one at
503+ * "unmodified". For example (parenthesized numbers are the revisions),
504+ *
505+ * @code
506+ * Document d; // a document is unmodified initially (0)
507+ * insert(d, text); // increment the revision (1)
508+ * d.isModified(); // true
509+ * d.undo(); // decrement the revision (0)
510+ * d.isModified(); // false
511+ * @endcode
512+ *
513+ * Use @c #markUnmodified method to set the current revision as unmodified.
514+ *
515+ * To set the modification state as modified explicitly, use @c #setModified method. Called this
516+ * method, the document never becomes unmodified unless @c #markUnmodified called.
517+ *
518+ * @code
519+ * Document d;
520+ * insert(d, text);
521+ * d.markUnmodified(); // the revision 1 is as unmodified
522+ * d.undo(); // modified (0)
523+ * d.redo(); // unmodified (1)
524+ * d.setModified(); // modified (1)
525+ * d.undo(); // modified (0)
526+ * @endcode
527+ *
528+ * <h3>Partitions</h3>
529+ *
530+ * A document can be devides into a sequence of semantic segments called partition.
531+ * Document partitioners expressed by @c DocumentPartitioner class define these
532+ * partitioning. Each partitions have its content type and region (see @c DocumentPartition).
533+ * To set the new partitioner, use @c #setPartitioner method. The partitioner's ownership
534+ * will be transferred to the document.
535+ *
536+ * @see DocumentPartitioner, Point, EditPoint
537+ */
538+
539+const DocumentPropertyKey Document::TITLE_PROPERTY;
540+
541+/**
542+ * Returns the accessible region of the document. The returned region is normalized.
543+ * @see #region, DocumentAccessViolationException
544+ */
545+Region Document::accessibleRegion() const BOOST_NOEXCEPT {
546+ return (accessibleRegion_.get() != nullptr) ? Region(accessibleRegion_->first, *accessibleRegion_->second) : region();
547+}
548+
549+#if 0
550+/**
551+ * Registers the compound change listener.
552+ * @param listener the listener to be registered
553+ * @throw std#invalid_argument @a listener is already registered
554+ */
555+void Document::addCompoundChangeListener(ICompoundChangeListener& listener) {
556+ compoundChangeListeners_.add(listener);
557+}
558+#endif
559+
560+/**
561+ * Registers the document listener with the document. After registration @a listener is notified
562+ * about each modification of this document.
563+ * @param listener The listener to be registered
564+ * @throw std#invalid_argument @a listener is already registered
565+ */
566+void Document::addListener(DocumentListener& listener) {
567+ if(boost::range::find(listeners_, &listener) != boost::end(listeners_))
568+ throw invalid_argument("the listener already has been registered.");
569+ listeners_.push_back(&listener);
570+}
571+
572+/**
573+ * Registers the document partitioning listener with the document.
574+ * @param listener The listener to be registered
575+ * @throw std#invalid_argument @a listener is already registered
576+ */
577+void Document::addPartitioningListener(DocumentPartitioningListener& listener) {
578+ partitioningListeners_.add(listener);
579+}
580+
581+/**
582+ * Registers the document listener as one which is notified before those document listeners
583+ * registered with @c #addListener are notified.
584+ * @internal This method is not for public use.
585+ * @param listener The listener to be registered
586+ * @throw std#invalid_argument @a listener is already registered
587+ */
588+void Document::addPrenotifiedListener(DocumentListener& listener) {
589+ if(boost::range::find(prenotifiedListeners_, &listener) != boost::end(prenotifiedListeners_))
590+ throw invalid_argument("the listener already has been registered.");
591+ prenotifiedListeners_.push_back(&listener);
592+}
593+
594+/**
595+ * Registers the rollback listener.
596+ * @param listener The listener to be registered
597+ * @throw std#invalid_argument @a listener is already registered
598+ */
599+void Document::addRollbackListener(DocumentRollbackListener& listener) {
600+ rollbackListeners_.add(listener);
601+}
602+
603+/// @c #resetContent invokes this method finally. Default implementation does nothing.
604+void Document::doResetContent() {
605+}
606+
607+void Document::fireDocumentAboutToBeChanged() BOOST_NOEXCEPT {
608+ if(partitioner_.get() != nullptr)
609+ partitioner_->documentAboutToBeChanged();
610+ BOOST_FOREACH(DocumentListener* listener, prenotifiedListeners_)
611+ listener->documentAboutToBeChanged(*this);
612+ BOOST_FOREACH(DocumentListener* listener, listeners_)
613+ listener->documentAboutToBeChanged(*this);
614+}
615+
616+void Document::fireDocumentChanged(const DocumentChange& c, bool updateAllPoints /* = true */) BOOST_NOEXCEPT {
617+ if(partitioner_.get() != nullptr)
618+ partitioner_->documentChanged(c);
619+ if(updateAllPoints)
620+ updatePoints(c);
621+ BOOST_FOREACH(DocumentListener* listener, prenotifiedListeners_)
622+ listener->documentChanged(*this, c);
623+ BOOST_FOREACH(DocumentListener* listener, listeners_)
624+ listener->documentChanged(*this, c);
625+}
626+
627+/**
628+ * Returns the number of characters (UTF-16 code units) in the document.
629+ * @param newline The method to count newlines
630+ * @return The number of characters
631+ */
632+Index Document::length(const Newline& newline /* = Newline::USE_INTRINSIC_VALUE */) const BOOST_NOEXCEPT {
633+ const Newline resolvedNewline(resolveNewline(*this, newline));
634+ if(resolvedNewline.isLiteral())
635+ return length_ + (numberOfLines() - 1) * ((resolvedNewline != Newline::CARRIAGE_RETURN_FOLLOWED_BY_LINE_FEED) ? 1 : 2);
636+ assert(resolvedNewline == Newline::USE_INTRINSIC_VALUE);
637+ Index len = length_;
638+ const Index lines = numberOfLines();
639+ assert(lines > 0);
640+ for(Index i = 0; i < lines - 1; ++i)
641+ len += lines_[i]->newline_.asString().length();
642+ return len;
643+}
644+
645+/**
646+ * Returns the offset of the line.
647+ * @param line The line
648+ * @param newline The line representation policy for character counting
649+ * @throw BadPostionException @a line is outside of the document
650+ */
651+Index Document::lineOffset(Index line, const Newline& newline) const {
652+ if(line >= numberOfLines())
653+ throw BadPositionException(Position(line, 0));
654+
655+ const Newline resolvedNewline(resolveNewline(*this, newline));
656+ Index offset = 0, eolLength = resolvedNewline.isLiteral() ? resolvedNewline.asString().length() : 0;
657+ assert(eolLength != 0 || resolvedNewline == Newline::USE_INTRINSIC_VALUE);
658+ for(Index i = 0; i < line; ++i) {
659+ const Line& ln = *lines_[i];
660+ offset += ln.text_.length();
661+ if(newline == Newline::USE_INTRINSIC_VALUE)
662+ offset += ln.newline_.asString().length();
663+ else
664+ offset += eolLength;
665+ }
666+ return offset;
667+}
668+#if 0
669+/**
670+ * Locks the document.
671+ * @param locker the object locks the document. this object is used with later @c #unlock call
672+ * @retval @c true Succeeded to lock
673+ * @retval @c false Failed to lock because the other object already had locked, or the document's
674+ * input rejected the lock (only when the document was not marked as modified)
675+ * @throw ReadOnlyDocumentException The document is read only
676+ * @throw NullPointerException @a locker is @c null
677+ * @see #unlock
678+ */
679+bool Document::lock(const void* locker) {
680+ // TODO: should support exclusive operation.
681+ if(isReadOnly())
682+ throw ReadOnlyDocumentException();
683+ else if(locker == nullptr)
684+ throw NullPointerException("locker");
685+ else if(locker_ != nullptr || (isModified() && input_.get() != nullptr && !input_->isChangeable()))
686+ return false;
687+ locker_ = locker;
688+ return true;
689+}
690+#endif
691+/**
692+ * Marks the document unmodified at the current revision.
693+ * For details about modification signature, see the documentation of @c Document class.
694+ * @see #isModified, #setModified, #ModificationSignChangedSignal
695+ */
696+void Document::markUnmodified() BOOST_NOEXCEPT {
697+ if(isModified()) {
698+ lastUnmodifiedRevisionNumber_ = revisionNumber();
699+ modificationSignChangedSignal_(*this);
700+ }
701+}
702+
703+/**
704+ * Narrows the accessible area to the specified region.
705+ * If the document is already narrowed, the accessible region will just change to @a region. In
706+ * this case, @a region can be wider than the current accessible region.
707+ * @param region The region
708+ * @throw BadRegionException @a region intersects with the outside of the document
709+ * @see #isNarrowed, #widen, #AccessibleRegionChangedSignal
710+ */
711+void Document::narrowToRegion(const Region& region) {
712+ if(region.end() > this->region().end())
713+ throw BadRegionException(region);
714+ else if(region == accessibleRegion())
715+ return;
716+ if(accessibleRegion_.get() == 0) {
717+ accessibleRegion_.reset(new pair<Position, unique_ptr<Point>>);
718+ accessibleRegion_->second.reset(new Point(*this, region.end()));
719+ } else
720+ accessibleRegion_->second->moveTo(region.end());
721+ accessibleRegion_->first = region.beginning();
722+// BOOST_FOREACH(Point* p, points_) {
723+// if(p->isExcludedFromRestriction())
724+// p->normalize();
725+// }
726+ accessibleRegionChangedSignal_(*this);
727+}
728+
729+/**
730+ * Removes the document listener from the document.
731+ * @param listener The listener to be removed
732+ * @throw std#invalid_argument @a listener is not registered
733+ */
734+void Document::removeListener(DocumentListener& listener) {
735+ const list<DocumentListener*>::iterator i(boost::range::find(listeners_, &listener));
736+ if(i == boost::end(listeners_))
737+ throw invalid_argument("the listener is not registered.");
738+ listeners_.erase(i);
739+}
740+
741+/**
742+ * Removes the document partitioning listener from the document.
743+ * @param listener The listener to be removed
744+ * @throw std#invalid_argument @a listener is not registered
745+ */
746+void Document::removePartitioningListener(DocumentPartitioningListener& listener) {
747+ partitioningListeners_.remove(listener);
748+}
749+
750+/**
751+ * Removes the pre-notified document listener from the document.
752+ * @internal This method is not for public use.
753+ * @param listener The listener to be removed
754+ * @throw std#invalid_argument @a listener is not registered
755+ */
756+void Document::removePrenotifiedListener(DocumentListener& listener) {
757+ const list<DocumentListener*>::iterator i(boost::range::find(prenotifiedListeners_, &listener));
758+ if(i == boost::end(prenotifiedListeners_))
759+ throw invalid_argument("the listener is not registered.");
760+ prenotifiedListeners_.erase(i);
761+}
762+
763+/**
764+ * Removes the rollback listener.
765+ * @param listener The listener to be removed
766+ * @throw std#invalid_argument @a listener is not registered
767+ */
768+void Document::removeRollbackListener(DocumentRollbackListener& listener) {
769+ rollbackListeners_.remove(listener);
770+}
771+
772+/**
773+ * Resets and initializes the content of the document. Does the following:
774+ * - Clears the text buffer, invokes the two methods of @c IDocumentListener and increments the
775+ * revision number even if the document was empty.
776+ * - Moves the all point to the beginning of the document.
777+ * - Clears the undo/redo buffers.
778+ * - Resets the modification flag to @c false.
779+ * - Resets the read-only flag to @c false.
780+ * - Revokes the narrowing.
781+ * - Removes the all bookmarks.
782+ * @note This method does not call @c IDocumentInput#isChangeable for rejection.
783+ * @see #doResetContent
784+ */
785+void Document::resetContent() {
786+ if(lines_.empty()) // called by constructor
787+ lines_.insert(begin(lines_), new Line(0));
788+ else {
789+ widen();
790+ BOOST_FOREACH(Point* p, points_)
791+ p->moveTo(Position(0, 0));
792+ bookmarker_->clear();
793+
794+ fireDocumentAboutToBeChanged();
795+ if(length_ != 0) {
796+ assert(!lines_.empty());
797+ for(size_t i = 0, c = lines_.size(); i < c; ++i)
798+ delete lines_[i];
799+ lines_.clear();
800+ lines_.insert(begin(lines_), new Line(revisionNumber_ + 1));
801+ length_ = 0;
802+ ++revisionNumber_;
803+ }
804+ const DocumentChange ca(region(), Region(region().beginning()));
805+ fireDocumentChanged(ca, false);
806+ }
807+
808+ setReadOnly(false);
809+ markUnmodified();
810+ clearUndoBuffer();
811+ onceUndoBufferCleared_ = false;
812+ doResetContent();
813+}
814+
815+/**
816+ * Sets the new document input.
817+ * @param newInput The new document input. Can be @c null
818+ */
819+void Document::setInput(weak_ptr<DocumentInput> newInput) BOOST_NOEXCEPT {
820+ input_ = newInput;
821+}
822+
823+/**
824+ * Marks the document modified.
825+ * For details about modification signature, see the documentation of @c Document class.
826+ * @see #isModified, #markUnmodified, #dModificationSignChangedSignal
827+ */
828+void Document::setModified() BOOST_NOEXCEPT {
829+ const bool modified = isModified();
830+ lastUnmodifiedRevisionNumber_ = numeric_limits<size_t>::max();
831+ if(!modified)
832+ modificationSignChangedSignal_(*this);
833+}
834+
835+/**
836+ * Sets the new document partitioner.
837+ * @param newPartitioner The new partitioner. The ownership will be transferred to the callee
838+ */
839+void Document::setPartitioner(unique_ptr<DocumentPartitioner> newPartitioner) BOOST_NOEXCEPT {
840+ partitioner_ = move(newPartitioner);
841+ if(partitioner_.get() != nullptr)
842+ partitioner_->install(*this);
843+ partitioningChanged(region());
844+}
845+
846+/**
847+ * Associates the given property with the document.
848+ * @param key The key of the property
849+ * @param property The property value
850+ * @see #property, #PropertyChangedSignal
851+ */
852+void Document::setProperty(const DocumentPropertyKey& key, const String& property) {
853+ map<const DocumentPropertyKey*, unique_ptr<String>>::iterator i(properties_.find(&key));
854+ if(i == end(properties_))
855+ properties_.insert(make_pair(&key, new String(property)));
856+ else
857+ i->second->assign(property);
858+ propertyChangedSignal_(*this, key);
859+}
860+
861+/**
862+ * Makes the document read only or not.
863+ * @see ReadOnlyDocumentException, #isReadOnly, #ReadOnlySignChangedSignal
864+ */
865+void Document::setReadOnly(bool readOnly /* = true */) BOOST_NOEXCEPT {
866+ if(readOnly != isReadOnly()) {
867+ readOnly_ = readOnly;
868+ readOnlySignChangedSignal_(*this);
869+ }
870+}
871+#if 0
872+/**
873+ * Unlocks the document.
874+ * @param locker The object used with previous @c #lock call
875+ * @throw IllegalStateException The document is not locked
876+ * @throw NullPointerException @a locker is @c null
877+ * @throw std#invalid_argument @a locker is not the object used with @c #lock call
878+ * @see #lock
879+ */
880+void Document::unlock(const void* locker) {
881+ // TODO: support exclusive operation.
882+ if(locker_ == nullptr)
883+ throw IllegalStateException("the document's input is not locked.");
884+ else if(locker == nullptr)
885+ throw NullPointerException("locker");
886+ else if(locker != locker_)
887+ throw invalid_argument("locker");
888+ locker_ = nullptr;
889+}
890+#endif
891+/**
892+ * Informs the document change to the adapting points.
893+ * @param change The document change
894+ */
895+
896+inline void Document::updatePoints(const DocumentChange& change) BOOST_NOEXCEPT {
897+ BOOST_FOREACH(Point* p, points_) {
898+ if(p->adaptsToDocument())
899+ p->update(change);
900+ }
901+}
902+
903+/**
904+ * Revokes the narrowing.
905+ * @see #isNarrowed, #narrow, #AccessibleRegionChangedSignal
906+ */
907+void Document::widen() BOOST_NOEXCEPT {
908+ if(accessibleRegion_.get() != nullptr) {
909+ accessibleRegion_.reset();
910+ accessibleRegionChangedSignal_(*this);
911+ }
912+}
913+
914+
915+// Document.Line //////////////////////////////////////////////////////////////////////////////////
916+
917+Document::Line::Line(size_t revisionNumber) BOOST_NOEXCEPT : newline_(ASCENSION_DEFAULT_NEWLINE), revisionNumber_(revisionNumber) {
918+}
919+
920+Document::Line::Line(size_t revisionNumber, const String& text,
921+ const Newline& newline /* = ASCENSION_DEFAULT_NEWLINE */) : text_(text), newline_(newline), revisionNumber_(revisionNumber) {
922+}
923+
924+
925+// Document.DefaultContentTypeInformationProvider /////////////////////////////////////////////////
926+
927+Document::DefaultContentTypeInformationProvider::DefaultContentTypeInformationProvider() : syntax_(new IdentifierSyntax()) {
928+}
929+
930+Document::DefaultContentTypeInformationProvider::~DefaultContentTypeInformationProvider() BOOST_NOEXCEPT {
931+ delete syntax_;
932+}
933+
934+
935+// CompoundChangeSaver ////////////////////////////////////////////////////////////////////////////
936+
937+/**
938+ * @class ascension::kernel::CompoundChangeSaver
939+ *
940+ * Calls automatically @c Document#beginCompoundChange and @c Document#endCompoundChange.
941+ *
942+ * @code
943+ * extern Document* target;
944+ * CompoundChangeSaver saver(target);
945+ * target-&gt;mayThrow();
946+ * // target-&gt;endCompoundChange() will be called automatically
947+ * @endcode
948+ *
949+ * @note This class is not intended to be subclassed.
950+ */
951+
952+/**
953+ * Constructor calls @c Document#beginCompoundChange.
954+ * @param document The document this object manages. if this is @c null, the object does nothing
955+ * @throw ... Any exceptions @c Document#beginCompoundChange throws
956+ */
957+CompoundChangeSaver::CompoundChangeSaver(Document* document) : document_(document) {
958+ if(document_ != nullptr)
959+ document_->beginCompoundChange();
960+}
961+
962+/**
963+ * Destructor calls @c Document#endCompoundChange.
964+ * @throw ... Any exceptions @c Document#endCompoundChange throws
965+ */
966+CompoundChangeSaver::~CompoundChangeSaver() {
967+ if(document_ != nullptr)
968+ document_->endCompoundChange();
969+}
970+
971+#if 0
972+// DocumentLocker /////////////////////////////////////////////////////////////////////////////////
973+
974+/**
975+ * @class ascension::kernel::DocumentLocker
976+ *
977+ * Calls @c Document#lock and @c Document#unlock automatically.
978+ *
979+ * @note This class is not intended to be subclassed.
980+ */
981+
982+/**
983+ * Constructor calls @c Document#lock.
984+ * @param document The document to lock
985+ * @throw ReadOnlyDocumentException The document is read only
986+ * @throw DocumentCantChangeException Failed to lock the document
987+ */
988+DocumentLocker::DocumentLocker(Document& document) : document_((document.locker() == nullptr) ? &document : nullptr) {
989+ if(document_ != nullptr && !document_->lock(this)) // manage lock if there is not an active lock
990+ throw DocumentCantChangeException();
991+}
992+
993+/// Destructor calls @c Document#unlock.
994+DocumentLocker::~DocumentLocker() BOOST_NOEXCEPT {
995+ if(document_ != nullptr)
996+ document_->unlock(this);
997+}
998+#endif
999+
1000+// DocumentCharacterIterator //////////////////////////////////////////////////////////////////////
1001+
1002+/**
1003+ * @class ascension::kernel::DocumentCharacterIterator
1004+ * Bidirectional iterator scans characters in the specified document.
1005+ *
1006+ * @c #current implementation of this class returns a character at which the iterator addresses. A
1007+ * returned character is as a UTF-32 code unit (not UTF-16). In the following cases, returns a
1008+ * special value depending on the context:
1009+ *
1010+ * - @c CharacterIterator#DONE at the end of the region of the iterator
1011+ * - @c LINE_SEPARATOR at the end of the line
1012+ * - a raw code unit value at any unpaired surrogate
1013+ *
1014+ * This class can't detect any change of the document. When the document changed, the existing
1015+ * iterators may be invalid.
1016+ *
1017+ * @note This class is not intended to be subclassed.
1018+ */
1019+
1020+const CharacterIterator::ConcreteTypeTag
1021+ DocumentCharacterIterator::CONCRETE_TYPE_TAG_ = CharacterIterator::ConcreteTypeTag();
1022+
1023+/// Default constructor makes an invalid iterator object.
1024+DocumentCharacterIterator::DocumentCharacterIterator() BOOST_NOEXCEPT
1025+ : CharacterIterator(CONCRETE_TYPE_TAG_), document_(nullptr), line_(0) {
1026+}
1027+
1028+/**
1029+ * Constructor. The iteration region is the accessible area of the document.
1030+ * @param document The document to iterate
1031+ * @param position The position at which the iteration starts
1032+ * @throw BadPositionException @a position is outside of the accessible area of the document
1033+ */
1034+DocumentCharacterIterator::DocumentCharacterIterator(const Document& document, const Position& position) :
1035+ CharacterIterator(CONCRETE_TYPE_TAG_), document_(&document),
1036+ region_(document.region()), line_(&document.line(position.line)), p_(position) {
1037+ if(!region_.includes(p_))
1038+ throw BadPositionException(p_);
1039+}
1040+
1041+/**
1042+ * Constructor. The iteration is started at @a region.beginning().
1043+ * @param document The document to iterate
1044+ * @param region The region to iterate
1045+ * @throw BadRegionException @a region intersects outside of the document
1046+ */
1047+DocumentCharacterIterator::DocumentCharacterIterator(const Document& document, const Region& region) :
1048+ CharacterIterator(CONCRETE_TYPE_TAG_), document_(&document), region_(region),
1049+ line_(&document.line(region.beginning().line)), p_(region.beginning()) {
1050+ region_.normalize();
1051+ if(!document.region().encompasses(region_))
1052+ throw BadRegionException(region_);
1053+}
1054+
1055+/**
1056+ * Constructor.
1057+ * @param document The document to iterate
1058+ * @param region The region to iterate
1059+ * @param position The position at which the iteration starts
1060+ * @throw BadRegionException @a region intersects outside of the document
1061+ * @throw BadPositionException @a position is outside of @a region
1062+ */
1063+DocumentCharacterIterator::DocumentCharacterIterator(const Document& document, const Region& region, const Position& position) :
1064+ CharacterIterator(CONCRETE_TYPE_TAG_), document_(&document), region_(region), line_(&document.line(position.line)), p_(position) {
1065+ region_.normalize();
1066+ if(!document.region().encompasses(region_))
1067+ throw BadRegionException(region_);
1068+ else if(!region_.includes(p_))
1069+ throw BadPositionException(p_);
1070+}
1071+
1072+/// Copy-constructor.
1073+DocumentCharacterIterator::DocumentCharacterIterator(const DocumentCharacterIterator& other) BOOST_NOEXCEPT :
1074+ text::CharacterIterator(other), document_(other.document_), region_(other.region_), line_(other.line_), p_(other.p_) {
1075+}
1076+
1077+/// @see text#CharacterIterator#current
1078+CodePoint DocumentCharacterIterator::current() const BOOST_NOEXCEPT {
1079+ if(document() == nullptr || tell() == region().second)
1080+ return DONE;
1081+ else if(tell().offsetInLine == line().length())
1082+ return LINE_SEPARATOR;
1083+ else
1084+ return (surrogates::isHighSurrogate((*line_)[tell().offsetInLine])
1085+ && tell().offsetInLine + 1 < line_->length() && surrogates::isLowSurrogate((*line_)[tell().offsetInLine + 1])) ?
1086+ surrogates::decode((*line_)[tell().offsetInLine], (*line_)[tell().offsetInLine + 1]) : (*line_)[tell().offsetInLine];
1087+}
1088+
1089+/// @see text#CharacterIterator#doAssign
1090+void DocumentCharacterIterator::doAssign(const CharacterIterator& other) {
1091+ CharacterIterator::operator=(other);
1092+ const DocumentCharacterIterator& r = static_cast<const DocumentCharacterIterator&>(other);
1093+ document_ = r.document_;
1094+ line_ = r.line_;
1095+ p_ = r.p_;
1096+ region_ = r.region_;
1097+}
1098+
1099+/// @see text#CharacterIterator#doClone
1100+unique_ptr<CharacterIterator> DocumentCharacterIterator::doClone() const {
1101+ return unique_ptr<CharacterIterator>(new DocumentCharacterIterator(*this));
1102+}
1103+
1104+/// @see text#CharacterIterator#doFirst
1105+void DocumentCharacterIterator::doFirst() {
1106+ seek(region_.first);
1107+}
1108+
1109+/// @see text#CharacterIterator#doLast
1110+void DocumentCharacterIterator::doLast() {
1111+ seek(region_.second);
1112+}
1113+
1114+/// @see text#CharacterIterator#doEquals
1115+bool DocumentCharacterIterator::doEquals(const CharacterIterator& other) const {
1116+ const DocumentCharacterIterator& o = static_cast<const DocumentCharacterIterator&>(other);
1117+ if(document() != o.document())
1118+ return false;
1119+ return document() == nullptr || tell() == o.tell();
1120+}
1121+
1122+/// @see text#CharacterIterator#doLess
1123+bool DocumentCharacterIterator::doLess(const CharacterIterator& other) const {
1124+ return tell() < static_cast<const DocumentCharacterIterator&>(other).tell();
1125+}
1126+
1127+/// @see text#CharacterIterator#doNext
1128+void DocumentCharacterIterator::doNext() {
1129+ if(!hasNext())
1130+// throw out_of_range("the iterator is at the last.");
1131+ return;
1132+ else if(tell().offsetInLine == line_->length()) {
1133+ line_ = &document_->line(++p_.line);
1134+ p_.offsetInLine = 0;
1135+ } else if(++p_.offsetInLine < line_->length()
1136+ && surrogates::isLowSurrogate((*line_)[tell().offsetInLine])
1137+ && surrogates::isHighSurrogate((*line_)[tell().offsetInLine - 1]))
1138+ ++p_.offsetInLine;
1139+}
1140+
1141+/// @see text#CharacterIterator#doPrevious
1142+void DocumentCharacterIterator::doPrevious() {
1143+ if(!hasPrevious())
1144+// throw out_of_range("the iterator is at the first.");
1145+ return;
1146+ else if(tell().offsetInLine == 0)
1147+ p_.offsetInLine = (line_ = &document_->line(--p_.line))->length();
1148+ else if(--p_.offsetInLine > 0
1149+ && surrogates::isLowSurrogate((*line_)[tell().offsetInLine])
1150+ && surrogates::isHighSurrogate((*line_)[tell().offsetInLine - 1]))
1151+ --p_.offsetInLine;
1152+}
1153+
1154+/**
1155+ * Sets the region of the iterator. The current position will adjusted.
1156+ * @param newRegion The new region to set
1157+ * @throw BadRegionException @a newRegion intersects outside of the document
1158+ */
1159+void DocumentCharacterIterator::setRegion(const Region& newRegion) {
1160+ const Position e(document_->region().second);
1161+ if(newRegion.first > e || newRegion.second > e)
1162+ throw BadRegionException(newRegion);
1163+ if(!(region_ = newRegion).includes(tell()))
1164+ seek(tell());
1165+}
1166+
1167+
1168+// NullPartitioner ////////////////////////////////////////////////////////////////////////////////
1169+
1170+/// Constructor.
1171+NullPartitioner::NullPartitioner() BOOST_NOEXCEPT : p_(DEFAULT_CONTENT_TYPE, Region(Position(0, 0), Position(0, 0))), changed_(true) {
1172+}
1173+
1174+/// @see DocumentPartitioner#documentAboutToBeChanged
1175+void NullPartitioner::documentAboutToBeChanged() BOOST_NOEXCEPT {
1176+}
1177+
1178+/// @see DocumentPartitioner#documentChanged
1179+void NullPartitioner::documentChanged(const DocumentChange&) BOOST_NOEXCEPT {
1180+ changed_ = true;
1181+}
1182+
1183+/// @see DocumentPartitioner#doGetPartition
1184+void NullPartitioner::doGetPartition(const Position&, DocumentPartition& partition) const BOOST_NOEXCEPT {
1185+ if(changed_) {
1186+ const_cast<NullPartitioner*>(this)->p_.region.second = document()->region().second;
1187+ changed_ = false;
1188+ }
1189+ partition = p_;
1190+}
1191+
1192+/// @see DocumentPartitioner#doInstall
1193+void NullPartitioner::doInstall() BOOST_NOEXCEPT {
1194+ changed_ = true;
1195+}
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/kernel/point.cpp
--- a/ascension/src/kernel/point.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/kernel/point.cpp Sat May 11 12:12:08 2013 +0900
@@ -89,7 +89,7 @@
8989 }
9090
9191 /// Destructor.
92-Point::~Point() /*throw()*/ {
92+Point::~Point() BOOST_NOEXCEPT {
9393 lifeCycleListeners_.notify(&PointLifeCycleListener::pointDestroyed);
9494 if(document_ != nullptr)
9595 static_cast<detail::PointCollection<Point>*>(document_)->removePoint(*this);
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/kernel/searcher.cpp
--- a/ascension/src/kernel/searcher.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/kernel/searcher.cpp Sat May 11 12:12:08 2013 +0900
@@ -178,10 +178,10 @@
178178 // TextSearcher ///////////////////////////////////////////////////////////////////////////////////
179179
180180 namespace {
181- inline DocumentCharacterIterator beginningOfDocument(const Document& document) /*throw()*/ {
181+ inline DocumentCharacterIterator beginningOfDocument(const Document& document) BOOST_NOEXCEPT {
182182 return DocumentCharacterIterator(document, document.region().first);
183183 }
184- inline DocumentCharacterIterator endOfDocument(const Document& document) /*throw()*/ {
184+ inline DocumentCharacterIterator endOfDocument(const Document& document) BOOST_NOEXCEPT {
185185 return DocumentCharacterIterator(document, document.region().second);
186186 }
187187 }
@@ -216,7 +216,7 @@
216216 * Returns the collation weight level.
217217 * @note This feature is not implemented and returns always @c Collator#IDENTICAL (15).
218218 */
219-int TextSearcher::collationWeight() const /*throw()*/ {
219+int TextSearcher::collationWeight() const BOOST_NOEXCEPT {
220220 #ifndef ASCENSION_NO_UNICODE_COLLATION
221221 return Collator::IDENTICAL;
222222 #else
@@ -241,7 +241,7 @@
241241 }
242242
243243 /// Returns @c true if Migemo is available.
244-bool TextSearcher::isMigemoAvailable() const /*throw()*/ {
244+bool TextSearcher::isMigemoAvailable() const BOOST_NOEXCEPT {
245245 #ifdef ASCENSION_NO_MIGEMO
246246 return false;
247247 #else
@@ -700,7 +700,7 @@
700700 }
701701
702702 /// Sets the maximum number of the stored patterns or replacement strings.
703-void TextSearcher::setMaximumNumberOfStoredStrings(size_t number) /*throw()*/ {
703+void TextSearcher::setMaximumNumberOfStoredStrings(size_t number) BOOST_NOEXCEPT {
704704 number = max<size_t>(number, MINIMUM_NUMBER_OF_STORED_STRINGS);
705705 if(storedPatterns_.size() > number)
706706 storedPatterns_.resize(number);
@@ -738,7 +738,7 @@
738738 * Returns the type of search.
739739 * @see #setPattern
740740 */
741-TextSearcher::Type TextSearcher::type() const /*throw()*/ {
741+TextSearcher::Type TextSearcher::type() const BOOST_NOEXCEPT {
742742 #ifndef ASCENSION_NO_REGEX
743743 if(regexPattern_.get() != nullptr)
744744 return REGULAR_EXPRESSION;
@@ -752,7 +752,7 @@
752752 }
753753
754754 /// Returns @c true if the pattern uses Unicode canonical equivalents.
755-bool TextSearcher::usesCanonicalEquivalents() const /*throw()*/ {
755+bool TextSearcher::usesCanonicalEquivalents() const BOOST_NOEXCEPT {
756756 #ifndef ASCENSION_NO_REGEX
757757 if(regexPattern_.get() != nullptr && (regexPattern_->flags() & regex::Pattern::CANON_EQ) != 0)
758758 return true;
@@ -761,7 +761,7 @@
761761 }
762762
763763 /// Returns the "whole match" condition.
764-TextSearcher::WholeMatch TextSearcher::wholeMatch() const /*throw()*/ {
764+TextSearcher::WholeMatch TextSearcher::wholeMatch() const BOOST_NOEXCEPT {
765765 return wholeMatch_;
766766 }
767767
@@ -769,7 +769,7 @@
769769 // IncrementalSearcher ////////////////////////////////////////////////////////////////////////////
770770
771771 /// Constructor.
772-IncrementalSearcher::IncrementalSearcher() /*throw()*/ : type_(TextSearcher::LITERAL) {
772+IncrementalSearcher::IncrementalSearcher() BOOST_NOEXCEPT : type_(TextSearcher::LITERAL) {
773773 }
774774
775775 /// Aborts the search.
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/kernel/undo.cpp
--- a/ascension/src/kernel/undo.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/kernel/undo.cpp Sat May 11 12:12:08 2013 +0900
@@ -30,7 +30,7 @@
3030 bool completed; // true if the change was *completely* performed
3131 size_t numberOfRevisions; // the number of the performed changes
3232 Position endOfChange; // the end position of the change
33- void reset() /*throw()*/ {
33+ void reset() BOOST_NOEXCEPT {
3434 completed = false;
3535 numberOfRevisions = 0;
3636 // endOfChange = Position();
@@ -38,7 +38,7 @@
3838 };
3939 public:
4040 // destructor
41- virtual ~UndoableChange() /*throw()*/ {}
41+ virtual ~UndoableChange() BOOST_NOEXCEPT {}
4242 // appends the "postChange" to this change and returns true, or returns false
4343 virtual bool appendChange(AtomicChange& postChange, const Document& document) = 0;
4444 // returns true if the change can perform
@@ -51,19 +51,19 @@
5151 class AtomicChange : public UndoableChange {
5252 public:
5353 struct TypeTag {}; // ugly dynamic type system for performance reason
54- virtual ~AtomicChange() /*throw()*/ {}
55- virtual const TypeTag& type() const /*throw()*/ = 0;
54+ virtual ~AtomicChange() BOOST_NOEXCEPT {}
55+ virtual const TypeTag& type() const BOOST_NOEXCEPT = 0;
5656 };
5757
5858 // an atomic insertion change
5959 class InsertionChange : public AtomicChange, public FastArenaObject<InsertionChange> {
6060 public:
6161 InsertionChange(const Position& position, const String& text) : position_(position), text_(text) {}
62- bool appendChange(AtomicChange&, const Document&) /*throw()*/ {return false;}
63- bool canPerform(const Document& document) const /*throw()*/ {return !document.isNarrowed() || document.region().includes(position_);}
62+ bool appendChange(AtomicChange&, const Document&) BOOST_NOEXCEPT {return false;}
63+ bool canPerform(const Document& document) const BOOST_NOEXCEPT {return !document.isNarrowed() || document.region().includes(position_);}
6464 void perform(Document& document, Result& result);
6565 private:
66- const TypeTag& type() const /*throw()*/ {return type_;}
66+ const TypeTag& type() const BOOST_NOEXCEPT {return type_;}
6767 private:
6868 const Position position_;
6969 const String text_;
@@ -73,12 +73,12 @@
7373 // an atomic deletion change
7474 class DeletionChange : public AtomicChange, public FastArenaObject<DeletionChange> {
7575 public:
76- explicit DeletionChange(const Region& region) /*throw()*/ : region_(region), revisions_(1) {}
77- bool appendChange(AtomicChange& postChange, const Document&) /*throw()*/;
78- bool canPerform(const Document& document) const /*throw()*/ {return !document.isNarrowed() || document.region().encompasses(region_);}
76+ explicit DeletionChange(const Region& region) BOOST_NOEXCEPT : region_(region), revisions_(1) {}
77+ bool appendChange(AtomicChange& postChange, const Document&) BOOST_NOEXCEPT;
78+ bool canPerform(const Document& document) const BOOST_NOEXCEPT {return !document.isNarrowed() || document.region().encompasses(region_);}
7979 void perform(Document& document, Result& result);
8080 private:
81- const TypeTag& type() const /*throw()*/ {return type_;}
81+ const TypeTag& type() const BOOST_NOEXCEPT {return type_;}
8282 private:
8383 Region region_;
8484 size_t revisions_;
@@ -89,11 +89,11 @@
8989 class ReplacementChange : public AtomicChange, public FastArenaObject<ReplacementChange> {
9090 public:
9191 explicit ReplacementChange(const Region& region, const String& text) : region_(region), text_(text) {}
92- bool appendChange(AtomicChange&, const Document&) /*throw()*/ {return false;}
93- bool canPerform(const Document& document) const /*throw()*/ {return !document.isNarrowed() || document.region().encompasses(region_);}
92+ bool appendChange(AtomicChange&, const Document&) BOOST_NOEXCEPT {return false;}
93+ bool canPerform(const Document& document) const BOOST_NOEXCEPT {return !document.isNarrowed() || document.region().encompasses(region_);}
9494 void perform(Document& document, Result& result);
9595 private:
96- const TypeTag& type() const /*throw()*/ {return type_;}
96+ const TypeTag& type() const BOOST_NOEXCEPT {return type_;}
9797 private:
9898 const Region region_;
9999 const String text_;
@@ -103,9 +103,9 @@
103103 // a compound change
104104 class CompoundChange : public UndoableChange {
105105 public:
106- ~CompoundChange() /*throw()*/;
106+ ~CompoundChange() BOOST_NOEXCEPT;
107107 bool appendChange(AtomicChange& postChange, const Document& document);
108- bool canPerform(const Document& document) const /*throw()*/ {return !changes_.empty() && changes_.back()->canPerform(document);}
108+ bool canPerform(const Document& document) const BOOST_NOEXCEPT {return !changes_.empty() && changes_.back()->canPerform(document);}
109109 void perform(Document& document, Result& result);
110110 private:
111111 vector<AtomicChange*> changes_;
@@ -165,7 +165,7 @@
165165 result.numberOfRevisions = 1;
166166 }
167167
168- CompoundChange::~CompoundChange() /*throw()*/ {
168+ CompoundChange::~CompoundChange() BOOST_NOEXCEPT {
169169 BOOST_FOREACH(AtomicChange* change, changes_)
170170 delete change;
171171 }
@@ -209,21 +209,21 @@
209209 ASCENSION_NONCOPYABLE_TAG(UndoManager);
210210 public:
211211 // constructors
212- explicit UndoManager(Document& document) /*throw()*/;
213- virtual ~UndoManager() /*throw()*/ {clear();}
212+ explicit UndoManager(Document& document) BOOST_NOEXCEPT;
213+ virtual ~UndoManager() BOOST_NOEXCEPT {clear();}
214214 // attributes
215- size_t numberOfRedoableChanges() const /*throw()*/ {return redoableChanges_.size() + ((pendingAtomicChange_.get() != nullptr) ? 1 : 0);}
216- size_t numberOfUndoableChanges() const /*throw()*/ {return undoableChanges_.size() + ((pendingAtomicChange_.get() != nullptr) ? 1 : 0);}
217- bool isStackingCompoundOperation() const /*throw()*/ {return compoundChangeDepth_ > 0;}
215+ size_t numberOfRedoableChanges() const BOOST_NOEXCEPT {return redoableChanges_.size() + ((pendingAtomicChange_.get() != nullptr) ? 1 : 0);}
216+ size_t numberOfUndoableChanges() const BOOST_NOEXCEPT {return undoableChanges_.size() + ((pendingAtomicChange_.get() != nullptr) ? 1 : 0);}
217+ bool isStackingCompoundOperation() const BOOST_NOEXCEPT {return compoundChangeDepth_ > 0;}
218218 // rollbacks
219219 void redo(UndoableChange::Result& result);
220220 void undo(UndoableChange::Result& result);
221221 // recordings
222222 void addUndoableChange(AtomicChange& c);
223- void beginCompoundChange() /*throw()*/ {++compoundChangeDepth_;}
224- void clear() /*throw()*/;
225- void endCompoundChange() /*throw()*/;
226- void insertBoundary() /*throw()*/;
223+ void beginCompoundChange() BOOST_NOEXCEPT {++compoundChangeDepth_;}
224+ void clear() BOOST_NOEXCEPT;
225+ void endCompoundChange() BOOST_NOEXCEPT;
226+ void insertBoundary() BOOST_NOEXCEPT;
227227 private:
228228 void commitPendingChange(bool beginCompound);
229229 Document& document_;
@@ -236,7 +236,7 @@
236236 };
237237
238238 // constructor takes the target document
239-Document::UndoManager::UndoManager(Document& document) /*throw()*/ : document_(document),
239+Document::UndoManager::UndoManager(Document& document) BOOST_NOEXCEPT : document_(document),
240240 compoundChangeDepth_(0), rollbacking_(false), rollbackingChange_(nullptr), currentCompoundChange_(nullptr) {
241241 }
242242
@@ -265,7 +265,7 @@
265265 }
266266
267267 // clears the stacks
268-inline void Document::UndoManager::clear() /*throw()*/ {
268+inline void Document::UndoManager::clear() BOOST_NOEXCEPT {
269269 while(!undoableChanges_.empty())
270270 undoableChanges_.pop();
271271 while(!redoableChanges_.empty())
@@ -296,7 +296,7 @@
296296 }
297297
298298 // ends the compound change
299-inline void Document::UndoManager::endCompoundChange() /*throw()*/ {
299+inline void Document::UndoManager::endCompoundChange() BOOST_NOEXCEPT {
300300 if(compoundChangeDepth_ == 0)
301301 // this does not throw IllegalStateException even if the internal counter is zero, because undo()
302302 // and redo() reset the counter to zero.
@@ -387,7 +387,7 @@
387387 }
388388
389389 /// Clears the undo/redo stacks and deletes the history.
390-void Document::clearUndoBuffer() /*throw()*/ {
390+void Document::clearUndoBuffer() BOOST_NOEXCEPT {
391391 undoManager_->clear();
392392 onceUndoBufferCleared_ = true;
393393 }
@@ -422,17 +422,17 @@
422422 * Returns true if the document is compound changing.
423423 * @see #beginCompoundChange, #endCompoundChange
424424 */
425-bool Document::isCompoundChanging() const /*throw()*/ {
425+bool Document::isCompoundChanging() const BOOST_NOEXCEPT {
426426 return undoManager_->isStackingCompoundOperation();
427427 }
428428
429429 /// Returns the number of undoable changes.
430-size_t Document::numberOfUndoableChanges() const /*throw()*/ {
430+size_t Document::numberOfUndoableChanges() const BOOST_NOEXCEPT {
431431 return undoManager_->numberOfUndoableChanges();
432432 }
433433
434434 /// Returns the number of redoable changes.
435-size_t Document::numberOfRedoableChanges() const /*throw()*/ {
435+size_t Document::numberOfRedoableChanges() const BOOST_NOEXCEPT {
436436 return undoManager_->numberOfRedoableChanges();
437437 }
438438
@@ -443,7 +443,7 @@
443443 * undone. If set to @c false, discards the undo/redo information and disables the recording
444444 * @see #isRecordingChanges, #undo, #redo
445445 */
446-void Document::recordChanges(bool record) /*throw()*/ {
446+void Document::recordChanges(bool record) BOOST_NOEXCEPT {
447447 if(!(recordingChanges_ = record))
448448 clearUndoBuffer();
449449 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/presentation.cpp
--- a/ascension/src/presentation.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/presentation.cpp Sat May 11 12:12:08 2013 +0900
@@ -735,7 +735,7 @@
735735 }
736736
737737 /// Destructor.
738-PresentationReconstructor::~PresentationReconstructor() /*throw()*/ {
738+PresentationReconstructor::~PresentationReconstructor() BOOST_NOEXCEPT {
739739 // presentation_.setLineStyleDirector(ASCENSION_SHARED_POINTER<LineStyleDirector>());
740740 for(map<ContentType, PartitionPresentationReconstructor*>::iterator i(reconstructors_.begin()); i != reconstructors_.end(); ++i)
741741 delete i->second;
@@ -804,7 +804,7 @@
804804 }
805805
806806 /// Destructor.
807-URIHyperlinkDetector::~URIHyperlinkDetector() /*throw()*/ {
807+URIHyperlinkDetector::~URIHyperlinkDetector() BOOST_NOEXCEPT {
808808 }
809809
810810 /// @see HyperlinkDetector#nextHyperlink
@@ -826,14 +826,14 @@
826826 // hyperlink.CompositeHyperlinkDetector ///////////////////////////////////////////////////////////
827827
828828 /// Destructor.
829-CompositeHyperlinkDetector::~CompositeHyperlinkDetector() /*throw()*/ {
829+CompositeHyperlinkDetector::~CompositeHyperlinkDetector() BOOST_NOEXCEPT {
830830 for(map<ContentType, HyperlinkDetector*>::iterator i(composites_.begin()), e(composites_.end()); i != e; ++i)
831831 delete i->second;
832832 }
833833
834834 /// @see HyperlinkDetector#nextHyperlink
835835 unique_ptr<Hyperlink> CompositeHyperlinkDetector::nextHyperlink(
836- const Document& document, Index line, const boost::integer_range<Index>& range) const /*throw()*/ {
836+ const Document& document, Index line, const boost::integer_range<Index>& range) const BOOST_NOEXCEPT {
837837 const DocumentPartitioner& partitioner = document.partitioner();
838838 DocumentPartition partition;
839839 for(Position p(line, *range.begin()), e(line, *range.end()); p < e;) {
@@ -965,7 +965,7 @@
965965 // LexicalPartitionPresentationReconstructor //////////////////////////////////////////////////////
966966
967967 /// @see presentation#PartitionPresentationReconstructor#getPresentation
968-unique_ptr<StyledTextRunIterator> LexicalPartitionPresentationReconstructor::getPresentation(const Region& region) const /*throw()*/ {
968+unique_ptr<StyledTextRunIterator> LexicalPartitionPresentationReconstructor::getPresentation(const Region& region) const BOOST_NOEXCEPT {
969969 return unique_ptr<presentation::StyledTextRunIterator>(
970970 new StyledTextRunIterator(presentation_.document(), *tokenScanner_, styles_, defaultStyle_, region));
971971 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/viewer/caret-windows.cpp
--- a/ascension/src/viewer/caret-windows.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/viewer/caret-windows.cpp Sat May 11 12:12:08 2013 +0900
@@ -30,7 +30,7 @@
3030
3131 // managed (but ugly) STGMEDIUM
3232 struct GlobalStgMedium : public STGMEDIUM {
33- GlobalStgMedium() /*noexcept*/ {
33+ GlobalStgMedium() BOOST_NOEXCEPT {
3434 tymed = TYMED_NULL;
3535 pUnkForRelease = nullptr;
3636 }
@@ -39,7 +39,7 @@
3939 if(0 == (hGlobal = ::GlobalAlloc(flags, nbytes)))
4040 throw makePlatformError();
4141 }
42- ~GlobalStgMedium() /*noexcept*/ {
42+ ~GlobalStgMedium() BOOST_NOEXCEPT {
4343 if(lockedBuffer_ != nullptr)
4444 ::GlobalUnlock(hGlobal);
4545 ::ReleaseStgMedium(this);
@@ -52,8 +52,8 @@
5252 throw makePlatformError();
5353 return lockedBuffer();
5454 }
55- void* lockedBuffer() /*noexcept*/ {return lockedBuffer_;}
56- const void* lockedBuffer() const /*noexcept*/ {return lockedBuffer_;}
55+ void* lockedBuffer() BOOST_NOEXCEPT {return lockedBuffer_;}
56+ const void* lockedBuffer() const BOOST_NOEXCEPT {return lockedBuffer_;}
5757 private:
5858 char* lockedBuffer_;
5959 };
@@ -93,19 +93,19 @@
9393 FORMATETC format;
9494 STGMEDIUM medium;
9595 };
96- list<Entry*>::iterator find(const FORMATETC& format, list<Entry*>::iterator initial) const /*throw()*/;
96+ list<Entry*>::iterator find(const FORMATETC& format, list<Entry*>::iterator initial) const BOOST_NOEXCEPT;
9797 private:
9898 list<Entry*> entries_;
9999 };
100100
101- GenericDataObject::~GenericDataObject() /*throw()*/ {
101+ GenericDataObject::~GenericDataObject() BOOST_NOEXCEPT {
102102 for(list<Entry*>::iterator i(entries_.begin()), e(entries_.end()); i != e; ++i) {
103103 ::CoTaskMemFree((*i)->format.ptd);
104104 ::ReleaseStgMedium(&(*i)->medium);
105105 }
106106 }
107107 list<GenericDataObject::Entry*>::iterator GenericDataObject::find(
108- const FORMATETC& format, list<Entry*>::iterator initial) const /*throw()*/ {
108+ const FORMATETC& format, list<Entry*>::iterator initial) const BOOST_NOEXCEPT {
109109 const list<Entry*>::iterator e(const_cast<GenericDataObject*>(this)->entries_.end());
110110 if(format.ptd == nullptr) { // this does not support DVTARGETDEVICE
111111 for(list<Entry*>::iterator i(initial); i != e; ++i) {
@@ -412,32 +412,18 @@
412412 }
413413 }
414414
415-/**
416- * Returns @c true if a paste operation can be performed.
417- * @note Even when this method returned @c true, the following @c #paste call can fail.
418- * @param useKillRing Set @c true to get the content from the kill-ring of the session, not from
419- * the system clipboard
420- * @return true if the clipboard data is pastable
421- */
422-bool Caret::canPaste(bool useKillRing) const {
423- if(!useKillRing) {
424- const UINT rectangleClipFormat = ::RegisterClipboardFormatW(ASCENSION_RECTANGLE_TEXT_MIME_FORMAT);
425- if(rectangleClipFormat != 0 && win32::boole(::IsClipboardFormatAvailable(rectangleClipFormat)))
426- return true;
427- else if(win32::boole(::IsClipboardFormatAvailable(CF_UNICODETEXT)) || win32::boole(::IsClipboardFormatAvailable(CF_TEXT)))
428- return true;
429- } else {
430- if(const texteditor::Session* const session = document().session())
431- return session->killRing().numberOfKills() != 0;
432- }
433- return false;
415+bool Caret::canPastePlatformData() const {
416+ const UINT rectangleClipFormat = ::RegisterClipboardFormatW(ASCENSION_RECTANGLE_TEXT_MIME_FORMAT);
417+ if(rectangleClipFormat != 0 && win32::boole(::IsClipboardFormatAvailable(rectangleClipFormat)))
418+ return true;
419+ return win32::boole(::IsClipboardFormatAvailable(CF_UNICODETEXT)) || win32::boole(::IsClipboardFormatAvailable(CF_TEXT));
434420 }
435421
436422 /**
437423 * Returns the locale identifier used to convert non-Unicode text.
438424 * @see #setClipboardLocale
439425 */
440-LCID Caret::clipboardLocale() const /*throw()*/ {
426+LCID Caret::clipboardLocale() const BOOST_NOEXCEPT {
441427 return clipboardLocale_;
442428 }
443429
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/viewer/caret.cpp
--- a/ascension/src/viewer/caret.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/viewer/caret.cpp Sat May 11 12:12:08 2013 +0900
@@ -19,6 +19,7 @@
1919 #include <ascension/viewer/default-caret-shaper.hpp>
2020 #include <ascension/viewer/viewer.hpp>
2121 #include <ascension/viewer/virtual-box.hpp>
22+#include <boost/range/algorithm/binary_search.hpp>
2223
2324 using namespace ascension;
2425 using namespace ascension::graphics;
@@ -185,16 +186,10 @@
185186 * @return true if the clipboard data is pastable
186187 */
187188 bool Caret::canPaste(bool useKillRing) const {
188- if(!useKillRing) {
189- const UINT rectangleClipFormat = ::RegisterClipboardFormatW(ASCENSION_RECTANGLE_TEXT_MIME_FORMAT);
190- if(rectangleClipFormat != 0 && win32::boole(::IsClipboardFormatAvailable(rectangleClipFormat)))
191- return true;
192- else if(win32::boole(::IsClipboardFormatAvailable(CF_UNICODETEXT)) || win32::boole(::IsClipboardFormatAvailable(CF_TEXT)))
193- return true;
194- } else {
195- if(const texteditor::Session* const session = document().session())
196- return session->killRing().numberOfKills() != 0;
197- }
189+ if(!useKillRing)
190+ return canPastePlatformData();
191+ else if(const texteditor::Session* const session = document().session())
192+ return session->killRing().numberOfKills() != 0;
198193 return false;
199194 }
200195
@@ -374,13 +369,13 @@
374369 * @param caret The caret
375370 * @param text The text to insert
376371 * @param keepNewline Set @c false to overwrite a newline characer
377- * @throw NullPointerException @a first is @c null
372+ * @throw NullPointerException @a text is @c null
378373 * @throw DocumentDisposedException
379374 * @throw TextViewerDisposedException
380375 * @throw ... Any exceptions @c Document#replace throws
381376 */
382377 void destructiveInsert(Caret& caret, const StringPiece& text, bool keepNewline = true) {
383- if(text.begin() == nullptr)
378+ if(text.begin() == nullptr || text.end() == nullptr)
384379 throw NullPointerException("text");
385380 const bool adapts = caret.adaptsToDocument();
386381 caret.adaptToDocument(false);
@@ -418,17 +413,17 @@
418413 */
419414 bool Caret::inputCharacter(CodePoint character, bool validateSequence /* = true */, bool blockControls /* = true */) {
420415 // check blockable control character
421- static const CodePoint SAFE_CONTROLS[] = {0x0009u, 0x001eu, 0x001fu};
416+ static const array<CodePoint, 3> SAFE_CONTROLS = {0x0009u, 0x001eu, 0x001fu};
422417 if(blockControls && character <= 0x00ffu
423418 && (iscntrl(static_cast<int>(character)) != 0)
424- && !binary_search(SAFE_CONTROLS, ASCENSION_ENDOF(SAFE_CONTROLS), character))
419+ && !boost::binary_search(SAFE_CONTROLS, character))
425420 return false;
426421
427422 // check the input sequence
428423 k::Document& doc = document();
429424 if(validateSequence) {
430425 if(const texteditor::Session* const session = doc.session()) {
431- if(const texteditor::InputSequenceCheckers* const checker = session->inputSequenceCheckers()) {
426+ if(const shared_ptr<const texteditor::InputSequenceCheckers> checker = session->inputSequenceCheckers()) {
432427 const Char* const lineString = doc.line(line(beginning())).data();
433428 if(!checker->check(StringPiece(lineString, offsetInLine(beginning())), character)) {
434429 eraseSelection(*this);
@@ -470,8 +465,7 @@
470465 context_.lastTypedPosition = position();
471466 }
472467
473- characterInputListeners_.notify<const Caret&, CodePoint>(
474- &CharacterInputListener::characterInput, *this, character);
468+ characterInputListeners_.notify<const Caret&, CodePoint>(&CharacterInputListener::characterInput, *this, character);
475469 return true;
476470 }
477471
@@ -603,6 +597,8 @@
603597 ::DestroyCaret();
604598 ::CreateCaret(viewer.handle().get(), image->asNativeObject().get(), 0, 0);
605599 ::ShowCaret(viewer.handle().get());
600+#else
601+ // TODO: Implement for other window systems.
606602 #endif
607603
608604 shapeCache_.image = move(image);
@@ -697,6 +693,8 @@
697693 static_cast<int>(geometry::y(p)) - geometry::y(shapeCache_.alignmentPoint));
698694 #if defined(ASCENSION_WINDOW_SYSTEM_WIN32)
699695 ::SetCaretPos(boost::geometry::get<0>(newLocation), boost::geometry::get<1>(newLocation));
696+#else
697+ // TODO: Implement for other window systems.
700698 #endif
701699 adjustInputMethodCompositionWindow();
702700 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/viewer/default-mouse-input-strategy.cpp
--- a/ascension/src/viewer/default-mouse-input-strategy.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/viewer/default-mouse-input-strategy.cpp Sat May 11 12:12:08 2013 +0900
@@ -58,7 +58,7 @@
5858 CURSOR_DOWNWARD ///< Indicates scrolling downward.
5959 };
6060 public:
61- explicit AutoScrollOriginMark(TextViewer& viewer) /*throw()*/;
61+ explicit AutoScrollOriginMark(TextViewer& viewer) BOOST_NOEXCEPT;
6262 static const widgetapi::Cursor& cursorForScrolling(CursorType type);
6363 void resetWidgetShape();
6464 private:
@@ -95,7 +95,7 @@
9595 * Constructor.
9696 * @param viewer The text viewer. The widget becomes the child of this viewer
9797 */
98-AutoScrollOriginMark::AutoScrollOriginMark(TextViewer& viewer) /*throw()*/ {
98+AutoScrollOriginMark::AutoScrollOriginMark(TextViewer& viewer) BOOST_NOEXCEPT {
9999 resetWidgetShape();
100100 widgetapi::setParent(*this, &viewer);
101101 }
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/viewer/viewer-windows.cpp
--- a/ascension/src/viewer/viewer-windows.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/viewer/viewer-windows.cpp Sat May 11 12:12:08 2013 +0900
@@ -52,7 +52,7 @@
5252 } // namespace @0
5353
5454 // defined at ascension/win32/windows.hpp
55-LANGID ASCENSION_FASTCALL ascension::win32::userDefaultUILanguage() /*throw()*/ {
55+LANGID ASCENSION_FASTCALL ascension::win32::userDefaultUILanguage() BOOST_NOEXCEPT {
5656 // references (from Global Dev)
5757 // - Writing Win32 Multilingual User Interface Applications (http://www.microsoft.com/globaldev/handson/dev/muiapp.mspx)
5858 // - Ask Dr. International Column #9 (http://www.microsoft.com/globaldev/drintl/columns/009/default.mspx#EPD)
@@ -101,7 +101,7 @@
101101 namespace {
102102 class AccLib {
103103 public:
104- AccLib() /*throw()*/ : oleaccDLL_(::LoadLibraryA("oleacc.dll")), user32DLL_(::LoadLibraryA("user32.dll")) {
104+ AccLib() BOOST_NOEXCEPT : oleaccDLL_(::LoadLibraryA("oleacc.dll")), user32DLL_(::LoadLibraryA("user32.dll")) {
105105 if(oleaccDLL_ == nullptr || user32DLL_ == nullptr) {
106106 ::FreeLibrary(oleaccDLL_);
107107 ::FreeLibrary(user32DLL_);
@@ -117,7 +117,7 @@
117117 }
118118 }
119119 ~AccLib() {::FreeLibrary(oleaccDLL_); ::FreeLibrary(user32DLL_);}
120- bool isAvailable() const /*throw()*/ {return oleaccDLL_ != nullptr;}
120+ bool isAvailable() const BOOST_NOEXCEPT {return oleaccDLL_ != nullptr;}
121121 HRESULT accessibleObjectFromWindow(HWND window, DWORD objectID, REFIID iid, void** object) {
122122 assert(isAvailable()); return (*accessibleObjectFromWindowPtr_)(window, objectID, iid, object);}
123123 void createStdAccessibleObject(HWND window, long objectID, REFIID iid, void** object) {
@@ -208,7 +208,7 @@
208208 * Constructor.
209209 * @param view the viewer
210210 */
211-AccessibleProxy::AccessibleProxy(TextViewer& viewer) /*throw()*/ : viewer_(viewer), available_(true) {
211+AccessibleProxy::AccessibleProxy(TextViewer& viewer) BOOST_NOEXCEPT : viewer_(viewer), available_(true) {
212212 assert(accLib.isAvailable());
213213 accLib.createStdAccessibleObject(viewer.handle().get(), OBJID_CLIENT, IID_IAccessible, defaultServer_.initializePPV());
214214 }
@@ -496,7 +496,7 @@
496496
497497 #ifndef ASCENSION_NO_ACTIVE_ACCESSIBILITY
498498 /// Returns the accessible proxy of the viewer.
499-HRESULT TextViewer::accessibleObject(IAccessible*& acc) const /*throw()*/ {
499+HRESULT TextViewer::accessibleObject(IAccessible*& acc) const BOOST_NOEXCEPT {
500500 TextViewer& self = *const_cast<TextViewer*>(this);
501501 acc = nullptr;
502502 if(accessibleProxy_.get() == nullptr && win32::boole(::IsWindow(handle().get())) && accLib.isAvailable()) {
@@ -515,7 +515,7 @@
515515 #endif // !ASCENSION_NO_ACTIVE_ACCESSIBILITY
516516
517517 /// Implementation of @c #beep method. The subclasses can override to customize the behavior.
518-void TextViewer::doBeep() /*throw()*/ {
518+void TextViewer::doBeep() BOOST_NOEXCEPT {
519519 ::MessageBeep(MB_OK);
520520 }
521521
diff -r 37d9e2b88f6c -r 8257513d0169 ascension/src/viewer/viewer.cpp
--- a/ascension/src/viewer/viewer.cpp Sat May 11 12:01:53 2013 +0900
+++ b/ascension/src/viewer/viewer.cpp Sat May 11 12:12:08 2013 +0900
@@ -238,7 +238,7 @@
238238 }
239239
240240 /// @see DefaultFontListener#defaultFontChanged
241-void TextViewer::defaultFontChanged() /*throw()*/ {
241+void TextViewer::defaultFontChanged() BOOST_NOEXCEPT {
242242 rulerPainter_->update();
243243 scrolls_.resetBars(*this, 'a', true);
244244 updateScrollBars();
@@ -658,7 +658,7 @@
658658 proposals.insert(new CompletionProposal(p));
659659 IdentifiersProposalProcessor::computeCompletionProposals(caret, incremental = true, replacementRegion, proposals);
660660 }
661- bool isCompletionProposalAutoActivationCharacter(CodePoint c) const /*throw()*/ {return c == L'@';}
661+ bool isCompletionProposalAutoActivationCharacter(CodePoint c) const BOOST_NOEXCEPT {return c == L'@';}
662662 };
663663 class JSProposals : public IdentifiersProposalProcessor {
664664 public:
@@ -671,7 +671,7 @@
671671 proposals.insert(new CompletionProposal(p));
672672 IdentifiersProposalProcessor::computeCompletionProposals(caret, incremental = true, replacementRegion, proposals);
673673 }
674- bool isCompletionProposalAutoActivationCharacter(CodePoint c) const /*throw()*/ {return c == L'.';}
674+ bool isCompletionProposalAutoActivationCharacter(CodePoint c) const BOOST_NOEXCEPT {return c == L'.';}
675675 };
676676 unique_ptr<contentassist::ContentAssistant> ca(new contentassist::ContentAssistant());
677677 ca->setContentAssistProcessor(JS_MULTILINE_DOC_COMMENT, unique_ptr<contentassist::IContentAssistProcessor>(new JSDocProposals(cti->getIdentifierSyntax(JS_MULTILINE_DOC_COMMENT))));
@@ -1359,7 +1359,7 @@
13591359 * Sets the new content assistant.
13601360 * @param newContentAssistant the content assistant to set. the ownership will be transferred to the callee.
13611361 */
1362-void TextViewer::setContentAssistant(unique_ptr<contentassist::ContentAssistant> newContentAssistant) /*throw()*/ {
1362+void TextViewer::setContentAssistant(unique_ptr<contentassist::ContentAssistant> newContentAssistant) BOOST_NOEXCEPT {
13631363 if(contentAssistant_.get() != nullptr)
13641364 contentAssistant_->uninstall(); // $friendly-access
13651365 (contentAssistant_ = std::move(newContentAssistant))->install(*this); // $friendly-access
@@ -1450,7 +1450,7 @@
14501450 * Returns the 'content-rectangle' of the text area, in local-coordinates.
14511451 * @see #bounds, #textAreaAllocationRectangle
14521452 */
1453-graphics::Rectangle TextViewer::textAreaContentRectangle() const /*throw()*/ {
1453+graphics::Rectangle TextViewer::textAreaContentRectangle() const BOOST_NOEXCEPT {
14541454 // TODO: Consider 'padding-start' setting.
14551455 return textAreaAllocationRectangle();
14561456 }
@@ -1545,7 +1545,7 @@
15451545 }
15461546
15471547 /// @see TextViewport#viewportBoundsInViewChanged
1548-void TextViewer::viewportBoundsInViewChanged(const graphics::Rectangle& oldBounds) /*throw()*/ {
1548+void TextViewer::viewportBoundsInViewChanged(const graphics::Rectangle& oldBounds) BOOST_NOEXCEPT {
15491549 // textRenderer().setTextWrapping(textRenderer().textWrapping(), widgetapi::createRenderingContext(*this).get());
15501550 scrolls_.resetBars(*this, 'a', true);
15511551 updateScrollBars();
@@ -1677,7 +1677,7 @@
16771677 }
16781678
16791679 /// @see VisualLinesListener#visualLinesDeleted
1680-void TextViewer::visualLinesDeleted(const boost::integer_range<Index>& lines, Index sublines, bool longestLineChanged) /*throw()*/ {
1680+void TextViewer::visualLinesDeleted(const boost::integer_range<Index>& lines, Index sublines, bool longestLineChanged) BOOST_NOEXCEPT {
16811681 scrolls_.changed = true;
16821682 const shared_ptr<const TextViewport> viewport(textRenderer().viewport());
16831683 if(*lines.end() < viewport->firstVisibleLineInLogicalNumber()) { // deleted before visible area
@@ -1699,7 +1699,7 @@
16991699 }
17001700
17011701 /// @see VisualLinesListener#visualLinesInserted
1702-void TextViewer::visualLinesInserted(const boost::integer_range<Index>& lines) /*throw()*/ {
1702+void TextViewer::visualLinesInserted(const boost::integer_range<Index>& lines) BOOST_NOEXCEPT {
17031703 scrolls_.changed = true;
17041704 const shared_ptr<const TextViewport> viewport(textRenderer().viewport());
17051705 if(*lines.end() < viewport->firstVisibleLineInLogicalNumber()) { // inserted before visible area
@@ -1720,7 +1720,7 @@
17201720
17211721 /// @see VisualLinesListener#visualLinesModified
17221722 void TextViewer::visualLinesModified(const boost::integer_range<Index>& lines,
1723- SignedIndex sublinesDifference, bool documentChanged, bool longestLineChanged) /*throw()*/ {
1723+ SignedIndex sublinesDifference, bool documentChanged, bool longestLineChanged) BOOST_NOEXCEPT {
17241724 if(sublinesDifference == 0) // number of visual lines was not changed
17251725 redrawLines(lines);
17261726 else {
@@ -1777,7 +1777,7 @@
17771777 }
17781778
17791779 /// Destructor calls @c TextViewer#unfreeze.
1780-AutoFreeze::~AutoFreeze() /*throw()*/ {
1780+AutoFreeze::~AutoFreeze() BOOST_NOEXCEPT {
17811781 try {
17821782 if(textViewer_ != nullptr)
17831783 textViewer_->unfreeze();
@@ -1789,10 +1789,10 @@
17891789
17901790 // TextViewer.CursorVanisher //////////////////////////////////////////////////////////////////////
17911791
1792-TextViewer::CursorVanisher::CursorVanisher() /*throw()*/ : viewer_(nullptr) {
1792+TextViewer::CursorVanisher::CursorVanisher() BOOST_NOEXCEPT : viewer_(nullptr) {
17931793 }
17941794
1795-TextViewer::CursorVanisher::~CursorVanisher() /*throw()*/ {
1795+TextViewer::CursorVanisher::~CursorVanisher() BOOST_NOEXCEPT {
17961796 restore();
17971797 }
17981798
@@ -1874,7 +1874,7 @@
18741874
18751875 #ifdef ASCENSION_ABANDONED_AT_VERSION_08
18761876 /// @see TextRenderer#width
1877-Scalar TextViewer::Renderer::width() const /*throw()*/ {
1877+Scalar TextViewer::Renderer::width() const BOOST_NOEXCEPT {
18781878 const LineWrapConfiguration& lwc = viewer_.configuration().lineWrap;
18791879 if(!lwc.wraps())
18801880 return (viewer_.horizontalScrollBar().range().end() + 1) * viewer_.textRenderer().defaultFont()->metrics().averageCharacterWidth();
@@ -1892,7 +1892,7 @@
18921892 // TextViewer.Configuration /////////////////////////////////////////////////
18931893
18941894 /// Default constructor.
1895-TextViewer::Configuration::Configuration() /*throw()*/ :
1895+TextViewer::Configuration::Configuration() BOOST_NOEXCEPT :
18961896 readingDirection(LEFT_TO_RIGHT), usesRichTextClipboardFormat(false) {
18971897 #if(_WIN32_WINNT >= 0x0501)
18981898 BOOL b;
@@ -1943,7 +1943,7 @@
19431943 }
19441944
19451945 /// Destructor.
1946-CurrentLineHighlighter::~CurrentLineHighlighter() /*noexcept*/ {
1946+CurrentLineHighlighter::~CurrentLineHighlighter() BOOST_NOEXCEPT {
19471947 if(caret_ != nullptr) {
19481948 caret_->removeListener(*this);
19491949 caret_->removeStateListener(*this);
@@ -1952,7 +1952,7 @@
19521952 }
19531953
19541954 /// Returns the background color.
1955-const boost::optional<Color>& CurrentLineHighlighter::background() const /*noexcept*/ {
1955+const boost::optional<Color>& CurrentLineHighlighter::background() const BOOST_NOEXCEPT {
19561956 return background_;
19571957 }
19581958
@@ -1969,7 +1969,7 @@
19691969 }
19701970
19711971 /// Returns the foreground color.
1972-const boost::optional<Color>& CurrentLineHighlighter::foreground() const /*noexcept*/ {
1972+const boost::optional<Color>& CurrentLineHighlighter::foreground() const BOOST_NOEXCEPT {
19731973 return foreground_;
19741974 }
19751975
@@ -2009,7 +2009,7 @@
20092009 * Sets the background color and redraws the window.
20102010 * @param color The background color to set
20112011 */
2012-void CurrentLineHighlighter::setBackground(const boost::optional<Color>& color) /*noexcept*/ {
2012+void CurrentLineHighlighter::setBackground(const boost::optional<Color>& color) BOOST_NOEXCEPT {
20132013 background_ = color;
20142014 }
20152015
@@ -2017,7 +2017,7 @@
20172017 * Sets the foreground color and redraws the window.
20182018 * @param color The foreground color to set
20192019 */
2020-void CurrentLineHighlighter::setForeground(const boost::optional<Color>& color) /*noexcept*/ {
2020+void CurrentLineHighlighter::setForeground(const boost::optional<Color>& color) BOOST_NOEXCEPT {
20212021 foreground_ = color;
20222022 }
20232023
@@ -2025,7 +2025,7 @@
20252025 // ascension.viewers.utils free functions /////////////////////////////////////////////////////////
20262026
20272027 /// Closes the opened completion proposals popup immediately.
2028-void utils::closeCompletionProposalsPopup(TextViewer& viewer) /*throw()*/ {
2028+void utils::closeCompletionProposalsPopup(TextViewer& viewer) BOOST_NOEXCEPT {
20292029 if(contentassist::ContentAssistant* ca = viewer.contentAssistant()) {
20302030 if(contentassist::ContentAssistant::CompletionProposalsUI* cpui = ca->completionProposalsUI())
20312031 cpui->close();
@@ -2047,7 +2047,7 @@
20472047 * Toggles the inline flow direction of the text viewer.
20482048 * @param viewer The text viewer
20492049 */
2050-void utils::toggleOrientation(TextViewer& viewer) /*throw()*/ {
2050+void utils::toggleOrientation(TextViewer& viewer) BOOST_NOEXCEPT {
20512051 viewer.textRenderer().setDirection(!viewer.presentation().computeWritingMode(&viewer.textRenderer()).inlineFlowDirection);
20522052 // viewer.synchronizeWritingModeUI();
20532053 // if(config.lineWrap.wrapsAtWindowEdge()) {
@@ -2154,7 +2154,7 @@
21542154 * Calls @c IncrementalSearcher#abort from @a viewer.
21552155 * @return true if the incremental search was running
21562156 */
2157-bool texteditor::abortIncrementalSearch(TextViewer& viewer) /*throw()*/ {
2157+bool texteditor::abortIncrementalSearch(TextViewer& viewer) BOOST_NOEXCEPT {
21582158 if(texteditor::Session* session = viewer.document().session()) {
21592159 if(session->incrementalSearcher().isRunning())
21602160 return session->incrementalSearcher().abort(), true;
@@ -2166,7 +2166,7 @@
21662166 * Calls @c IncrementalSearcher#end from @a viewer.
21672167 * @return true if the incremental search was running
21682168 */
2169-bool texteditor::endIncrementalSearch(TextViewer& viewer) /*throw()*/ {
2169+bool texteditor::endIncrementalSearch(TextViewer& viewer) BOOST_NOEXCEPT {
21702170 if(texteditor::Session* session = viewer.document().session()) {
21712171 if(session->incrementalSearcher().isRunning())
21722172 return session->incrementalSearcher().end(), true;
Show on old repository browser